File: /wordpress/plugins/wp-cloud-client/1.2.3/src/Settings/SettingsRepository.php
<?php
declare(strict_types=1);
namespace VPlugins\WPCloudClient\Settings;
class SettingsRepository {
private const OPTION_KEY = 'wpcc_settings';
/**
* Retrieve the configured site ID (9-char WP Cloud / Atomic site ID).
*
* Resolution order:
* 1. Atomic_Persistent_Data::ATOMIC_SITE_ID — platform-managed.
* 2. ATOMIC_SITE_ID constant — direct platform constant.
* 3. wpcc_site_id filter — last-resort hook.
*
* @return string|null Site ID or null if not resolvable.
*/
public function getSiteId(): ?string {
if ( class_exists( 'Atomic_Persistent_Data' ) ) {
$persistent = new \Atomic_Persistent_Data();
$v = trim( (string) ( $persistent->ATOMIC_SITE_ID ?? '' ) );
if ( '' !== $v ) {
return $v;
}
}
if ( \defined( 'ATOMIC_SITE_ID' ) && is_scalar( \ATOMIC_SITE_ID ) ) {
$v = (string) \ATOMIC_SITE_ID;
return '' !== $v ? $v : null;
}
try {
$value = (string) apply_filters( 'wpcc_site_id', '' );
} catch ( \Throwable $e ) {
error_log( '[WP Cloud Client] wpcc_site_id filter threw: ' . $e->getMessage() );
return null;
}
return '' !== $value ? $value : null;
}
/**
* Retrieve the Vendasta site ID (64-char VStore PK) for GA4 tracking.
*
* @return string|null Vendasta site ID or null if not set.
*/
public function getVendastaSiteId(): ?string {
if ( class_exists( 'Atomic_Persistent_Data' ) ) {
$persistent = new \Atomic_Persistent_Data();
$v = trim( (string) ( $persistent->WSP_SITE_ID ?? '' ) );
if ( '' !== $v ) {
return $v;
}
}
return null;
}
/**
* Retrieve the configured API key.
*
* Resolution order:
* 1. WSP_API_KEY constant — explicit override (wp-config.php or mu-plugin).
* 2. Atomic_Persistent_Data — platform-managed, not in DB; survives staging→prod pushes.
* 3. wpcc_api_key filter — last-resort hook.
*
* @return string|null API key or null if not set.
*/
public function getApiKey(): ?string {
if ( \defined( 'WSP_API_KEY' ) && is_scalar( \WSP_API_KEY ) ) {
$v = (string) \WSP_API_KEY;
return '' !== $v ? $v : null;
}
if ( class_exists( 'Atomic_Persistent_Data' ) ) {
$persistent = new \Atomic_Persistent_Data();
$v = trim( (string) ( $persistent->WSP_API_KEY ?? '' ) );
if ( '' !== $v ) {
return $v;
}
}
try {
$value = (string) apply_filters( 'wpcc_api_key', '' );
} catch ( \Throwable $e ) {
error_log( '[WP Cloud Client] wpcc_api_key filter threw: ' . $e->getMessage() );
return null;
}
return '' !== $value ? $value : null;
}
/**
* Retrieve the configured environment.
*
* Reads WSP_SITE_ENVIRONMENT from Atomic_Persistent_Data (PROD or DEMO).
* Defaults to 'PROD' if the value is absent.
*
* @return string Environment value ('PROD' or 'DEMO').
*/
public function getEnvironment(): string {
if ( class_exists( 'Atomic_Persistent_Data' ) ) {
$persistent = new \Atomic_Persistent_Data();
$value = trim( (string) ( $persistent->WSP_SITE_ENVIRONMENT ?? '' ) );
if ( '' !== $value ) {
return $value;
}
}
return 'PROD';
}
/**
* Check whether this site is a multisite installation.
*
* Reads WSP_SITE_TYPE from Atomic_Persistent_Data (SINGLE or MULTISITE).
* Defaults to false (single site) if not set.
*
* @return bool True if the site type is MULTISITE.
*/
public function isMultisite(): bool {
if ( class_exists( 'Atomic_Persistent_Data' ) ) {
$persistent = new \Atomic_Persistent_Data();
$value = strtoupper( trim( (string) ( $persistent->WSP_SITE_TYPE ?? '' ) ) );
return 'MULTISITE' === $value;
}
return false;
}
/**
* Check whether this site is a staging site.
*
* Reads WSP_STAGING from Atomic_Persistent_Data (TRUE or FALSE).
* Defaults to false if not set.
*
* @return bool True if staging is enabled.
*/
public function isStaging(): bool {
if ( class_exists( 'Atomic_Persistent_Data' ) ) {
$persistent = new \Atomic_Persistent_Data();
$value = strtoupper( trim( (string) ( $persistent->WSP_STAGING ?? '' ) ) );
return 'TRUE' === $value;
}
return false;
}
/**
* Retrieve the custom GA4 tracking ID.
*
* On multisite, this is a single network-wide value stored on the primary
* site, rather than a per-subsite value — every site in the network uses
* the same custom tracking ID (or falls back to the same platform default
* tracking ID, which is already identical across all sites regardless).
*
* @return string|null Tracking ID or null if not set.
*/
public function getGa4TrackingId(): ?string {
if ( $this->isMultisite() ) {
$value = trim( (string) ( get_blog_option( get_main_site_id(), self::OPTION_KEY, [] )['ga4_tracking_id'] ?? '' ) );
return '' !== $value ? $value : null;
}
return $this->get( 'ga4_tracking_id' );
}
/**
* Set the custom GA4 tracking ID.
*
* On multisite, always writes to the primary site's own settings,
* regardless of which site's admin the form was submitted from; see
* {@see self::getGa4TrackingId()}.
*
* @param string $value Tracking ID to store.
* @return bool True if the option was updated, false on failure.
*/
public function setGa4TrackingId( string $value ): bool {
if ( $this->isMultisite() ) {
$mainSiteId = get_main_site_id();
$current = get_blog_option( $mainSiteId, self::OPTION_KEY, [] );
$current = is_array( $current ) ? $current : [];
return (bool) update_blog_option( $mainSiteId, self::OPTION_KEY, array_merge( $current, [ 'ga4_tracking_id' => $value ] ) );
}
return $this->update( [ 'ga4_tracking_id' => $value ] );
}
/**
* Check whether the partner has enabled their own Google Analytics integration.
*
* Set via the Advanced Tools toggle (wp-cloud-manager's SetDefaultGoogleAnalytics
* RPC, sync_ga_settings action). When true, the partner is running their own GA
* setup independently, so the platform suppresses its default GA4 injection to
* avoid duplicating tracking. Defaults to false — platform tracking runs until
* the partner explicitly enables their own.
*
* @return bool True when the partner's own GA integration is active (platform tracking suppressed).
*/
public function isPartnerGaEnabled(): bool {
$value = $this->get( 'partner_ga_enabled' );
if ( null === $value ) {
return false;
}
return filter_var( $value, FILTER_VALIDATE_BOOLEAN );
}
/**
* Set whether the partner has enabled their own Google Analytics integration.
*
* @param bool $enabled True when the partner is running their own GA (suppresses platform tracking).
* @return bool True if the option was updated, false on failure.
*/
public function setPartnerGaEnabled( bool $enabled ): bool {
return $this->update( [ 'partner_ga_enabled' => $enabled ? '1' : '0' ] );
}
/**
* Check whether debug mode is enabled.
*
* @return bool True if debug mode is on.
*/
public function isDebugMode(): bool {
return (bool) $this->get( 'debug_mode' );
}
/**
* Check whether the wp-login.php page is exposed.
*
* Defaults to false (login hidden) so direct access to wp-login.php is
* redirected away unless the manager has explicitly exposed it via
* set_login_visibility.
*
* @return bool True if the login page is exposed, false if hidden.
*/
public function isLoginExposed(): bool {
return (bool) $this->get( 'expose_login' );
}
/**
* Set whether the wp-login.php page is exposed.
*
* @param bool $exposed True to expose the login page, false to hide it.
* @return bool True if the option was updated, false on failure.
*/
public function setLoginExposed( bool $exposed ): bool {
return $this->update( [ 'expose_login' => $exposed ? '1' : '' ] );
}
/**
* Retrieve the redirect URL for hidden login page access attempts.
*
* @return string Redirect URL, or empty string if not set.
*/
public function getLoginRedirectUrl(): string {
return (string) $this->get( 'login_redirect_url' );
}
/**
* Set the redirect URL for hidden login page access attempts.
*
* @param string $url URL to redirect unauthenticated visitors to.
* @return bool True if the option was updated, false on failure.
*/
public function setLoginRedirectUrl( string $url ): bool {
return $this->update( [ 'login_redirect_url' => $url ] );
}
/**
* Retrieve the WP Cloud Manager base URL.
*
* Checks the WPCC_MANAGER_URL constant first, then falls back to the
* wpcc_manager_url filter so the value can be supplied by the hosting
* environment without touching the database.
*
* @return string Manager base URL, or empty string if not configured.
*/
public function getManagerUrl(): string {
if ( \defined( 'WPCC_MANAGER_URL' ) ) {
return (string) \WPCC_MANAGER_URL;
}
return (string) apply_filters( 'wpcc_manager_url', '' );
}
/**
* Check whether all required credentials are configured.
*
* @return bool True if site ID and API key are set.
*/
public function isConfigured(): bool {
return $this->getSiteId() !== null
&& $this->getApiKey() !== null;
}
/**
* Update settings by merging with existing values.
*
* @param array $values Key-value pairs to update.
* @return bool True if the option was updated, false on failure.
*/
public function update( array $values ): bool {
$current = $this->all();
return (bool) update_option( self::OPTION_KEY, array_merge( $current, $values ) );
}
/**
* Remove specific keys from stored settings.
*
* Used for migrations to clean up stale keys from previous versions.
*
* @param array $keys Keys to remove.
*/
public function purge( array $keys ): void {
$current = $this->all();
foreach ( $keys as $key ) {
unset( $current[ $key ] );
}
update_option( self::OPTION_KEY, $current );
}
/**
* Retrieve all settings as an array.
*
* @return array All stored settings.
*/
public function all(): array {
return (array) get_option( self::OPTION_KEY, [] );
}
/**
* Retrieve a single setting value by key.
*
* @param string $key Setting key to retrieve.
* @return string|null Setting value or null if empty.
*/
private function get( string $key ): ?string {
$settings = $this->all();
$value = isset( $settings[ $key ] ) ? trim( (string) $settings[ $key ] ) : null;
return null !== $value && '' !== $value ? $value : null;
}
}