namespace Extendify\Shared\DataProvider;
defined('ABSPATH') || die('No direct access.');
use Extendify\Assist\Controllers\DomainsSuggestionController;
use Extendify\Assist\Controllers\RecommendationsController;
use Extendify\HelpCenter\Controllers\SupportArticlesController;
use Extendify\Shared\Services\Sanitizer;
public function __construct()
if (!(is_admin() || defined('DOING_CRON'))) {
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
add_action('http_api_curl', function ($handle, $_req, $url) {
// Allow a longer timeout for this request since it happens in a scheduler.
if (strpos($url, 'api/domains/suggest') !== false) {
curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 150); // phpcs:ignore
curl_setopt($handle, CURLOPT_TIMEOUT, 150); // phpcs:ignore
* Register the cache schedule.
public static function scheduleCache()
\add_action('init', function () {
// phpcs:ignore WordPress.WP.CronInterval -- Verified > 30 days.
\add_filter('cron_schedules', function ($schedules) {
$schedules['extendify_every_month'] = [
'interval' => (30 * DAY_IN_SECONDS), // phpcs:ignore
'display' => __('Every month', 'extendify-local'),
if (! \wp_next_scheduled('extendify_cache_data')) {
(\current_time('timestamp') + DAY_IN_SECONDS), // phpcs:ignore
\add_action('extendify_cache_data', function () {
if (!defined('EXTENDIFY_PARTNER_ID')) {
$resourceData = new ResourceData();
$resourceData->cacheData('recommendations', RecommendationsController::fetchRecommendations()->get_data());
$resourceData->cacheData('supportArticles', SupportArticlesController::fetchArticles()->get_data());
// For domains, only update when the site title changes.
\add_action('update_option_blogname', function () {
if (!defined('EXTENDIFY_PARTNER_ID')) {
wp_schedule_single_event(time(), 'extendify_update_domains_cache');
\add_action('extendify_update_domains_cache', function () {
if (!defined('EXTENDIFY_PARTNER_ID')) {
$data = DomainsSuggestionController::fetchDomainSuggestions()->get_data();
set_transient('extendify_domains', Sanitizer::sanitizeArray($data));
public function getData()
if (!defined('EXTENDIFY_PARTNER_ID')) {
$domains = get_transient('extendify_domains');
wp_schedule_single_event(time(), 'extendify_update_domains_cache');
'recommendations' => $this->recommendations(),
'supportArticles' => $this->supportArticles(),
// Domains are now cached forever until the site title changes.
* Return the recommendations. Fetch them if not found (or on a schedule).
* @return mixed|\WP_REST_Response
protected function recommendations()
$recommendations = get_transient('extendify_recommendations');
if ($recommendations === false) {
// Fetch these immediately if not found.
$recommendations = RecommendationsController::fetchRecommendations()->get_data();
$this->cacheData('recommendations', $recommendations);
* Return the support articles. Fetch them if not found (or on a schedule).
* @return mixed|\WP_REST_Response
protected function supportArticles()
$supportArticles = get_transient('extendify_supportArticles');
if ($supportArticles === false) {
$supportArticles = SupportArticlesController::fetchArticles()->get_data();
$this->cacheData('supportArticles', $supportArticles);
* This stores the data as a transient.
* @param string $functionName The function name that we use in the store.
* @param array $data The extracted data returned from the HTTP request.
protected function cacheData($functionName, $data)
// The scheduler runs monthly, one day before the cache expires.
'extendify_' . $functionName,
Sanitizer::sanitizeArray($data),
(DAY_IN_SECONDS + MONTH_IN_SECONDS)