{"id":340234,"date":"2026-07-17T02:06:49","date_gmt":"2026-07-17T02:06:49","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/friend-product-links-for-woocommerce\/"},"modified":"2026-07-17T02:06:39","modified_gmt":"2026-07-17T02:06:39","slug":"friend-product-links","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/friend-product-links\/","author":13886629,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.1.44","stable_tag":"1.1.44","tested":"7.0.1","requires":"6.2","requires_php":"7.4","requires_plugins":null,"header_name":"Friend Product Links for woocommerce","header_author":"EEZZNET","header_description":"A free P2P WooCommerce friend product link plugin with local feed caching.","assets_banners_color":"beb48f","last_updated":"2026-07-17 02:06:39","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/eezz.net\/projects\/","header_author_uri":"https:\/\/eezz.net","rating":0,"author_block_rating":0,"active_installs":0,"downloads":26,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.1.44":{"tag":"1.1.44","author":"daijianpu","date":"2026-07-17 02:06:39"}},"upgrade_notice":{"1.1.44":"<p>Standardized all plugin-owned global identifiers with the unique EZFRIPL prefix for WordPress.org compatibility.<\/p>","1.1.43":"<p>Copy friend product images into the local Media Library during sync. Frontend pages no longer load images directly from friend websites.<\/p>","1.1.42":"<p>Fixed REST callback canonical-offer failure handling and hardened exchange partner duplicate\/error handling.<\/p>","1.1.41":"<p>Improved exchange offer URL canonical handling, duplicate request protection, invalid URL feedback, and partner repository URL validation.<\/p>","1.1.40":"<p>Improved exchange notice severity, invalid URL feedback, duplicate partner protection, and cached preview URL safety.<\/p>","1.1.39":"<p>Improved admin external-link validation, catalog action guarding, partner identity refresh on sync, and settings save consistency.<\/p>","1.1.38":"<p>Completed backend empty-value helper rollout across Performance, Core Friends, Exchange Requests, and Dashboard rows.<\/p>","1.1.37":"<p>Admin empty values now use a unified muted dash helper across backend pages.<\/p>","1.1.36":"<p>Improved exchange resume safety, approval callback consistency, callback token validation, and removed BOM from source files.<\/p>","1.1.35":"<p>Improved paused partner resume safety, approval callback consistency, callback token validation, and sync degradation for incomplete partner records.<\/p>","1.1.34":"<p>Improved paused partner resume safety, callback token validation, and admin muted display styling.<\/p>","1.1.33":"<p>Improved exchange partner degradation behavior, pending partner timestamps, callback token validation, and empty admin URL display.<\/p>","1.1.32":"<p>Improved exchange request safety, callback idempotency, self-exchange prevention, and admin link output.<\/p>","1.1.31":"<p>Improved Exchange admin flow safety, request failure visibility, and backend action layout consistency.<\/p>","1.1.28":"<p>Settings now make it clearer that frontend color customization is optional, and Exchange Catalog Mode is locked on while active partners exist.<\/p>","1.1.27":"<p>Frontend price and button colors can now be customized with CSS variables in your theme Additional CSS.<\/p>","1.1.26":"<p>Dashboard onboarding, partner warnings, and Exchange Catalog quick links are now more consistent.<\/p>","1.1.25":"<p>Fixed Dashboard status edge cases and reduced noisy onboarding messages on empty sites.<\/p>","1.1.24":"<p>Dashboard warnings are now less noisy for Exchange-only sites, and the Dashboard no longer performs unlimited reads for summary cards.<\/p>","1.1.23":"<p>Dashboard health warnings are more accurate, especially when Core Friends or Core Product Links are disabled.<\/p>","1.1.22":"<p>The Dashboard now reports setup health more accurately and remains read-only.<\/p>","1.1.21":"<p>Friend Product Links now opens to a read-only Dashboard that summarizes setup status, exchange health, and click performance.<\/p>","1.1.20":"<p>Review Exchange Partners after updating. Paused\/degraded partners now have clearer status and recovery actions.<\/p>","1.1.19":"<p>Purge caches after updating. This release refines frontend price sizing and responsive grid CSS.<\/p>","1.1.18":"<p>Purge caches after updating. Frontend price styling and responsive product grids now rely on the updated frontend stylesheet.<\/p>","1.1.17":"<p>Core Friends now render later on single product pages with a higher priority, so store related products can appear first on more themes. Purge caches after updating.<\/p>","1.1.16":"<p>Core Friends are now displayed later on single product pages, after the store&#039;s own related-product area where supported by the active theme. Purge caches after updating.<\/p>","1.1.15":"<p>Core Product Links now require at least 4 products. Please update existing Core Product Links and re-sync Core Friends after updating.<\/p>","1.1.14":"<p>After updating, purge caches and re-sync Exchange Partners. Exchange Offers now require at least 4 products.<\/p>","1.1.13":"<p>Exchange Offers now require at least 4 products. Please update your Exchange Offer products and re-sync Exchange Partners after updating.<\/p>","1.1.12":"<p>After updating, sync your Core Friends and Exchange Partners again to refresh cached product images and prices.<\/p>","1.1.11":"<p>After updating, sync your Core Friends and Exchange Partners again to refresh cached product images and prices.<\/p>"},"ratings":[],"assets_icons":{"icon-256x256.png":{"filename":"icon-256x256.png","revision":3610896,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3610896,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.1.44"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3610896,"resolution":"1","location":"assets","locale":"","width":1912,"height":966},"screenshot-10.png":{"filename":"screenshot-10.png","revision":3610896,"resolution":"10","location":"assets","locale":"","width":1912,"height":1166},"screenshot-11.png":{"filename":"screenshot-11.png","revision":3610896,"resolution":"11","location":"assets","locale":"","width":1145,"height":1627},"screenshot-12.png":{"filename":"screenshot-12.png","revision":3610896,"resolution":"12","location":"assets","locale":"","width":1498,"height":966},"screenshot-13.png":{"filename":"screenshot-13.png","revision":3610896,"resolution":"13","location":"assets","locale":"","width":1124,"height":966},"screenshot-14.png":{"filename":"screenshot-14.png","revision":3610896,"resolution":"14","location":"assets","locale":"","width":1912,"height":966},"screenshot-16.png":{"filename":"screenshot-16.png","revision":3610896,"resolution":"16","location":"assets","locale":"","width":1912,"height":966},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3610896,"resolution":"2","location":"assets","locale":"","width":1886,"height":2252},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3610896,"resolution":"3","location":"assets","locale":"","width":1912,"height":966},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3610896,"resolution":"4","location":"assets","locale":"","width":1912,"height":1166},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3610896,"resolution":"5","location":"assets","locale":"","width":1912,"height":1466},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3610896,"resolution":"6","location":"assets","locale":"","width":1180,"height":938},"screenshot-7.png":{"filename":"screenshot-7.png","revision":3610896,"resolution":"7","location":"assets","locale":"","width":1895,"height":937},"screenshot-8.png":{"filename":"screenshot-8.png","revision":3610896,"resolution":"8","location":"assets","locale":"","width":1912,"height":928},"screenshot-9.png":{"filename":"screenshot-9.png","revision":3610896,"resolution":"9","location":"assets","locale":"","width":1374,"height":931}},"screenshots":[]},"plugin_section":[],"plugin_tags":[13943,5418,143626,286],"plugin_category":[45,58],"plugin_contributors":[265102],"plugin_business_model":[],"class_list":["post-340234","plugin","type-plugin","status-publish","hentry","plugin_tags-friends","plugin_tags-product-feed","plugin_tags-product-links","plugin_tags-woocommerce","plugin_category-ecommerce","plugin_category-user-management","plugin_contributors-daijianpu","plugin_committers-daijianpu"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/friend-product-links\/assets\/icon-256x256.png?rev=3610896","icon_2x":"https:\/\/ps.w.org\/friend-product-links\/assets\/icon-256x256.png?rev=3610896","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/friend-product-links\/assets\/screenshot-1.png?rev=3610896","caption":""},{"src":"https:\/\/ps.w.org\/friend-product-links\/assets\/screenshot-2.png?rev=3610896","caption":""},{"src":"https:\/\/ps.w.org\/friend-product-links\/assets\/screenshot-3.png?rev=3610896","caption":""},{"src":"https:\/\/ps.w.org\/friend-product-links\/assets\/screenshot-4.png?rev=3610896","caption":""},{"src":"https:\/\/ps.w.org\/friend-product-links\/assets\/screenshot-5.png?rev=3610896","caption":""},{"src":"https:\/\/ps.w.org\/friend-product-links\/assets\/screenshot-6.png?rev=3610896","caption":""},{"src":"https:\/\/ps.w.org\/friend-product-links\/assets\/screenshot-7.png?rev=3610896","caption":""},{"src":"https:\/\/ps.w.org\/friend-product-links\/assets\/screenshot-8.png?rev=3610896","caption":""},{"src":"https:\/\/ps.w.org\/friend-product-links\/assets\/screenshot-9.png?rev=3610896","caption":""},{"src":"https:\/\/ps.w.org\/friend-product-links\/assets\/screenshot-10.png?rev=3610896","caption":""},{"src":"https:\/\/ps.w.org\/friend-product-links\/assets\/screenshot-11.png?rev=3610896","caption":""},{"src":"https:\/\/ps.w.org\/friend-product-links\/assets\/screenshot-12.png?rev=3610896","caption":""},{"src":"https:\/\/ps.w.org\/friend-product-links\/assets\/screenshot-13.png?rev=3610896","caption":""},{"src":"https:\/\/ps.w.org\/friend-product-links\/assets\/screenshot-14.png?rev=3610896","caption":""},{"src":"https:\/\/ps.w.org\/friend-product-links\/assets\/screenshot-16.png?rev=3610896","caption":""}],"raw_content":"<!--section=description-->\n<p>Friend Product Links lets WooCommerce store owners share selected products with trusted friend stores.<\/p>\n\n<p>Each store can generate a private Friend Product Link, send it to a friend, add up to 3 friend links, cache up to 9 products per friend, display up to 4 products from each core friend on WooCommerce product pages, and exchange products on a dedicated Exchange Catalog page.<\/p>\n\n<p>Aggregated local click stats help evaluate friend product placements and sponsored partner slots. The stats stay privacy-friendly: no cookies, no visitor profiles, no IP logging, and no browser fingerprinting. Server-side display counts may be affected by full-page cache; click counts are usually more reliable.<\/p>\n\n<p>The plugin keeps the first version simple:<\/p>\n\n<ul>\n<li>No account system.<\/li>\n<li>No connection to the plugin author's server.<\/li>\n<li>No JSON copy-paste for normal users.<\/li>\n<li>Store-to-store sharing through the Friend Product Link.<\/li>\n<li>Frontend product pages never request friend websites in real time.<\/li>\n<li>Aggregated stats only.<\/li>\n<li>No visitor tracking.<\/li>\n<li>No data sent to the plugin author.<\/li>\n<\/ul>\n\n<p>Friend product feeds are requested only by the site administrator through manual sync or by the site scheduled sync. When a friend feed or exchange offer contains product image URLs, the plugin copies those images into the local WordPress Media Library during sync. Frontend pages display local Media Library images or a local plugin placeholder image. They do not load product images directly from friend websites during visitor page views.<\/p>\n\n<h3>Basic Workflow<\/h3>\n\n<ol>\n<li>Create a product link under My Product Links.<\/li>\n<li>Select 4 to 9 public WooCommerce products.<\/li>\n<li>Send the generated Friend Product Link to your friend.<\/li>\n<li>Add your friend's link under My Friends.<\/li>\n<li>Fetch and preview the friend products.<\/li>\n<li>Enable the friend after a successful sync.<\/li>\n<li>View aggregate server-rendered displays, clicks, and CTR values in the admin.<\/li>\n<\/ol>\n\n<h3>Privacy<\/h3>\n\n<p>This plugin stores aggregated display and click counts locally on your WordPress site. If stats sharing is enabled, the plugin can send aggregated display and click counts to the connected friend site through the Friend Product Link. It does not track individual visitors, does not use cookies, and does not send statistics to the plugin author or any central server.<\/p>\n\n<p>The plugin never sends visitor IP addresses, user agents, user accounts, order data, cookies, or personal data as part of stats sharing.<\/p>\n\n<p>Friend product feeds and exchange offers are requested only during administrator-triggered sync or scheduled site sync. Product images from those feeds are copied into the local WordPress Media Library during sync. Frontend product cards display local Media Library images or the plugin local placeholder image, not friend-site image URLs.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin folder to <code>\/wp-content\/plugins\/friend-product-links<\/code>.<\/li>\n<li>Activate the plugin through the WordPress Plugins screen.<\/li>\n<li>Make sure WooCommerce is active.<\/li>\n<li>Open Friend Product Links in the WordPress admin.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20the%20plugin%20include%20external%20community%20links%3F\"><h3>Does the plugin include external community links?<\/h3><\/dt>\n<dd><p>Yes. The plugin may show optional admin links to external community spaces such as Facebook, Reddit, and EEZZ Club. These links are only opened when you click them. The plugin does not embed external pages, load third-party community scripts, or send site data to those communities automatically.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20contact%20the%20plugin%20author%20server%3F\"><h3>Does the plugin contact the plugin author server?<\/h3><\/dt>\n<dd><p>No. Friend product links are shared directly between stores.<\/p><\/dd>\n<dt id=\"does%20the%20frontend%20request%20friend%20feeds%3F\"><h3>Does the frontend request friend feeds?<\/h3><\/dt>\n<dd><p>No. Friend feeds are cached locally and refreshed by WP-Cron or manually by an administrator.<\/p><\/dd>\n<dt id=\"does%20the%20frontend%20load%20images%20from%20friend%20websites%3F\"><h3>Does the frontend load images from friend websites?<\/h3><\/dt>\n<dd><p>No. Friend product images are copied into the local WordPress Media Library during sync. Frontend product cards display local Media Library images or the plugin local placeholder image.<\/p><\/dd>\n<dt id=\"what%20performance%20stats%20are%20stored%3F\"><h3>What performance stats are stored?<\/h3><\/dt>\n<dd><p>The plugin stores aggregated server-rendered display and click counts locally on your WordPress site. It does not track individual visitors and does not use cookies. Full-page cache may undercount server-rendered displays; click counts are usually more reliable.<\/p><\/dd>\n<dt id=\"are%20stats%20sent%20anywhere%3F\"><h3>Are stats sent anywhere?<\/h3><\/dt>\n<dd><p>If stats sharing is enabled, the plugin can send aggregated display and click counts to the connected friend site through the Friend Product Link. It does not send statistics to the plugin author or any central server.<\/p><\/dd>\n<dt id=\"why%20are%20links%20marked%20nofollow%20sponsored%20noopener%20noreferrer%3F\"><h3>Why are links marked nofollow sponsored noopener noreferrer?<\/h3><\/dt>\n<dd><p>Friend links are external links to another store. The plugin uses nofollow sponsored noopener noreferrer by default to keep the first version conservative for search engines and referrer privacy.<\/p><\/dd>\n<dt id=\"how%20can%20i%20customize%20the%20price%20and%20button%20colors%3F\"><h3>How can I customize the price and button colors?<\/h3><\/dt>\n<dd><p>This is optional. If you do not add custom CSS, Friend Product Links uses its default frontend colors.<\/p>\n\n<p>To customize colors, add CSS variables to your theme's Additional CSS:<\/p>\n\n<p>body .ezfripl-module {\n--ezfripl-price-color: #f00000;\n--ezfripl-button-color: #7c00ff;\n--ezfripl-button-hover-color: #5f00cc;\n--ezfripl-button-text-color: #ffffff;\n}<\/p>\n\n<p>Change the hex colors to match your theme. These variables affect only Friend Product Links modules. Leave a variable out to use the plugin default.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.1.44<\/h4>\n\n<ul>\n<li>Replaced the former short global prefix with the unique EZFRIPL\/ezfripl prefix across PHP symbols, WordPress data keys, hooks, shortcodes, assets, and internal identifiers.<\/li>\n<li>Kept the renamed private custom post type keys within WordPress's 20-character post type limit.<\/li>\n<\/ul>\n\n<h4>1.1.43<\/h4>\n\n<ul>\n<li>Copy friend product images into the local Media Library during sync. Frontend pages display local Media Library images or a local plugin placeholder image, not remote friend image URLs.<\/li>\n<\/ul>\n\n<h4>1.1.42<\/h4>\n\n<ul>\n<li>Fixed a REST callback edge case where canonical offer URL validation could read a WP_Error as an array after a failed remote fetch.<\/li>\n<li>Matched existing partners by both canonical and legacy expected offer URLs during callback approval.<\/li>\n<li>Checked both submitted and canonical offer URLs when detecting duplicate outgoing exchange requests.<\/li>\n<li>Hardened repository-level exchange partner offer URL validation to require public http(s) URLs.<\/li>\n<li>Surfaced duplicate\/invalid partner creation errors more accurately in admin approval flows.<\/li>\n<li>Returned explicit REST status codes for duplicate or invalid partner creation errors during approval callbacks.<\/li>\n<li>Kept Empty Value Helper rollout, frontend CSS variables, Dashboard read-only behavior, and Exchange state-machine fixes intact.<\/li>\n<\/ul>\n\n<h4>1.1.41<\/h4>\n\n<ul>\n<li>Marked Exchange Catalog Mode disabled create\/repair notices as errors instead of success notices.<\/li>\n<li>Validated Start Exchange partner offer URLs before remote fetch attempts.<\/li>\n<li>Validated and used remote offer_url from exchange offer payloads as the canonical partner offer URL.<\/li>\n<li>Rechecked incoming exchange request duplicates after fetching canonical remote offer URLs.<\/li>\n<li>Rejected empty or invalid partner offer URLs at the repository layer.<\/li>\n<li>Allowed approval callbacks to match either the stored expected offer URL or the verified canonical remote offer URL.<\/li>\n<li>Cleaned high-risk admin table action markup formatting.<\/li>\n<li>Kept Empty Value Helper rollout, frontend CSS variables, Dashboard read-only behavior, and Exchange state-machine fixes intact.<\/li>\n<\/ul>\n\n<h4>1.1.40<\/h4>\n\n<ul>\n<li>Marked Exchange Catalog Mode disabled create\/repair notices as errors instead of success notices.<\/li>\n<li>Validated Start Exchange partner offer URLs before remote fetch attempts.<\/li>\n<li>Used canonical remote offer URLs when detecting existing exchange partners during approval.<\/li>\n<li>Added a repository-level duplicate partner guard by normalized offer URL.<\/li>\n<li>Hardened cached preview product links against invalid or cross-host historical cached URLs.<\/li>\n<li>Cleaned high-risk admin table action markup formatting.<\/li>\n<li>Cleaned duplicated catalog manager docblock.<\/li>\n<li>Kept Empty Value Helper rollout, frontend CSS variables, Dashboard read-only behavior, and Exchange state-machine fixes intact.<\/li>\n<\/ul>\n\n<h4>1.1.39<\/h4>\n\n<ul>\n<li>Hardened admin external link rendering to reject non-http(s) or relative URLs.<\/li>\n<li>Displayed a muted placeholder instead of a broken Copy Link when a Core Product Link token is missing or invalid.<\/li>\n<li>Added a server-side guard to prevent Exchange Catalog create\/repair actions while Exchange Catalog Mode is disabled.<\/li>\n<li>Refreshed exchange partner site name, site URL, and offer URL after successful partner sync.<\/li>\n<li>Refreshed exchange partner offer URL after approval callback success paths.<\/li>\n<li>Prevented partial Settings saves when Exchange Catalog Mode cannot be disabled due to active partners.<\/li>\n<li>Cleaned high-risk admin table action markup formatting.<\/li>\n<li>Kept Empty Value Helper rollout, frontend CSS variables, Dashboard read-only behavior, and Exchange state-machine fixes intact.<\/li>\n<\/ul>\n\n<h4>1.1.38<\/h4>\n\n<ul>\n<li>Replaced the remaining plain dash in outgoing exchange request actions with the shared empty value helper.<\/li>\n<li>Applied the shared empty value helper to Performance table names and last-click columns.<\/li>\n<li>Applied the shared empty value helper to Core Friends last-click and name fields.<\/li>\n<li>Prevented empty product hashes from rendering as ellipses in Dashboard and Performance tables.<\/li>\n<li>Cleaned duplicated helper docblocks.<\/li>\n<li>Kept frontend color CSS variable support and Dashboard read-only behavior intact.<\/li>\n<\/ul>\n\n<h4>1.1.37<\/h4>\n\n<ul>\n<li>Added a shared admin Empty Value Helper for consistent muted dash output.<\/li>\n<li>Replaced scattered plain dash placeholders across Core, Exchange, Dashboard, and Performance admin pages.<\/li>\n<li>Standardized empty external links through a shared admin link-or-empty helper.<\/li>\n<li>Preserved numeric zero values while rendering only real empty values as muted dashes.<\/li>\n<li>Kept frontend color CSS variable support and Dashboard read-only behavior intact.<\/li>\n<\/ul>\n\n<h4>1.1.36<\/h4>\n\n<ul>\n<li>Removed UTF-8 BOM from plugin source files to prevent unexpected output before redirects or REST responses.<\/li>\n<li>Re-synced paused exchange partners before making them active again.<\/li>\n<li>Prevented existing partners from receiving success timestamps before approval callbacks succeed.<\/li>\n<li>Added site name and site URL updates only after approval callbacks succeed.<\/li>\n<li>Validated stored callback tokens before processing exchange callbacks.<\/li>\n<li>Validated request IDs and callback tokens before sending approval\/rejection callbacks.<\/li>\n<li>Blocked self-exchange URLs before remote fetch attempts.<\/li>\n<li>Marked active partners with missing offer URLs as degraded during sync.<\/li>\n<li>Standardized muted dash display for empty backend values.<\/li>\n<li>Kept frontend color CSS variable support and Dashboard read-only behavior intact.<\/li>\n<\/ul>\n\n<h4>1.1.35<\/h4>\n\n<ul>\n<li>Re-synced paused exchange partners before making them active again.<\/li>\n<li>Prevented existing partners from receiving success timestamps before approval callbacks succeed.<\/li>\n<li>Added site name and site URL updates only after approval callbacks succeed.<\/li>\n<li>Validated stored callback tokens before processing exchange callbacks.<\/li>\n<li>Validated request IDs and callback tokens before sending approval\/rejection callbacks.<\/li>\n<li>Blocked self-exchange URLs before remote fetch attempts.<\/li>\n<li>Marked active partners with missing offer URLs as degraded during sync.<\/li>\n<li>Standardized muted dash display for empty backend values.<\/li>\n<li>Kept frontend color CSS variable support and Dashboard read-only behavior intact.<\/li>\n<\/ul>\n\n<h4>1.1.34<\/h4>\n\n<ul>\n<li>Fixed malformed admin CSS for muted empty-value indicators.<\/li>\n<li>Made Resume re-sync paused exchange partners before making them public again.<\/li>\n<li>Prevented existing partners from receiving success timestamps before approval callbacks succeed.<\/li>\n<li>Validated stored callback tokens before processing exchange callbacks.<\/li>\n<li>Validated callback request IDs and tokens before sending approval\/rejection callbacks.<\/li>\n<li>Blocked self-exchange URLs before remote fetch attempts.<\/li>\n<li>Standardized muted dash display for empty admin action cells.<\/li>\n<li>Kept frontend color CSS variable support and Dashboard read-only behavior intact.<\/li>\n<\/ul>\n\n<h4>1.1.33<\/h4>\n\n<ul>\n<li>Marked exchange partners as degraded when remote offer sync fails so stale cached products stop rendering publicly.<\/li>\n<li>Avoided writing last-success timestamps for pending activation partners.<\/li>\n<li>Clarified degraded remote offer handling for too-few-product sync failures.<\/li>\n<li>Validated callback request ID token shape before processing exchange callbacks.<\/li>\n<li>Displayed muted dashes for empty admin URL cells instead of leaving table cells blank.<\/li>\n<li>Kept frontend color CSS variable support and Dashboard read-only behavior intact.<\/li>\n<\/ul>\n\n<h4>1.1.32<\/h4>\n\n<ul>\n<li>Prevented failed approval callbacks from downgrading existing active exchange partners.<\/li>\n<li>Cleared stale request errors after successful approve\/reject decisions.<\/li>\n<li>Added finalized-state guards for exchange approval callbacks.<\/li>\n<li>Stored the real remote offer fetch error when callback processing fails.<\/li>\n<li>Blocked attempts to exchange with the same store.<\/li>\n<li>Validated exchange request IDs and callback tokens before storing incoming requests.<\/li>\n<li>Improved the new Core Friend Save Without Sync notice.<\/li>\n<li>Hardened backend external links and avoided empty clickable links.<\/li>\n<\/ul>\n\n<h4>1.1.31<\/h4>\n\n<ul>\n<li>Added confirmation to the Settings-page Exchange Catalog repair action.<\/li>\n<li>Prevented empty View Offer buttons when offer URLs are missing.<\/li>\n<li>Changed partner sync feedback so degraded sync results are shown as warnings instead of success.<\/li>\n<li>Marked outgoing exchange requests as failed when approved callbacks cannot be processed locally.<\/li>\n<li>Added confirmation before sending new exchange requests.<\/li>\n<li>Improved backend action button layout consistency across Core and Exchange admin pages.<\/li>\n<li>Kept frontend color CSS variable support and Dashboard read-only behavior intact.<\/li>\n<\/ul>\n\n<h4>1.1.30<\/h4>\n\n<ul>\n<li>Allowed disabled Exchange Offers to be saved without requiring the minimum product count in frontend validation.<\/li>\n<li>Hid misleading Sync Now actions for partners that are not in a syncable state.<\/li>\n<li>Added confirmation prompts for high-impact Exchange Request and Exchange Catalog actions.<\/li>\n<li>Added View Offer action for outgoing exchange requests.<\/li>\n<li>Improved backend action button layout with wrapping row action containers.<\/li>\n<li>Kept frontend color CSS variable support and Dashboard read-only behavior intact.<\/li>\n<\/ul>\n\n<h4>1.1.29<\/h4>\n\n<ul>\n<li>Added Resume and Delete buttons to the Exchange Partners admin page.<\/li>\n<li>Added success notices for resumed and deleted exchange partners.<\/li>\n<li>Improved Exchange Partners diagnostics by showing last error messages and cached product count health.<\/li>\n<li>Kept frontend color CSS variable support and default color fallbacks intact.<\/li>\n<li>Kept Dashboard read-only behavior intact.<\/li>\n<\/ul>\n\n<h4>1.1.28<\/h4>\n\n<ul>\n<li>Locked the Exchange Catalog Mode switch on the Settings page while active exchange partners exist.<\/li>\n<li>Clarified that frontend price and button color customization with CSS variables is optional.<\/li>\n<li>Kept default frontend price and button color fallbacks.<\/li>\n<li>Kept Dashboard fixes and read-only behavior intact.<\/li>\n<\/ul>\n\n<h4>1.1.27<\/h4>\n\n<ul>\n<li>Added CSS variable support for frontend price and button colors.<\/li>\n<li>Added a Settings page example for customizing Friend Product Links colors in theme Additional CSS.<\/li>\n<li>Removed the unused css.txt test file from the plugin package.<\/li>\n<li>Kept Dashboard fixes and read-only behavior intact.<\/li>\n<\/ul>\n\n<h4>1.1.26<\/h4>\n\n<ul>\n<li>Removed the duplicate empty-site Exchange Mode info message from the Dashboard.<\/li>\n<li>Counted active partners with too few cached products in the Partners \/ Requests dashboard card.<\/li>\n<li>Renamed the Exchange Catalog quick link to Manage Exchange Catalog when the catalog page is not ready.<\/li>\n<li>Made Core Summary sync health focus on enabled friend issues.<\/li>\n<li>Kept the Dashboard read-only.<\/li>\n<\/ul>\n\n<h4>1.1.25<\/h4>\n\n<ul>\n<li>Fixed an undefined Dashboard status state for healthy Partners \/ Requests cards.<\/li>\n<li>Replaced multiple empty-site setup warnings with one onboarding message.<\/li>\n<li>Made Core Friends status metadata use enabled friend issues only.<\/li>\n<li>Cleaned duplicate Dashboard changelog entries.<\/li>\n<li>Kept the Dashboard read-only.<\/li>\n<\/ul>\n\n<h4>1.1.24<\/h4>\n\n<ul>\n<li>Kept Dashboard summary reads bounded to avoid encouraging excessive exchange networks.<\/li>\n<li>Removed outdated readme wording about 100+ record Dashboard totals.<\/li>\n<li>Added request failure\/error checks to the Partners \/ Requests Dashboard status.<\/li>\n<li>Reduced Core setup warnings for stores using Exchange Catalog only.<\/li>\n<li>Kept the Dashboard read-only.<\/li>\n<\/ul>\n\n<h4>1.1.23<\/h4>\n\n<ul>\n<li>Reduced false Dashboard warnings from disabled Core Friends and disabled Core Product Links.<\/li>\n<li>Improved empty-state handling for the Partners \/ Requests dashboard card.<\/li>\n<li>Made the Exchange Catalog quick link point to the admin page when the catalog is not ready.<\/li>\n<li>Optimized read-only friend stats checks in the Dashboard.<\/li>\n<li>Kept the Dashboard read-only.<\/li>\n<\/ul>\n\n<h4>1.1.22<\/h4>\n\n<ul>\n<li>Improved Dashboard status accuracy for Core Friends and Exchange Catalog readiness.<\/li>\n<li>Counted valid public WooCommerce products for Core Product Link and Exchange Offer dashboard health.<\/li>\n<li>Added CTR columns to Dashboard performance top tables.<\/li>\n<li>Wrapped Dashboard tables to prevent narrow admin layouts from overflowing.<\/li>\n<li>Reduced unnecessary Exchange setup info messages for Core-only users.<\/li>\n<li>Kept the Dashboard read-only.<\/li>\n<\/ul>\n\n<h4>1.1.21<\/h4>\n\n<ul>\n<li>Added a read-only Dashboard for Friend Product Links.<\/li>\n<li>Added quick status cards for WooCommerce, Core Friends, Exchange Catalog, and partners.<\/li>\n<li>Added Action Required checks for setup, sync, catalog, request, partner, cron, and stats issues.<\/li>\n<li>Added Core Friends, Exchange, Performance, and System Health summaries.<\/li>\n<li>Moved the main admin menu landing page to the new Dashboard.<\/li>\n<\/ul>\n\n<h4>1.1.20<\/h4>\n\n<ul>\n<li>Improved admin notices for Exchange Catalog Mode and catalog repair actions.<\/li>\n<li>Locked Exchange Catalog Mode ON in Settings while active exchange partners exist.<\/li>\n<li>Added Resume and Delete actions for Exchange Partners.<\/li>\n<li>Added degraded_remote_offer status when partner sync returns too few valid products.<\/li>\n<li>Improved Exchange Partners health, cached product count, and error visibility.<\/li>\n<li>Added horizontal table wrappers for wide admin tables.<\/li>\n<li>Added confirmations for exchange approve, reject, pause, and delete actions.<\/li>\n<li>Added lightweight Exchange readiness status strips across Exchange admin pages.<\/li>\n<li>Limited saved disabled Exchange Offer product IDs to the configured maximum.<\/li>\n<\/ul>\n\n<h4>1.1.19<\/h4>\n\n<ul>\n<li>Refined frontend price styling so price labels and values inherit the corrected EZFRIPL price size without double scaling.<\/li>\n<li>Scoped container-query product grid rules to Friend Product Links modules.<\/li>\n<li>Kept responsive container-based product grids and theme-resistant price styling intact.<\/li>\n<\/ul>\n\n<h4>1.1.18<\/h4>\n\n<ul>\n<li>Fixed frontend price styling being overridden by theme price span rules.<\/li>\n<li>Applied Friend Product Links price color, size, and weight directly to price labels and values.<\/li>\n<li>Added container-query based responsive grids so Core Friends and Exchange Catalog respond to their actual module width.<\/li>\n<li>Kept viewport media queries as fallback for older browsers.<\/li>\n<\/ul>\n\n<h4>1.1.17<\/h4>\n\n<ul>\n<li>Moved automatic Core Friends rendering later in the WooCommerce single product page flow.<\/li>\n<li>Centered the Core Friends frontend module title.<\/li>\n<li>Unified Friend Product Links button and price colors using theme\/WooCommerce color variables with a red fallback.<\/li>\n<li>Kept buttons and prices consistent between Core Friends and Exchange Catalog.<\/li>\n<li>Replaced remaining hard-coded product-count messages with constants.<\/li>\n<\/ul>\n\n<h4>1.1.16<\/h4>\n\n<ul>\n<li>Moved automatic Core Friends output later in the WooCommerce single product page flow so store related products appear first.<\/li>\n<li>Updated frontend price color to use theme\/WooCommerce color variables with a red-orange fallback.<\/li>\n<li>Kept button styling controlled by the active theme.<\/li>\n<li>Replaced remaining hard-coded Core and Exchange product-count messages with constants.<\/li>\n<\/ul>\n\n<h4>1.1.15<\/h4>\n\n<ul>\n<li>Updated Core Friends frontend rendering to display up to 4 products per core friend.<\/li>\n<li>Updated Core Product Links minimum product requirement from 3 to 4 products.<\/li>\n<li>Replaced remaining Core Product Link product-count hardcoding with constants.<\/li>\n<li>Improved frontend price styling with larger, bold red prices.<\/li>\n<li>Preserved Exchange Catalog 4-product display and responsive 4\/3\/2\/1 frontend grids.<\/li>\n<\/ul>\n\n<h4>1.1.14<\/h4>\n\n<ul>\n<li>Fixed Exchange Catalog grid displacement caused by WooCommerce products clearfix and product layout styles.<\/li>\n<li>Switched plugin frontend grids to plugin-controlled layout classes while preserving theme-friendly title, price, and button classes.<\/li>\n<li>Strengthened frontend image sizing and title clamping so product cards render consistently in responsive 4\/3\/2\/1 grids.<\/li>\n<li>Updated remaining Exchange admin copy to reflect the 4-to-9 product offer requirement and 4-product catalog display.<\/li>\n<\/ul>\n\n<h4>1.1.13<\/h4>\n\n<ul>\n<li>Changed Exchange Catalog partner display count from 3 to 4 products to better match the responsive 4-column frontend grid.<\/li>\n<li>Updated Exchange Offer minimum product requirement to 4 products.<\/li>\n<li>Improved frontend product image sizing so product images fill the product card area consistently.<\/li>\n<li>Strengthened title clamping so long product titles stay within two lines.<\/li>\n<li>Improved grid item width resets to prevent themes from compressing plugin product cards.<\/li>\n<li>Preserved Core Friends friend limit and existing Core Friends business rules.<\/li>\n<\/ul>\n\n<h4>1.1.12<\/h4>\n\n<ul>\n<li>Fixed WooCommerce products clearfix pseudo-elements from interfering with plugin CSS Grid layouts.<\/li>\n<li>Added local WooCommerce wrapper classes so Exchange Catalog and Core Friends inherit theme product styles more reliably.<\/li>\n<li>Improved cached text normalization for product titles and price text.<\/li>\n<li>Kept responsive 4\/3\/2\/1 frontend grids and theme-friendly product card rendering intact.<\/li>\n<\/ul>\n\n<h4>1.1.11<\/h4>\n\n<ul>\n<li>Switched frontend product grids to WooCommerce-compatible ul.products \/ li.product markup.<\/li>\n<li>Strengthened responsive grid resets to prevent theme float and width rules from breaking the 4\/3\/2\/1 layout.<\/li>\n<li>Reduced hard-coded image and module title styling so frontend output follows the active theme more closely.<\/li>\n<li>Improved frontend stylesheet loading reliability for shortcode and template usage.<\/li>\n<li>Added a standard upgrade notice reminding users to re-sync cached products after updating.<\/li>\n<\/ul>\n\n<h4>1.1.10<\/h4>\n\n<ul>\n<li>Ensured frontend styles load early on product and Exchange Catalog pages.<\/li>\n<li>Added WooCommerce-compatible product grid classes for Core Friends and Exchange Catalog.<\/li>\n<li>Improved responsive 4\/3\/2\/1 product grid stability across themes.<\/li>\n<li>Reduced hard-coded frontend card styling so product cards follow the active theme more closely.<\/li>\n<li>Kept clean price rendering, local image fallback handling, and Core Friends fallback rendering intact.<\/li>\n<\/ul>\n\n<h4>1.1.9<\/h4>\n\n<ul>\n<li>Unified frontend product grids for Core Friends and Exchange Catalog with responsive 4\/3\/2\/1 columns.<\/li>\n<li>Improved WooCommerce theme compatibility for frontend product cards.<\/li>\n<li>Kept frontend product data sanitization and clean price rendering intact.<\/li>\n<li>Preserved Core Friends display logic while updating its responsive layout.<\/li>\n<\/ul>\n\n<h4>1.1.8<\/h4>\n\n<ul>\n<li>Fixed frontend product card rendering for Core Friends and Exchange Catalog.<\/li>\n<li>Reworked clean price text generation to avoid WooCommerce screen-reader price text and HTML entities.<\/li>\n<li>Improved validation for product image URLs before caching.<\/li>\n<li>Removed empty image placeholders when products have no image.<\/li>\n<li>Improved Core Friends frontend rendering with safer filtering and a fallback WooCommerce hook.<\/li>\n<li>Improved admin hints for disabled Core Friends with cached products.<\/li>\n<\/ul>\n\n<p>After updating, sync your Core Friends and Exchange Partners again to refresh cached product images and prices.<\/p>\n\n<h4>1.1.7<\/h4>\n\n<ul>\n<li>Fixed Exchange partner sync recovery for degraded_missing_catalog partners.<\/li>\n<li>Hardened Exchange request approve\/reject actions against stale request status submissions.<\/li>\n<\/ul>\n\n<h4>1.1.6<\/h4>\n\n<ul>\n<li>Moved Core Friends Mode to the top of the Settings page as an always-on mode card.<\/li>\n<li>Added a locked green ON switch for Core Friends Mode.<\/li>\n<li>Reorganized Settings page sections to make plugin modes clearer.<\/li>\n<\/ul>\n\n<h4>1.1.5<\/h4>\n\n<ul>\n<li>Improved Exchange Catalog Mode settings UI with a clear ON\/OFF switch.<\/li>\n<li>Added clearer mode status messaging for Exchange Catalog setup.<\/li>\n<li>Kept Exchange Catalog Mode save and page creation logic unchanged.<\/li>\n<\/ul>\n\n<h4>1.1.4<\/h4>\n\n<ul>\n<li>Fixed Settings page repair form markup by removing nested form output.<\/li>\n<li>Reworked Exchange Catalog admin page to use the bound catalog page manager status instead of the legacy manual shortcode flow.<\/li>\n<li>Hardened exchange approval callback offer URL comparison by normalizing the received and expected offer URLs.<\/li>\n<li>Added async image decoding for Exchange Catalog frontend images.<\/li>\n<\/ul>\n\n<h4>1.1.3<\/h4>\n\n<ul>\n<li>Fixed Exchange Catalog readiness checks after automatic catalog page creation.<\/li>\n<li>Enforced remote offer catalog readiness validation for exchange mode, catalog status, and catalog URL.<\/li>\n<li>Fixed Settings repair form markup with no nested forms.<\/li>\n<li>Fixed Exchange Catalog frontend rendering when the catalog page is missing or invalid.<\/li>\n<li>Fixed partner degraded_missing_catalog sync state handling.<\/li>\n<li>Hardened exchange approval callback offer URL matching.<\/li>\n<\/ul>\n\n<h4>1.1.1<\/h4>\n\n<ul>\n<li>Fixed Exchange Catalog runtime loader for frontend renderer and click tracker classes.<\/li>\n<li>Hardened exchange partner\/request matching with exact normalized offer URL comparisons.<\/li>\n<li>Improved exchange approval handshake to avoid one-sided activation when local partner creation fails.<\/li>\n<li>Rendered the first 3 valid exchange products from each partner cache.<\/li>\n<li>Showed Exchange Partner clicks sent in the partner management table.<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Added Exchange Catalog module: plugin constants, generic product picker, and admin JS improvements.<\/li>\n<li>Updated Core Friends menu labels to distinguish from Exchange Catalog.<\/li>\n<li>Made the Copy Link button fall back to execCommand when the clipboard API fails.<\/li>\n<\/ul>\n\n<h4>1.0.3<\/h4>\n\n<ul>\n<li>Fixed friend website URL validation when generating My Product Links. The generation step now validates URL format only and no longer blocks offline or DNS-restricted friend sites.<\/li>\n<li>Kept strict public URL validation for feed fetching, product URLs, image URLs, redirects, and stats endpoints.<\/li>\n<\/ul>\n\n<h4>1.0.2<\/h4>\n\n<ul>\n<li>Fixed admin share-link form submission hardening for WooCommerce Select2 product IDs.<\/li>\n<li>Added clearer validation messages when selected products are filtered out because they are not public visible products.<\/li>\n<li>Declared WooCommerce HPOS custom order table compatibility.<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Tightened product validation so only public visible WooCommerce products are saved.<\/li>\n<li>Fixed aggregate performance table uniqueness so different friend feeds do not merge stats.<\/li>\n<li>Hardened stats signature\/key validation and click redirect hash handling.<\/li>\n<li>Added safer save failure handling for admin forms.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial MVP.<\/li>\n<\/ul>","raw_excerpt":"A free P2P WooCommerce plugin for exchanging selected friend product links with local caching and aggregated performance stats.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/340234","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=340234"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/daijianpu"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=340234"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=340234"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=340234"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=340234"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=340234"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=340234"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}