<?php
namespace cnb\admin\api;
// don't load directly
defined( 'ABSPATH' ) || die( '-1' );
use cnb\admin\action\CnbAction;
use cnb\admin\apikey\CnbApiKey;
use cnb\admin\button\CnbButton;
use cnb\admin\condition\CnbCondition;
use cnb\admin\domain\CnbDomain;
use cnb\admin\domain\SubscriptionStatus;
use cnb\admin\models\CnbPlan;
use cnb\admin\models\CnbUser;
use cnb\admin\models\ValidationMessageWithId;
use cnb\admin\settings\StripeBillingPortal;
use cnb\admin\settings\UrlSettings;
use cnb\coupons\CnbPromotionCode;
use cnb\cron\Cron;
use cnb\utils\CnbUtils;
use JsonSerializable;
use WP_Error;
class CnbAppRemote {
/**
* By creating a proxy method, we can easily stub this for testing
*
* It also needs to be public for the tests/stub to work, it seems?
*
* @return string Site URL with optional path appended.
*/
public function get_site_url() {
/** @noinspection PhpFullyQualifiedNameUsageInspection */
return \get_site_url();
}
/**
* Return a cleaned up version of the Site URL.
*
* Removes protocol, port and path (and lowercases it)
*
* Examples:
* - https://www.Example.org:8080/test becomes example.org
* - https://subdomaIN.eXAMple.prg:8080/test becomes subdomain.example.org
*
* @return string
*/
public function cnb_clean_site_url() {
$siteUrl = $this->get_site_url();
$url = wp_parse_url( $siteUrl, PHP_URL_HOST );
if ( $url ) {
return
preg_replace( '/^www\./', '',
trim(
strtolower( $url ) )
, 1 );
}
// Fallback behavior
// Order:
// 1: Strip everything after // (so to remove a potential protocol like http(s)://
// 2: Strip the port if found, via :1234
// 3: Strip everything after /, so that "example.org/test" becomes "example.org"
// 4: Lowercase & trim everything
// 5: Remove a potential "www." prefix
return
preg_replace( '/^www\./', '',
trim(
strtolower( preg_replace( '/\/.*/', '',
preg_replace( '/:\d+/', '',
preg_replace( '/.*\/\//', '', $siteUrl, 1 ), 1 ), 1 ) )
)
, 1 );
}
/**
* @return string usually "https://api.callnowbutton.com"
*/
public static function cnb_get_api_base() {
$cnb_options = get_option( 'cnb' );
return isset( $cnb_options['api_base'] ) ? $cnb_options['api_base'] : 'https://api.callnowbutton.com';
}
/**
* @return string usually "https://user.callnowbutton.com"
*/
public static function cnb_get_user_base() {
UrlSettings::restoreFromOptions();
/** @type UrlSettings $cnb_settings */
global $cnb_settings;
if ($cnb_settings && $cnb_settings->get_user_root()) {
return $cnb_settings->get_user_root();
}
// This needs to /only/ be the fallback
return str_replace( 'api', 'user', CnbAppRemote::cnb_get_api_base() );
}
/**
* @return string usually "https://static.callnowbutton.com"
*/
public static function cnb_get_static_base() {
UrlSettings::restoreFromOptions();
/** @type UrlSettings $cnb_settings */
global $cnb_settings;
if ($cnb_settings && $cnb_settings->get_static_root()) {
return $cnb_settings->get_static_root();
}
// This needs to /only/ be the fallback
return str_replace( 'api', 'static', CnbAppRemote::cnb_get_api_base() );
}
/**
* @return string usually "https://static.callnowbutton.com/js/client.js
*/
public static function get_client_js() {
UrlSettings::restoreFromOptions();
/** @type UrlSettings $cnb_settings */
global $cnb_settings;
if ($cnb_settings && $cnb_settings->get_js_location()) {
return $cnb_settings->get_js_location();
}
// This needs to /only/ be the fallback
return CnbAppRemote::cnb_get_static_base() . '/js/client.js';
}
/**
* @return string usually "https://static.callnowbutton.com/css/main.css"
*/
public static function get_client_css() {
UrlSettings::restoreFromOptions();
/** @type UrlSettings $cnb_settings */
global $cnb_settings;
if ($cnb_settings && $cnb_settings->get_css_location()) {
return $cnb_settings->get_css_location();
}
// This needs to /only/ be the fallback
return CnbAppRemote::cnb_get_static_base() . '/css/main.css';
}
/**
* @return int|false false if not found, otherwise the current cache key
*/
public static function cnb__get_transient_base() {
$val = get_transient( self::cnb_get_api_base() );
if ( $val ) {
return (int) $val;
}
return false;
}
/**
* Set the cache key.
*
* @param string|int|null $time Should not be added, but can be used to force a base (mostly used for testing).
*/
public static function cnb_incr_transient_base( $time = null ) {
/** @noinspection PhpTernaryExpressionCanBeReducedToShortVersionInspection */
$value = $time ? $time : time();
set_transient( self::cnb_get_api_base(), $value );
}
public static function cnb_get_transient_base() {
return self::cnb__get_transient_base() . self::cnb_get_api_base();
}
private static function cnb_remote_get_args( $authenticated = true ) {
global $cnb_api_key;
$cnb_options = get_option( 'cnb' );
$api_key = isset( $cnb_options['api_key'] ) ? $cnb_options['api_key'] : false;
// Special case, we also need to be able to temporarily overwrite the API key
// This is done by functions by setting the special global "$cnb_api_key"
if ( isset( $cnb_api_key ) && ! empty( $cnb_api_key ) ) {
$api_key = $cnb_api_key;
}
$headers = array(
'Content-Type' => 'application/json',
'X-CNB-Plugin-Version' => CNB_VERSION,
);
if ( $authenticated ) {
if ( ! $api_key ) {
return new WP_Error( 'CNB_API_NOT_SETUP_YET' );
}
$header_name = 'X-CNB-Api-Key';
$header_value = $api_key;
$headers[ $header_name ] = $header_value;
}
return array(
'headers' => $headers,
);
}
private static function cnb_remote_handle_response( $response ) {
global $wp_version;
if ( $response instanceof WP_Error ) {
if ( version_compare( $wp_version, '5.6.0', '>=' ) ) {
$error = new WP_Error( 'CNB_UNKNOWN_REMOTE_ERROR', 'There was an issue communicating with the CallNowButton API. Please see the detailed error message from the response below.' );
$error->merge_from( $response );
return $error;
}
return $response;
}
$response_code = wp_remote_retrieve_response_code( $response );
if ( $response_code == 403 ) {
$response_message = wp_remote_retrieve_response_message( $response );
if ( $response_message == 'Forbidden' && str_contains( wp_remote_retrieve_body ( $response ), 'Access Denied' ) ) {
return new WP_Error( 'CNB_API_KEY_INVALID', $response_message );
}
}
if ( $response_code == 404 ) {
return new WP_Error( 'CNB_ENTITY_NOT_FOUND', wp_remote_retrieve_response_message( $response ) );
}
// 402 == Payment required
if ( $response_code == 402 ) {
$body = json_decode( $response['body'] );
return new WP_Error( 'CNB_PAYMENT_REQUIRED', wp_remote_retrieve_response_message( $response ), $body->message );
}
if ( $response_code != 200 ) {
return new WP_Error( 'CNB_ERROR', wp_remote_retrieve_response_message( $response ), wp_remote_retrieve_body ( $response ) );
}
return json_decode( wp_remote_retrieve_body ( $response ) );
}
/**
* DELETE, PATCH support.
*
* Includes Trace support
*
* @param $url string
* @param $parsed_args array
*
* @return array|WP_Error
*/
private static function cnb_wp_request( $url, $parsed_args ) {
$http = _wp_http_get_object();
$context = __METHOD__ . '<' . $parsed_args['method'] . '>';
$timer = new RemoteTrace( $url, $context );
$response = $http->request( $url, $parsed_args );
$timer->end();
return $response;
}
/**
* DELETE is missing from WordPress Core.
*
* This is inspired by https://developer.wordpress.org/reference/functions/wp_remote_post/
*
* @param $url string
* @param $args array
*
* @return array|WP_Error
*/
private static function wp_remote_delete( $url, $args = array() ) {
$defaults = array( 'method' => 'DELETE' );
$parsed_args = wp_parse_args( $args, $defaults );
return self::cnb_wp_request( $url, $parsed_args );
}
/**
* PATCH is missing from WordPress Core.
*
* This is inspired by https://developer.wordpress.org/reference/functions/wp_remote_post/
*
* @param $url string
* @param $args array
*
* @return array|WP_Error
*/
private static function wp_remote_patch( $url, $args = array() ) {
$defaults = array( 'method' => 'PATCH' );
$parsed_args = wp_parse_args( $args, $defaults );
return self::cnb_wp_request( $url, $parsed_args );
}
/**
* @param $rest_endpoint string
* @param $body array|JsonSerializable will be JSON encoded, can be `array` (or class with `JsonSerializable`?)
*
* @return mixed|WP_Error
*/
private static function cnb_remote_patch( $rest_endpoint, $body ) {
$args = self::cnb_remote_get_args();
if ( $args instanceof WP_Error ) {
return $args;
}
if ( $body != null ) {
$args['body'] = wp_json_encode( $body );
}
$url = self::cnb_get_api_base() . $rest_endpoint;
$response = self::wp_remote_patch( $url, $args );
self::cnb_incr_transient_base();
do_action( 'cnb_after_button_changed' );
return self::cnb_remote_handle_response( $response );
}
private static function cnb_remote_delete( $rest_endpoint ) {
$args = self::cnb_remote_get_args();
if ( $args instanceof WP_Error ) {
return $args;
}
$url = self::cnb_get_api_base() . $rest_endpoint;
$response = self::wp_remote_delete( $url, $args );
self::cnb_incr_transient_base();
do_action( 'cnb_after_button_changed' );
return self::cnb_remote_handle_response( $response );
}
public static function cnb_remote_post( $rest_endpoint, $body = null, $authenticated = true ) {
$args = self::cnb_remote_get_args( $authenticated );
if ( $args instanceof WP_Error ) {
return $args;
}
if ( $body != null ) {
$args['body'] = wp_json_encode( $body );
}
$url = self::cnb_get_api_base() . $rest_endpoint;
$timer = new RemoteTrace( $url, __METHOD__ );
$response = wp_remote_post( $url, $args );
self::cnb_incr_transient_base();
do_action( 'cnb_after_button_changed' );
$timer->end();
return self::cnb_remote_handle_response( $response );
}
public static function cnb_remote_get( $rest_endpoint, $authenticated = true ) {
$cnb_remote = new CnbAppRemote();
$url = self::cnb_get_api_base() . $rest_endpoint;
return $cnb_remote->cnb_get($url, $authenticated);
}
public function cnb_get( $rest_endpoint, $authenticated = true ) {
$cnb_get_cache = new CnbGet();
$args = self::cnb_remote_get_args( $authenticated );
if ( $args instanceof WP_Error ) {
return $args;
}
$url = $rest_endpoint;
$timer = new RemoteTrace( $url, __METHOD__ );
$response = $cnb_get_cache->get( $url, $args );
$timer->setCacheHit( $cnb_get_cache->isLastCallCached() );
$timer->end();
return self::cnb_remote_handle_response( $response );
}
/**
* In case the cloud is enabled, retrieve all the needed information from the remote server.
*
* @return void
*/
public function init() {
$cnb_options = get_option( 'cnb' );
$cnb_utils = new CnbUtils();
if ( ! $cnb_utils->isCloudActive( $cnb_options ) ) {
return;
}
$this->get_wp_info();
}
/***
* Sets all WordPress needed information globally
*
* @return void
*
* @global CnbUser|WP_Error|null $cnb_user the User corresponding to the current API key
* @global CnbDomain|null $cnb_domain the Domain corresponding to the current clean site URL
* @global CnbButton[]|null $cnb_buttons the Buttons corresponding to the current Domain
* @global CnbDomain[]|null $cnb_domains the Domains corresponding to the current User
* @global CnbPromotionCode|null $cnb_coupon the Coupon currently active
* @global CnbPlan[]|null $cnb_plans the Plans currently active
* @global ValidationMessageWithId[]|null $cnb_validation_messages all Validation messages for this account
* @global SubscriptionStatus|null $cnb_subscription_data Subscription status for the current domain
*/
public function get_wp_info() {
global
$cnb_user,
$cnb_domain,
$cnb_buttons,
$cnb_domains,
$cnb_coupon,
$cnb_plans,
$cnb_validation_messages,
$cnb_subscription_data,
$cnb_settings;
$rest_endpoint = '/v1/wp/all/' . $this->cnb_clean_site_url();
$data = self::cnb_remote_get( $rest_endpoint );
if ( $data === null || is_wp_error( $data ) ) {
$cnb_user = CnbUser::fromObject( $data );
return;
}
$cnb_user = CnbUser::fromObject( $data->user );
$cnb_domain = CnbDomain::fromObject( $data->currentDomain );
$cnb_domains = CnbDomain::fromObjects( $data->domains );
$cnb_buttons = CnbButton::fromObjects( $data->buttons );
$cnb_coupon = CnbPromotionCode::fromObject( $data->coupon );
$cnb_plans = CnbPlan::fromObjects( $data->plans );
$cnb_validation_messages = ValidationMessageWithId::fromObjects( $data->validationMessages );
$cnb_settings = UrlSettings::fromObject($data->settings);
// This might not be available in each API call, depending on environment settings
if ( isset( $data->subscriptionStatusData ) ) {
$cnb_subscription_data = SubscriptionStatus::from_object( $data->subscriptionStatusData );
$this->save_subscription_data($cnb_subscription_data);
}
// This updates the internal options, so that the new settings (if any) can be rendered on the front-end
if ( $cnb_settings ) {
$cnb_settings->register_settings();
}
}
/**
* Stores the SubscriptionStatus to a local (transient) store, so that #get_subscription_data
* can retrieve it.
*
* @param $cnb_subscription_data SubscriptionStatus
*
* @return void
*/
private function save_subscription_data($cnb_subscription_data) {
if ($cnb_subscription_data && !is_wp_error($cnb_subscription_data)) {
$hook_name = (new Cron())->get_hook_name();
set_transient( $hook_name, $cnb_subscription_data, DAY_IN_SECONDS );
}
}
/**
* Get the SubscriptionStatus without a call to the remote API, instead relying on the
* local transient store.
*
* @return bool|SubscriptionStatus
*/
public function get_subscription_data() {
$hook_name = (new Cron())->get_hook_name();
return get_transient($hook_name);
}
public function get_subscription_status( $domainId ) {
$rest_endpoint = '/v1/subscription/domain/' . $domainId;
$data = self::cnb_remote_get( $rest_endpoint );
return SubscriptionStatus::from_object( $data );
}
/**
* @param $id string
*
* @return CnbButton|WP_Error
*/
public function get_button( $id ) {
global $cnb_buttons;
// This usually means the API was to slow return anything
if ( empty($cnb_buttons) ) {
return new WP_Error( 'WP_RETRIEVE_ERROR', 'Could not retrieve buttons for ID <code>' . esc_html( $id ) . '</code>. Please refresh the page.' );
}
foreach ( $cnb_buttons as $button ) {
if ( $button->id === $id ) {
return $button;
}
}
return new WP_Error( 'WP_RETRIEVE_ERROR', 'Could not retrieve button with ID <code>' . esc_html( $id ) . '</code>. Please refresh the page.' );
}
/**
* @param $id string
*
* @return CnbAction|WP_Error
*/
public function get_action( $id ) {
global $cnb_buttons;
/**
* @type $button CnbButton
*/
foreach ( $cnb_buttons as $button ) {
foreach ( $button->actions as $action ) {
if ( $action->id === $id ) {
return $action;
}
}
}
return null;
}
/**
* @param $id
*
* @return CnbDomain|WP_Error
*/
public function get_domain( $id ) {
global $cnb_domains;
foreach ( $cnb_domains as $domain ) {
if ( $domain->id === $id ) {
return $domain;
}
}
return null;
}
/**
* @param $id string
*
* @return CnbButton|null
*/
public function get_button_for_action( $id ) {
global $cnb_buttons;
/**
* @type $button CnbButton
*/
foreach ( $cnb_buttons as $button ) {
foreach ( $button->actions as $action ) {
if ( $action->id === $id ) {
return $button;
}
}
}
return null;
}
/**
* @param $id string
*
* @return CnbButton|null
*/
public function get_button_for_condition( $id ) {
global $cnb_buttons;
/**
* @type $button CnbButton
*/
foreach ( $cnb_buttons as $button ) {
foreach ( $button->conditions as $condition ) {
if ( $condition->id === $id ) {
return $button;
}
}
}
return null;
}
/**
* Returns the User corresponding to the current API key
*
* @return CnbUser|WP_Error
*
* @global CnbUser|WP_Error|null $cnb_user the User corresponding to the current API key
*
*/
public function get_user() {
global $cnb_user;
$rest_endpoint = '/v1/user';
$user = CnbUser::fromObject( self::cnb_remote_get( $rest_endpoint ) );
// Only set the global if the User is successfully retrieved
if ( $user instanceof CnbUser ) {
$cnb_user = $user;
}
return $user;
}
/**
* @param $user CnbUser
*
* @return CnbUser|WP_Error
*/
public function update_user( $user ) {
$rest_endpoint = '/v1/user';
return CnbUser::fromObject( self::cnb_remote_patch( $rest_endpoint, $user ) );
}
/**
* Opt-in to Marketing e-mails
*
* @return void
*/
public function enable_email_opt_in() {
$rest_endpoint = '/v1/user/emailPreference';
self::cnb_remote_post( $rest_endpoint );
}
/**
* Remove the opt-in (basically, opt-out) from the user, preventing Marketing e-mails from being sent
*
* @return void
*/
public function disable_email_opt_in() {
$rest_endpoint = '/v1/user/emailPreference';
self::cnb_remote_delete( $rest_endpoint );
}
/**
* This returns the domain matching the WordPress domain
*
* @return CnbDomain|WP_Error
*
* @global CnbDomain|null $cnb_domain the domain matching the WordPress domain
*
*/
public function get_wp_domain() {
global $cnb_domain;
$cnbAppRemote = new CnbAppRemote();
$rest_endpoint = '/v1/domain/byName/' . $cnbAppRemote->cnb_clean_site_url();
$domain = CnbDomain::fromObject( self::cnb_remote_get( $rest_endpoint ) );
// Only set the global if the CnbDomain is successfully retrieved
if ( $domain instanceof CnbDomain ) {
$cnb_domain = $domain;
}
return $domain;
}
/**
* This does not (yet) actually return CnbButton, but a stdclass that resembles it.
*
* @return CnbButton[]|WP_Error
*/
public function get_buttons() {
$rest_endpoint = '/v1/button';
return CnbButton::fromObjects( self::cnb_remote_get( $rest_endpoint ) );
}
/**
* @return CnbAction[]|WP_Error
*/
public function get_actions() {
$rest_endpoint = '/v1/action';
return CnbAction::fromObjects( self::cnb_remote_get( $rest_endpoint ) );
}
/**
* @return CnbCondition[]|WP_Error
*/
public function get_conditions() {
$rest_endpoint = '/v1/condition';
return CnbCondition::fromObjects( self::cnb_remote_get( $rest_endpoint ) );
}
/**
* @param $id string
*
* @return CnbCondition|WP_Error
*/
public function get_condition( $id ) {
$rest_endpoint = '/v1/condition/' . $id;
return CnbCondition::fromObject( self::cnb_remote_get( $rest_endpoint ) );
}
/**
* @param $ott string a one-time token to retrieve an API key
*
* @return CnbApiKey|WP_Error
*/
public function get_apikey_via_ott( $ott ) {
$rest_endpoint = '/v1/apikey/ott/' . $ott;
return CnbApiKey::fromObject( self::cnb_remote_get( $rest_endpoint, false ) );
}
/**
* @return CnbApiKey[]|WP_Error
*/
public function get_apikeys() {
$rest_endpoint = '/v1/apikey';
return CnbApiKey::fromObjects( self::cnb_remote_get( $rest_endpoint ) );
}
/**
* @param $button CnbButton
*
* @return CnbButton|WP_Error
*/
public function update_button( $button ) {
// Find the ID in the options
if ( ! $button->id ) {
return new WP_Error( 'CNB_BUTTON_ID_MISSING', 'buttonId expected, but not found' );
}
$rest_endpoint = '/v1/button/' . $button->id;
return CnbButton::fromObject( self::cnb_remote_patch( $rest_endpoint, $button ) );
}
/**
* @param $domain CnbDomain
*
* @return CnbDomain|WP_Error
*/
public function update_domain( $domain ) {
// Find the ID in the options
if ( ! $domain->id ) {
return new WP_Error( 'CNB_DOMAIN_ID_MISSING', 'domainId expected, but not found' );
}
$rest_endpoint = '/v1/domain/' . $domain->id;
return CnbDomain::fromObject( self::cnb_remote_patch( $rest_endpoint, $domain ) );
}
/**
* @param $button CnbButton
*
* @return CnbButton|WP_Error
*/
public function delete_button( $button ) {
if ( ! $button->id ) {
return new WP_Error( 'CNB_BUTTON_ID_MISSING', 'buttonId expected, but not found' );
}
$rest_endpoint = '/v1/button/' . $button->id;
$delete_result = CnbDeleteResult::fromObject( self::cnb_remote_delete( $rest_endpoint ) );
if ( $delete_result->is_success() ) {
return CnbButton::fromObject( $delete_result->object );
}
return $delete_result->get_error();
}
/**
* @param $domain CnbDomain
*
* @return CnbDomain|WP_Error
*/
public function delete_domain( $domain ) {
if ( ! $domain->id ) {
return new WP_Error( 'CNB_DOMAIN_ID_MISSING', 'domainId expected, but not found' );
}
$rest_endpoint = '/v1/domain/' . $domain->id;
$delete_result = CnbDeleteResult::fromObject( self::cnb_remote_delete( $rest_endpoint ) );
if ( $delete_result->is_success() ) {
return CnbDomain::fromObject( $delete_result->object );
}
return $delete_result->get_error();
}
/**
* @param $condition CnbCondition
*
* @return CnbCondition|WP_Error
*/
public function delete_condition( $condition ) {
// Find the ID in the options
if ( ! $condition->id ) {
return new WP_Error( 'CNB_CONDITION_ID_MISSING', 'conditionId expected, but not found' );
}
$rest_endpoint = '/v1/condition/' . $condition->id;
$delete_result = CnbDeleteResult::fromObject( self::cnb_remote_delete( $rest_endpoint ) );
if ( $delete_result->is_success() ) {
return CnbCondition::fromObject( $delete_result->object );
}
return $delete_result->get_error();
}
/**
* @param $action CnbAction
*
* @return CnbAction|WP_Error
*/
public function delete_action( $action ) {
// Find the ID in the options
if ( ! $action->id ) {
return new WP_Error( 'CNB_ACTION_ID_MISSING', 'actionId expected, but not found' );
}
$rest_endpoint = '/v1/action/' . $action->id;
$delete_result = CnbDeleteResult::fromObject( self::cnb_remote_delete( $rest_endpoint ) );
if ( $delete_result->is_success() ) {
return CnbAction::fromObject( $delete_result->object );
}
return $delete_result->get_error();
}
/**
* @param $apikey CnbApiKey
*
* @return CnbApiKey|WP_Error
*/
public function delete_apikey( $apikey ) {
// Find the ID in the options
$apikeyId = $apikey->id;
if ( ! $apikeyId ) {
return new WP_Error( 'CNB_APIKEY_ID_MISSING', 'apikeyId expected, but not found' );
}
$rest_endpoint = '/v1/apikey/' . $apikeyId;
$delete_result = CnbDeleteResult::fromObject( self::cnb_remote_delete( $rest_endpoint ) );
if ( $delete_result->is_success() ) {
return CnbApiKey::fromObject( $delete_result->object );
}
return $delete_result->get_error();
}
/**
* @param $action CnbAction
*
* @return CnbAction|WP_Error
*/
public function update_action( $action ) {
// Find the action ID in the options
if ( ! $action->id ) {
return new WP_Error( 'CNB_ACTION_ID_MISSING', 'actionId expected, but not found' );
}
$rest_endpoint = '/v1/action/' . $action->id;
return CnbAction::fromObject( self::cnb_remote_patch( $rest_endpoint, $action ) );
}
/**
* @param $domain CnbDomain
*
* @return CnbDomain|WP_Error
*/
public function create_domain( $domain ) {
if ( $domain->id ) {
return new WP_Error( 'CNB_DOMAIN_ID_FOUND', 'no domainId expected, but one was given' );
}
$rest_endpoint = '/v1/domain';
return CnbDomain::fromObject( self::cnb_remote_post( $rest_endpoint, $domain ) );
}
/**
* @param $button CnbButton Single Button object
*
* @return CnbButton|WP_Error
*/
public function create_button( $button ) {
if ( $button->id ) {
return new WP_Error( 'CNB_BUTTON_ID_FOUND', 'no buttonId expected, but one was given' );
}
$rest_endpoint = '/v1/button';
return CnbButton::fromObject( self::cnb_remote_post( $rest_endpoint, $button ) );
}
/**
* @param $action CnbAction
*
* @return CnbAction|WP_Error
*/
public function create_action( $action ) {
if ( $action->id ) {
return new WP_Error( 'CNB_ACTION_ID_FOUND', 'no actionId expected, but one was given' );
}
$rest_endpoint = '/v1/action';
return CnbAction::fromObject( self::cnb_remote_post( $rest_endpoint, $action ) );
}
/**
* @param $condition CnbCondition
*
* @return CnbCondition|WP_Error
*/
public function create_condition( $condition ) {
if ( $condition->id ) {
return new WP_Error( 'CNB_CONDITION_ID_FOUND', 'no conditionId expected, but one was given' );
}
$rest_endpoint = '/v1/condition';
return CnbCondition::fromObject( self::cnb_remote_post( $rest_endpoint, $condition ) );
}
/**
* @param $condition CnbCondition
*
* @return CnbCondition|WP_Error
*/
public function update_condition( $condition ) {
if ( ! $condition->id ) {
return new WP_Error( 'CNB_CONDITION_ID_MISSING', 'conditionId expected, but not found' );
}
$rest_endpoint = '/v1/condition/' . $condition->id;
return CnbCondition::fromObject( self::cnb_remote_patch( $rest_endpoint, $condition ) );
}
/**
* @param $apikey CnbApiKey
*
* @return CnbApiKey|WP_Error
*/
public function create_apikey( $apikey ) {
$rest_endpoint = '/v1/apikey';
return CnbApiKey::fromObject( self::cnb_remote_post( $rest_endpoint, $apikey ) );
}
/**
* @return StripeBillingPortal
*/
public function create_billing_portal() {
$return_link =
add_query_arg(
array(
'page' => 'call-now-button-settings',
'tab' => 'account_options',
),
admin_url( 'admin.php' ) );
$body = array(
'returnUrl' => $return_link
);
$rest_endpoint = '/v1/stripe/createBillingPortal';
return StripeBillingPortal::fromObject( self::cnb_remote_post( $rest_endpoint, $body ) );
}
/**
* Data model:
* {
* "email": "jasper+wp-signup-test-02@studiostacks.com",
* "domain": "http://www.button.local:8000/",
* "adminUrl": "http://www.button.local:8000/wp-admin",
* "version": 2,
* }
*
* Version 2 is the admin-post.php version
*
* @param $admin_email string Email address of the user signing up
* @param $admin_url string URL (including the /wp-admin portion)
*/
public function create_email_activation( $admin_email, $admin_url ) {
$cnbAppRemote = new CnbAppRemote();
$body = array(
'email' => $admin_email,
'domain' => $cnbAppRemote->cnb_clean_site_url(),
'adminUrl' => $admin_url,
'version' => 2,
);
$rest_endpoint = '/v1/user/wp';
return self::cnb_remote_post( $rest_endpoint, $body, false );
}
/**
* @param $storage_type string GCS or R2
*
* @return mixed|WP_Error
*/
public function set_user_storage_type ( $storage_type ) {
$rest_endpoint = '/v1/user/settings/storage/' . $storage_type;
$body = '';
return self::cnb_remote_post( $rest_endpoint, $body );
}
}