Skip to content

Commit

Permalink
Merge pull request #99 from newfold-labs/Add/capabilities-tests
Browse files Browse the repository at this point in the history
Update `SiteCapabilities` to use `Transient` class
  • Loading branch information
BrianHenryIE authored Sep 11, 2024
2 parents 69d8f4e + 1c11134 commit 89f0957
Show file tree
Hide file tree
Showing 6 changed files with 560 additions and 48 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"package": {
"name": "bluehost/bluehost-wordpress-plugin",
"type": "wordpress-plugin",
"version": "3.1.0",
"version": "3.14.8",
"dist": {
"url": "https://github.com/bluehost/bluehost-wordpress-plugin/releases/latest/download/bluehost-wordpress-plugin.zip",
"type": "zip"
Expand Down Expand Up @@ -105,6 +105,7 @@
},
"require": {
"ext-json": "*",
"newfold-labs/wp-module-context": "^1.0",
"newfold-labs/wp-module-loader": "^1.0.10",
"wp-forge/helpers": "^2.0",
"wp-forge/wp-query-builder": "^1.0.4",
Expand Down
58 changes: 56 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

76 changes: 52 additions & 24 deletions includes/Helpers/Transient.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,37 @@ class Transient {
*
* If the site has an object-cache.php drop-in, then we can't reliably
* use the transients API. We'll try to fall back to the options API.
*
* @return boolean
*/
public static function should_use_transients() {
protected static function should_use_transients(): bool {
require_once constant( 'ABSPATH' ) . '/wp-admin/includes/plugin.php';
return ! array_key_exists( 'object-cache.php', get_dropins() );
return ! array_key_exists( 'object-cache.php', get_dropins() )
|| 'atomic' === \NewfoldLabs\WP\Context\getContext( 'platform' ); // Bluehost Cloud.
}

/**
* Wrapper for get_transient() with Options API fallback
*
* @see \get_transient()
* @see \get_option()
* @see \delete_option()
*
* @param string $key The key of the transient to retrieve
* @return mixed The value of the transient
*/
public static function get( $key ) {
public static function get( string $key ) {
if ( self::should_use_transients() ) {
return get_transient( $key );
return \get_transient( $key );
}

$data = get_option( $key );
if ( ! empty( $data ) && isset( $data['expires'] ) ) {
if ( $data['expires'] > time() ) {
/**
* @var array{value:mixed, expires_at:int} $data The saved value and the Unix time it expires at.
*/
$data = \get_option( $key );
if ( is_array( $data ) && isset( $data['expires_at'], $data['value'] ) ) {
if ( $data['expires_at'] > time() ) {
return $data['value'];
} else {
delete_option( $key );
\delete_option( $key );
}
}

Expand All @@ -45,35 +51,57 @@ public static function get( $key ) {
/**
* Wrapper for set_transient() with Options API fallback
*
* @param string $key Key to use for storing the transient
* @param mixed $value Value to be saved
* @param integer $expires Optional expiration time in seconds from now. Default is 1 hour
* @return boolean Whether the value was saved
* @see \set_transient()
* @see \update_option()
*
* @param string $key Key to use for storing the transient
* @param mixed $value Value to be saved
* @param integer $expires_in Optional expiration time in seconds from now. Default is 1 hour
*
* @return bool Whether the value was saved
*/
public static function set( $key, $value, $expires = null ) {
$expiration = ( $expires ) ? $expires : 60 * MINUTE_IN_SECONDS;
public static function set( string $key, $value, int $expires_in = 3600 ): bool {
if ( self::should_use_transients() ) {
return set_transient( $key, $value, $expiration );
return \set_transient( $key, $value, $expires_in );
}

$data = array(
'value' => $value,
'expires' => $expiration + time(),
'value' => $value,
'expires_at' => $expires_in + time(),
);
return update_option( $key, $data, false );
return \update_option( $key, $data, false );
}

/**
* Wrapper for delete_transient() with Options API fallback
*
* @see \delete_transient()
* @see \delete_option()
*
* @param string $key The key of the transient/option to delete
* @return boolean Whether the value was deleted
* @return bool Whether the value was deleted
*/
public static function delete( $key ) {
public static function delete( $key ): bool {
if ( self::should_use_transients() ) {
return delete_transient( $key );
return \delete_transient( $key );
}

return delete_option( $key );
return \delete_option( $key );
}

/**
* Make the static functions callable as instance methods.
*
* @param string $name The function name being called.
* @param array $arguments The arguments passed to that function.
*
* @return mixed
* @throws \BadMethodCallException If the method does not exist.
*/
public function __call( $name, $arguments ) {
if ( ! method_exists( __CLASS__, $name ) ) {
throw new \BadMethodCallException( "Method $name does not exist" );
}
return self::$name( ...$arguments );
}
}
63 changes: 42 additions & 21 deletions includes/SiteCapabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace NewfoldLabs\WP\Module\Data;

use NewfoldLabs\WP\Module\Data\Helpers\Transient;

/**
* Class SiteCapabilities
*
Expand All @@ -12,52 +14,71 @@
class SiteCapabilities {

/**
* Get all capabilities.
* Implementation of transient functionality which uses the WordPress options table when an object cache is present.
*
* @return array
* @var Transient
*/
public function all() {
$capabilities = get_transient( 'nfd_site_capabilities' );
if ( false === $capabilities ) {
$capabilities = $this->fetch();
set_transient( 'nfd_site_capabilities', $capabilities, 4 * HOUR_IN_SECONDS );
}
protected $transient;

return $capabilities;
/**
* Constructor.
*
* @param ?Transient $transient Inject instance of Transient class.
*/
public function __construct( ?Transient $transient = null ) {
$this->transient = $transient ?? new Transient();
}

/**
* Check if a capability exists.
* Get the value of a capability.
*
* @used-by \NewfoldLabs\WP\Module\AI\SiteGen\SiteGen::check_capabilities()
* @used-by \NewfoldLabs\WP\Module\AI\Utils\AISearchUtil::check_capabilities()
* @used-by \NewfoldLabs\WP\Module\AI\Utils\AISearchUtil::check_help_capability()
* @used-by \NewfoldLabs\WP\Module\ECommerce\ECommerce::__construct()
* @used-by \NewfoldLabs\WP\Module\HelpCenter\CapabilityController::get_capability()
* @used-by \NewfoldLabs\WP\Module\Onboarding\Data\Config::get_site_capability()
*
* @param string $capability Capability name.
*/
public function get( string $capability ): bool {
return $this->exists( $capability ) && $this->all()[ $capability ];
}

/**
* Get all capabilities.
*
* @return bool
* @used-by \NewfoldLabs\WP\Module\Runtime\Runtime::prepareRuntime()
*/
public function exists( $capability ) {
return array_key_exists( $capability, $this->all() );
public function all(): array {
$capabilities = $this->transient->get( 'nfd_site_capabilities' );
if ( false === $capabilities ) {
$capabilities = $this->fetch();
$this->transient->set( 'nfd_site_capabilities', $capabilities, 4 * constant( 'HOUR_IN_SECONDS' ) );
}

return $capabilities;
}

/**
* Get the value of a capability.
* Check if a capability exists.
*
* @param string $capability Capability name.
*
* @return bool
*/
public function get( $capability ) {
return $this->exists( $capability ) && $this->all()[ $capability ];
protected function exists( string $capability ): bool {
return array_key_exists( $capability, $this->all() );
}

/**
* Fetch all capabilities from Hiive.
*
* @return array
* @return array<string, bool>
*/
public function fetch() {
protected function fetch(): array {
$capabilities = array();

$response = wp_remote_get(
NFD_HIIVE_URL . '/sites/v1/capabilities',
constant( 'NFD_HIIVE_URL' ) . '/sites/v1/capabilities',
array(
'headers' => array(
'Content-Type' => 'application/json',
Expand Down
Loading

0 comments on commit 89f0957

Please sign in to comment.