NONE_IN_USAGE, \__('You must have at least one license of a site in use within your multisite.', RPM_WP_CLIENT_TD)); } } // Validate license keys foreach ($licenses as $value) { $blogId = $value['blog']; $installationType = $value['installationType']; $code = $value['code']; $noUsage = $value['noUsage']; if (isset($currentLicenses[$blogId])) { $activation = $currentLicenses[$blogId]->getActivation(); if ($noUsage) { $activation->skip(\true); } else { $result = $activation->activate($code, $installationType, $telemetry, $newsletterOptIn, $firstName, $email); // Ignore already existing activations as they should not lead to UI errors if (\is_wp_error($result) && $result->get_error_code() !== LicenseActivation::ERROR_CODE_ALREADY_ACTIVATED) { $errorText = \join(' ', $result->get_error_messages()); switch ($result->get_error_code()) { case 'http_request_failed': $errorText = \sprintf( // translators: \__('The license server for checking the license cannot be reached. Please check if you are blocking access to %s e.g. by a firewall.', RPM_WP_CLIENT_TD), $provider ); break; default: break; } $invalidKeys[$blogId] = ['validateStatus' => 'error', 'hasFeedback' => \true, 'help' => $errorText, 'debug' => $result]; } } } else { return new WP_Error(PluginUpdate::ERROR_CODE_BLOG_NOT_FOUND, '', ['blog' => $blogId]); } } return empty($invalidKeys) ? \true : new WP_Error(PluginUpdate::ERROR_CODE_INVALID_KEYS, $invalidKeys[\array_keys($invalidKeys)[0]]['help'], ['invalidKeys' => $invalidKeys]); } /** * Get the license for the current blog id. * * @return License */ public function getCurrentBlogLicense() { $blogId = \get_current_blog_id(); $licenses = $this->getLicenses(\false, [$blogId]); return \array_shift($licenses); } /** * Get first found license as we can not update per-site in multisite (?). */ public function getFirstFoundLicense() { $licensedBlogIds = $this->getLicensedBlogIds(\false, \true)['_']; if (\count($licensedBlogIds) === 0) { return \false; } foreach ($licensedBlogIds as $blogId) { $licenses = $this->getLicenses(\false, [$blogId]); foreach ($licenses as $license) { if ($license->isFulfilled()) { return $license; } } } return \false; } /** * Get a list of licensed blog IDs. * * @param boolean|string $invalidate If `true` it will invalidate the transient, or `"never"` to get the value independent of cache expiration * @param boolean $returnCurrentOnNonMultisite * @return array|false Array with hostname as key and blog IDs as value. If it is not multisite, it returns `false` (see also `$returnCurrentOnNonMultisite`) */ public function getLicensedBlogIds($invalidate = \false, $returnCurrentOnNonMultisite = \false) { if (\is_multisite()) { $transientName = \sprintf('%s-licensedBlogIds_v2_%s', RPM_WP_CLIENT_OPT_PREFIX, $this->getInitiator()->getPluginSlug()); $expireOption = new ExpireOption($transientName, \true, 1 * DAY_IN_SECONDS, \true); if ($invalidate === 'never') { return $expireOption->get(['_' => []], \false); } $transientValue = $invalidate ? \false : $expireOption->get(\false); if (!\is_array($transientValue)) { $transientValue = [ // A collection of all blog ids '_' => [], ]; $this->suppressGetLicensesWpDie = \true; foreach ($this->getUniqueLicenses(\true) as $license) { if (!empty($license->getActivation()->getCode())) { $hostname = $license->getCurrentHostname(); $transientValue['_'][] = $license->getBlogId(); $transientValue[$hostname] = $transientValue[$hostname] ?? []; $transientValue[$hostname][] = $license->getBlogId(); } } $this->suppressGetLicensesWpDie = \false; $expireOption->set($transientValue); } return $transientValue; } elseif ($returnCurrentOnNonMultisite) { $license = $this->getCurrentBlogLicense(); $currentHostname = $license->getCurrentHostname(); $currentBlogId = $license->getBlogId(); return $this->getCurrentBlogLicense()->isFulfilled() ? ['_' => [$currentBlogId], $currentHostname => [$currentBlogId]] : ['_' => []]; } return \false; } /** * Get all licenses for each blog (when multisite is enabled). Attention: If a blog * uses the same hostname as a previous known blog, they share the same `License` instance. * * @param boolean $checkRemoteStatus * @param int[] $inBlogIds If set only return the list of this blog IDs * @return License[] */ public function getLicenses($checkRemoteStatus = \false, $inBlogIds = null) { global $pagenow; /** * Short circuit when getting only a set of blogs. * * @var License[] */ $inBlogIdsLicenses = []; if ($this->licenses === null || $checkRemoteStatus || \is_array($inBlogIds)) { $blogIds = $this->getPotentialBlogIds($inBlogIds); $hostnames = Utils::mapBlogsToHosts($blogIds); /** * Create licenses per hostname and prefer the blog ID which holds an active license, * otherwise take the first one. * * @var License[] */ $licensedBlogIds = $this->getLicensedBlogIds('never', \false); $hostLicenses = []; foreach ($hostnames['host'] as $host => $hostBlogIds) { $hostBlogId = $hostBlogIds[0]; // Prefer an active license within a multisite for this host if ($licensedBlogIds !== \false && isset($licensedBlogIds[$host])) { $hostBlogId = $licensedBlogIds[$host][0]; } $cacheKey = $host . ':' . $hostBlogId; $hostLicenses[$host] = $this->licenseCache[$cacheKey] ?? new License($this, $host, $hostBlogId); $this->licenseCache[$cacheKey] = $hostLicenses[$host]; } // Create licenses per blog ID and point to hostname-license if ($inBlogIds === null) { $this->licenses = []; $isDevEnv = \defined('DEVOWL_WP_DEV') && \constant('DEVOWL_WP_DEV'); if ($isDevEnv && \is_admin() && $pagenow === 'index.php' && !$this->suppressGetLicensesWpDie) { \wp_die(\sprintf('You are calling %s at page load which leads to performance issues on multisite. This text is only visible to development environments and never to end users of the plugin! Backtrace:

%s
', __METHOD__, \json_encode(\debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 10), \JSON_PRETTY_PRINT))); } } foreach ($blogIds as $blogId) { $host = $hostnames['blog'][$blogId]; $license = $hostLicenses[$host]; if ($checkRemoteStatus) { $license->fetchRemoteStatus(\true); } $license->initialize(); if ($inBlogIds === null) { $this->licenses[$blogId] = $license; } else { $inBlogIdsLicenses[$blogId] = $license; } } } return $inBlogIds === null ? $this->licenses : $inBlogIdsLicenses; } /** * The same as `getLicenses`, but only get unique `License` instances. * * Use this with caution as it leads to iterate all subsites within your multisite! * * @param boolean $skipNoUsage Pass `true` to skip licenses which are not in usage * @return License[] */ public function getUniqueLicenses($skipNoUsage = \false) { $result = []; foreach ($this->getLicenses() as $license) { if ($skipNoUsage && $license->isNoUsage()) { continue; } $result[$license->getBlogId()] = $license; } return \array_values($result); } /** * Get license activation client. * * @codeCoverageIgnore */ public function getLicenseActivationClient() { return $this->licenseActivationClient; } }