Due to recent changes in the Transifex service, po
files were formatted differently than before. This in turn caused erroneous compilation of mo
files.
This resulted in strings showing up as blank in the new Opt-In UI.
We are serving a quick patch to fix the error in this release. We will also revamp our build process to update it with the current Transifex conventions.
We improved the error handling in the library code used to communicate with the API. This will prevent the issue where wp_remote_request
could return a WP_Error
instance and the system would fail with an error message:
Fatal error: Uncaught Error: Cannot use object of type WP_Error as array
In version 2.5.4
, among many other improvements, we enhanced the internal PHP SDK used to communicate with the Freemius API and added new helper functions. Those changes are meant for internal use of SDK, and changing them shouldn't have caused any issues.
However, after developers started to release new versions of their products with version 2.5.4, we began to receive reports of the following fatal PHP error:
Fatal error: Uncaught Error: Call to undefined method Freemius_Api_WordPress::RemoteRequest()
After being able to investigate some of the affected sites, we found that all of them were running a plugin that was using a custom-modified version of the SDK, which bypassed the SDK's logic that is responsible for using the latest SDK available in the environment while using the same class names for the internal PHP SDK. Meaning when WordPress loaded a plugin with such a custom SDK before a plugin/theme that uses 2.5.4, an outdated version of the internal PHP SDK was loaded, which was missing the newly added Freemius_Api_WordPress::RemoteRequest()
method.
We reached out to the developers that made those customizations but haven't yet heard from them. Plus, even if they would release new versions of their plugins with the standard SDK, it will take time until those changes propagate to the affected websites. So, to mitigate those compatibility issues, we are releasing 2.5.5
, where our SDK can work in harmony parallel to those custom-modified, non-standard integrations, with a minimum impact.
Whether you received complaints about the incompatibility or not, we urge that you update and release a new version of your product with the latest release.
As a long-term solution, we consider identifying unexpected SDK customizations during deployment and either warn the developer about the potential consequences or prohibit those altogether.
Starting from this version, the WordPress SDK no longer makes a connectivity test (aka ping.json
) to the Freemius API upon plugin/theme activation.
This now-obsolete feature, which was initially used to improve user experience (more on that down below) and later proved to be a cause for concern among users, is finally down and out.
For demonstration, I downloaded the latest version of TablePress, which uses Freemius, and manually updated the SDK to 2.5.4. Here’s what happens after activation:
Voilà 🎊 As you can see on Snitch, a plugin that monitors remote requests, no HTTP requests were made after plugin activation.
After launching the WordPress SDK, we quickly discovered that API connectivity could not be taken for granted. Whether it’s related to cURL misconfiguration, HTTPS or OpenSSL issues, firewalls, or regional ISP blockages, servers are sometimes unable to make remote requests.
After researching popular plugins with an opt-in component, we stumbled upon Jetpack. The plugin initiates a connectivity test immediately after activation. You can test it yourself:
Long story short, as this approach enabled us to resolve the challenge we were facing — along with the fact that Jetpack is a super popular plugin with millions of active installs and developed by Automattic — we decided to replicate this approach to make sure we didn’t show the opt-in to users who wouldn’t be able to opt-in anyway due to connectivity issues.
The connectivity test was also useful in identifying clock differences between the WP site and the API server, which is essential for security reasons. This allowed developers to limit the exposure of the SDK — or even turn it off completely — without the need to release a new version.
If you are a developer who has been using the moderation capabilities, make sure to read the next section.
By removing the connectivity test, the moderation capabilities had to be transitioned to SDK settings. So, if you are using the moderation section in the Developer Dashboard to activate Freemius only for new installs or you limit the number of installs, please make sure to add the new config.
So, for example, the settings to only show the opt-in for new installations looks like this:
'opt_in_moderation' => array(
'new' => 100,
'updates' => 0,
'localhost' => true,
),
'new'
(int | boolean
): An integer from 0
to 100
to control the exposure percentage of the opt-in to new product installs. It also supports a boolean value. When set to true
, then assume 100% exposure; if set to false
, then no exposure at all. Defaults to true
(as 100%) when not set.'updates'
(int | boolean
): Exactly as the ‘new’
param, but controls the opt-in exposure for product updates (i.e., what % of websites will see the opt-in after upgrading to a new version with the Freemius SDK, when the previous version didn’t include the SDK).'localhost'
(boolean
): Whether to show the opt-in on localhost sites. Default's to true
if not set.You can now override the in-dashboard checkout URL across the entire SDK by using the 'checkout_url'
filter. Or you can use the 'update_notice_checkout_url'
to specifically set the checkout URL shown in the admin notice when a license has expired.
💡 We have improved the logic determining if WP is executed via an HTTP/S request, which resolves some PHP notices when WordPress gets executed via WP CLI or through an actual server cronjob with define('DISABLE_WP_CRON', true)
.
💡 Added support for Kinsta's new staging environment URL patterns.
🐞 Fixed the permissions state after upgrading to a paid version in anonymous mode.
🐞 Fixed the in-dashboard affiliate application form submission.
SDK version 2.5.4 was thoroughly code reviewed, fully tested, soft-released as a release candidate more than 3 weeks ago to give enough time for testing, and is already running in production with our own plugin since last week without any issues. While we have high confidence it's production-ready because the change is on the infrastructure level, it's inevitably of a higher risk. So please take the time to test before deploying.
Starting from this version, the WordPress SDK no longer makes a connectivity test (aka ping.json
) to the Freemius API upon plugin/theme activation.
This now-obsolete feature, which was initially used to improve user experience (more on that down below) and later proved to be a cause for concern among users, is finally down and out.
For demonstration, I downloaded the latest version of TablePress, which uses Freemius, and manually updated the SDK to 2.5.4. Here’s what happens after activation:
Voilà 🎊 As you can see on Snitch, a plugin that monitors remote requests, no HTTP requests were made after plugin activation.
After launching the WordPress SDK, we quickly discovered that API connectivity could not be taken for granted. Whether it’s related to cURL misconfiguration, HTTPS or OpenSSL issues, firewalls, or regional ISP blockages, servers are sometimes unable to make remote requests.
After researching popular plugins with an opt-in component, we stumbled upon Jetpack. The plugin initiates a connectivity test immediately after activation. You can test it yourself:
Long story short, as this approach enabled us to resolve the challenge we were facing — along with the fact that Jetpack is a super popular plugin with millions of active installs and developed by Automattic — we decided to replicate this approach to make sure we didn’t show the opt-in to users who wouldn’t be able to opt-in anyway due to connectivity issues.
The connectivity test was also useful in identifying clock differences between the WP site and the API server, which is essential for security reasons. This allowed developers to limit the exposure of the SDK — or even turn it off completely — without the need to release a new version.
If you are a developer who has been using the moderation capabilities, make sure to read the next section.
By removing the connectivity test, the moderation capabilities had to be transitioned to SDK settings. So, if you are using the moderation section in the Developer Dashboard to activate Freemius only for new installs or you limit the number of installs, please make sure to add the new config.
So, for example, the settings to only show the opt-in for new installations looks like this:
'opt_in_moderation' => array(
'new' => 100,
'updates' => 0,
'localhost' => true,
),
'new'
(int | boolean
): An integer from 0
to 100
to control the exposure percentage of the opt-in to new product installs. It also supports a boolean value. When set to true
, then assume 100% exposure; if set to false
, then no exposure at all. Defaults to true
(as 100%) when not set.'updates'
(int | boolean
): Exactly as the ‘new’
param, but controls the opt-in exposure for product updates (i.e., what % of websites will see the opt-in after upgrading to a new version with the Freemius SDK, when the previous version didn’t include the SDK).'localhost'
(boolean
): Whether to show the opt-in on localhost sites. Default's to true
if not set.You can now override the in-dashboard checkout URL across the entire SDK by using the 'checkout_url'
filter. Or you can use the 'update_notice_checkout_url'
to specifically set the checkout URL shown in the admin notice when a license has expired.
💡 We have improved the logic determining if WP is executed via an HTTP/S request, which resolves some PHP notices when WordPress gets executed via WP CLI or through an actual server cronjob with define('DISABLE_WP_CRON', true)
.
💡 Added support for Kinsta's new staging environment URL patterns.
🐞 Fixed the permissions state after upgrading to a paid version in anonymous mode.
🐞 Fixed the in-dashboard affiliate application form submission.
SDK version 2.5.4 was thoroughly code reviewed and fully tested. While we have high confidence it's production-ready because the change is on the infrastructure level, it's inevitably of a higher risk. Along with the fact that many of the Freemius team are traveling to WordCamp Asia this week (meet us 🤝) and many of us will stay in Thailand for another week of vacation, we decided that it wouldn’t be responsible to release it as a final version before we're back in full capacity at our home offices with strong internet and the proper working environment to react promptly if/as needed.
Dear Freemius partners, we need your help in testing the release candidate.
If you're using the SDK functions beyond the standard integration snippet, please verify your integration still works as expected.
If you have automated testing, please make sure to run your tests to verify those are still passing ✅ If you don't, you can still help by running sanity testing with the new SDK.
We're super pumped for WordCamp Asia. The team is flying to Bangkok from four continents 🗺 It’s an exciting opportunity to finally meet fellow “Freemians” face2face 😁 This was something that was planned a long time ago in 2020, but we all know how it ended 🤷♂️
We’re looking forward to hanging out with community members, catching up with friends, establishing new connections, and talking to plugin & theme developers and other product makers.
We are also eager to meet with freelancers, agencies, and anyone who’s building websites professionally, as we are looking for feedback on how we can make Freemius even more awesome for professional builders.
With that said…
Heads up, we're transitioning to maintenance mode for the next two weeks (until Feb 26th). We will keep providing support throughout the entire period, with a focus on pressing issues.
WordPress supports having a special header Requires PHP
in a plugin's readme.txt
file. If this is present and the current web-host is not running a compatible PHP version WordPress blocks plugin updates.
Following feedback from our partners, we have added the same capability in our SDK and deployment strategy. If you include the Requires PHP
header in your plugin's readme.txt
file, the SDK will show an appropriate notice in the update page and will block update if needed.
If the current WordPress version is a patch of the "Tested up to" version (e.g., 6.1.2
is a patch of 6.1
), then our SDK will now detect it and will show that the plugin is compatible with it. This saves a false positive notice and also saves our partners from having to deploy a version just to bump a patched "Tested up to" header.
We've found some compatibility issues with how FS_Admin_Menu_Manager
was called when running our SDK with PHP 8.1. With this release, the issue has been fixed.
Patches version 2.5.1 by adding assets/css/admin/optout.css
(and optout.css.map
), a CSS stylesheet for styling the new opt-out permissions dialog.
All of the features and updates included in version 2.5.0-RC.1 (a release candidate) are now part of the SDK. If you are still on 2.4.x (or below), please take the time to review the previous release notes to familiarize yourself with the expected updates.
Here are 2.5.0-RC.1 highlights:
The new SDK version resolves all reported PHP 8 incompatibility issues and warnings 🐘
The Safe Mode & Clone Resolution mechanism introduced in 2.5.0-RC.1 is officially out of beta. In addition to the bug fixed during the beta period:
We’ve also introduced a new FS__RESOLVE_CLONE_AS
flag, which allows you to programmatically guide the mechanism for resolving clones upon site replication. The flag can easily be added to a site’s wp-config.php
(or functions.php
) with one of the following values:
// A temporary duplication for the purpose of testing, staging, or development.
define( 'FS__RESOLVE_CLONE_AS', 'temporary_duplicate' );
// The new site is replacing the old one — this will migrate the license activation to the new site to resolve the clone.
define( 'FS__RESOLVE_CLONE_AS', 'new_home' );
// The cloned site is a new and different one — this will automatically activate the license on the new site to resolve the clone.
define( 'FS__RESOLVE_CLONE_AS', 'long_term_duplicate' );
Following tons of feedback, we are excited to introduce the next generation of our opt-in screen 🎊
In addition to the slicker UI:
Like the opt-in, the license activation also went through a similar UI and framing refresh. What’s even more exciting is that licenses can now be activated with a minimal data footprint. This means only sharing the essentials needed for Freemius’s license & updates delivery engine:
That’s it!
So anyone sensitive about privacy can easily expand the permissions list and toggle off the new Diagnostic Info permission. This skips the sharing of WordPress & PHP versions, and site language & title.
Thanks, Chris Wiegman, for providing your feedback on it!
After our CEO Vova Feldman participated in a live QA about Freemius, a concern was raised about sharing user IPs.
For context, the IP was used to identify users’ geolocation to help developers recognize which languages & regions their plugin/theme should be translated and tailored to. It can also be used for security purposes to flag suspicious activity and prevent impersonation.
Even though it was only shared with user consent upon opting in, we have re-evaluated the need for this data point and decided to remove it altogether:
https://github.com/Freemius/wordpress-sdk/pull/580/files
Along with the user IP removal, we’ve also stopped sharing the nickname of the opting in user — this was used as a placeholder when the user had an empty first and last name.
Thanks, Sean D., for bringing it to our attention!
When we launched Freemius in 2015, the WordPress.org repository didn’t have the active installs growth chart (which was recently back in the news after its removal). At the time, plugin and theme developers were “thirsty” to understand how efforts to improve their products impacted adoption. To solve this problem and give developers an accurate picture of their product usage, skipping the Freemius opt-in also sent an anonymous ping, which increased the product’s “skips” counter. Along with the Deactivation Feedback Form and some heuristics, we could offer an estimate of the product’s audience size.
Long story short: over the years, we realized the skips counter is far from accurate, unreliable, and prone to errors, which is why we’ve removed it from the new dashboard. Combined with the fact that some didn't like this behavior, the Skip button is just for skipping the opt-in now. That's it.
The connection between the SDK and the Freemius API is secured with public/private keys and we manage a single entity per email address. If a person with the same email address has already opted in on another website, we have to make sure they are not impersonating by confirming the ownership of their address before sharing the keys with the website.
Following feedback (thanks, David McCan), we realized the email copy was confusing. We therefore revised the copy to clarify the purpose of the confirmation:
To make the opt-in permissions more flexible and allow users to pick and choose what they want to share, the team has introduced a brand new permissions management layer for free and paid products.
Clicking the Opt Out action link now opens a new dialog box where users can selectively choose which of the permissions they want to opt out from or keep sharing:
The granular permissions support new states that were not supported before. For example, a user can stay subscribed to receive email updates from the product team while opting out from sharing diagnostic info about their WordPress environment.
And here’s how it looks for paid products:
The new permissions layer comes with complementary events you can consume through a webhook:
install.extensions.opt_in
Occurs whenever a user opts in for sharing a website’s plugins & themes list after previously opting out from it.
install.extensions.opt_out
Occurs whenever a user opts out from sharing a website’s plugins & themes list after previously sharing it.
install.user.opt_in
Occurs whenever a user opts in for sharing their basic profile info after previously opting out from it.
install.user.opt_out
Occurs whenever a user opts out from sharing their basic profile info after previously sharing it.
You can find the complete events list here:
https://freemius.com/help/documentation/marketing-automation/events-webhooks/
Important:
install.connected
and install.disconnected
will be renamed to install.site.opt_in
and install.site.opt_out
(correspondingly). So, if you “listen” to any of these events through a custom webhook, make sure to update the webhook to support the new event names before.install.user.opt_out
occurs, and optionally resubscribing them on install.user.opt_in
.We’ve introduced a new set of actions to enable more advanced (yet still structured) customization of the opt-in screen:
connect/before
For adding text or visual elements before/above the opt-in container.
connect/after
For adding text or visual elements after/below the opt-in container.
connect/before_message
For adding text or visual elements before/above the opt-in message header (within the opt-in container).
connect/after_message
For adding text or visual elements after/below the opt-in message (within the opt-in container).
connect/before_actions
For adding text or visual elements before/above the opt-in action buttons.
connect/after_actions
For adding text or visual elements after/below the opt-in action buttons.
You can find the complete documentation of the opt-in screen customization options here:
https://freemius.com/help/documentation/wordpress-sdk/opt-in-message/
Since version 2.0.1, the SDK comes with advanced support for multi-site networks. As part of the implementation, we needed a way to identify if an admin notice needed to be dismissed from the network admin or site-level admin.
Unfortunately, due to WordPress limitations, there’s no way to programmatically know if an AJAX request was initiated from the network or sub-site admin. So, we came up with a simple jQuery snippet that intercepts WP Admin AJAX requests before they are triggered. This enriches them with a querystring flag based on the admin context so the backend code will have the proper context. We chose this approach because it was the easiest and most efficient code-wise.
Long story short, this implementation raised concerns as it gave the impression that the SDK was monitoring all AJAX requests. While it’s obviously not the case, we all know how impressions matter. So, I’m happy to share that we are no longer intercepting admin AJAX requests. The querystring flag is now only added to AJAX requests triggered by the SDK:
https://github.com/Freemius/wordpress-sdk/pull/578/files
Thanks, Amber C., for continually calling us out on this!
The SDK now automatically identifies staging & testing sites hosted on WPMU DEV, InstaWP, and Vendasta. This identification allows for license activation without deducting from the production activations quota. You can check the complete list of supported sites here:
https://freemius.com/help/documentation/selling-with-freemius/license-utilization/
To reduce confusion, the previously titled Delete link shown in the Account page is now titled Disconnect:
In addition, the link now shows a confirmation dialog box explaining exactly what the disconnection means:
Following the opt-in and license activation screen updates, we’ve introduced new strings and updated some of the previous ones to make the messaging clearer. We need your help in translating the strings:
https://www.transifex.com/freemius/wordpress-sdk/dashboard/
In addition, we now have a formal German translation team and will officially add the locale once it covers at least 50% of the strings.
After an in-depth investigation, the development team discovered that the SDK’s caching layer was redundant. Removing it resolved all sorts of caching issues for sites using Object Cache.
SECURE_AUTH_KEY
is missing, the SDK will no longer throw a PHP error and will work around the missing constant.We are moving away from mega releases and towards micro releases. It will allow for releasing new versions in much shorter cycles so that developers can enjoy the bug and compatibility fixes and new features in confidence, without the concern of using the develop
branch.
Once the new SDK gets adopted, we'll most likely discover more edge cases related to the clone resolution that we'll need to fix.
Except for those, we want to address several more (small) user-facing concerns in the next release.
In addition, we'd like to prioritize reevaluating the SDK's storage architecture. We received concerns about the size of the fs_option
record, so we are finally going to deep-dive to understand its impact. According to our findings, we’ll possibly need to adjust the storage design to reduce the resource consumption as much as possible.
Finally, we are well aware of the need for a lite SDK, and it's on our list. Once we finish handling the two concerns mentioned above, we'll get back to planning and designing what a ‘lite’ and more modular SDK could look like.
Thank you @matczar for the PR 🙌