Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
31 / 31
100.00% covered (success)
100.00%
7 / 7
CRAP
100.00% covered (success)
100.00%
1 / 1
SiteCapabilities
100.00% covered (success)
100.00%
31 / 31
100.00% covered (success)
100.00%
7 / 7
14
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 update
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 set
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 all
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 exists
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fetch
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
5
1<?php
2
3namespace NewfoldLabs\WP\Module\Data;
4
5use NewfoldLabs\WP\Module\Data\API\Capabilities;
6use NewfoldLabs\WP\Module\Data\Helpers\Transient;
7
8/**
9 * Class SiteCapabilities
10 *
11 * Class that handles fetching, caching, and checking of site capabilities.
12 *
13 * @package NewfoldLabs\WP\Module\Data
14 */
15class SiteCapabilities {
16
17    /**
18     * Implementation of transient functionality which uses the WordPress options table when an object cache is present.
19     *
20     * @var Transient
21     */
22    protected $transient;
23
24    /**
25     * Constructor.
26     *
27     * @param ?Transient $transient Inject instance of Transient class.
28     */
29    public function __construct( ?Transient $transient = null ) {
30        $this->transient = $transient ?? new Transient();
31    }
32
33    /**
34     * Get the value of a capability.
35     *
36     * @used-by \NewfoldLabs\WP\Module\AI\SiteGen\SiteGen::check_capabilities()
37     * @used-by \NewfoldLabs\WP\Module\AI\Utils\AISearchUtil::check_capabilities()
38     * @used-by \NewfoldLabs\WP\Module\AI\Utils\AISearchUtil::check_help_capability()
39     * @used-by \NewfoldLabs\WP\Module\ECommerce\ECommerce::__construct()
40     * @used-by \NewfoldLabs\WP\Module\HelpCenter\CapabilityController::get_capability()
41     * @used-by \NewfoldLabs\WP\Module\Onboarding\Data\Config::get_site_capability()
42     *
43     * @param string $capability Capability name.
44     */
45    public function get( string $capability ): bool {
46        return $this->exists( $capability ) && $this->all()[ $capability ];
47    }
48
49    /**
50     * Merge a new list of capabilities into the existing list and save.
51     *
52     * @used-by Capabilities::update()
53     *
54     * @param array<string, bool> $capabilities
55     *
56     * @return bool True if the value was changed, false otherwise.
57     */
58    public function update( array $capabilities ): bool {
59        $updated_capabilities = array_merge( $this->all( false ), $capabilities );
60        return $this->set( $updated_capabilities );
61    }
62
63    /**
64     * Save a list of capabilities, overwriting the existing list.
65     *
66     * @used-by self::fetch()
67     * @used-by Capabilities::update()
68     *
69     * @param array<string, bool> $capabilities
70     *
71     * @return bool True if the value was set, false otherwise.
72     */
73    public function set( array $capabilities ): bool {
74        return $this->transient->set( 'nfd_site_capabilities', $capabilities, 4 * constant( 'HOUR_IN_SECONDS' ) );
75    }
76
77    /**
78     * Get all capabilities.
79     *
80     * @param bool $fetch_when_absent Make a request to Hiive to fetch capabilities when not present in cache (default: `true`).
81     *
82     * @return array<string, bool> List of capabilities and if they are enabled or not.
83     */
84    public function all( bool $fetch_when_absent = true ): array {
85        $capabilities = $this->transient->get( 'nfd_site_capabilities' );
86
87        if ( is_array( $capabilities ) ) {
88            return $capabilities;
89        }
90
91        if ( $fetch_when_absent ) {
92            $capabilities = $this->fetch();
93            $this->set( $capabilities );
94            return $capabilities;
95        }
96
97        return array();
98    }
99
100    /**
101     * Check if a capability exists.
102     *
103     * @param string $capability Capability name.
104     */
105    protected function exists( string $capability ): bool {
106        return array_key_exists( $capability, $this->all() );
107    }
108
109    /**
110     * Fetch all capabilities from Hiive.
111     *
112     * @return array<string, bool>
113     */
114    protected function fetch(): array {
115        $capabilities = array();
116
117        $response = wp_remote_get(
118            constant( 'NFD_HIIVE_URL' ) . '/sites/v1/capabilities',
119            array(
120                'headers' => array(
121                    'Content-Type'  => 'application/json',
122                    'Accept'        => 'application/json',
123                    'Authorization' => 'Bearer ' . HiiveConnection::get_auth_token(),
124                ),
125            )
126        );
127
128        if ( wp_remote_retrieve_response_code( $response ) === 200 && ! is_wp_error( $response ) ) {
129            $body = wp_remote_retrieve_body( $response );
130            $data = json_decode( $body, true );
131            if ( $data && is_array( $data ) ) {
132                $capabilities = $data;
133            }
134        }
135
136        return $capabilities;
137    }
138}