PluginProbe
AffiliateX – Amazon Affiliate Plugin, Product Boxes, Comparison Tables & Affiliate Link Tracking / trunk
AffiliateX – Amazon Affiliate Plugin, Product Boxes, Comparison Tables & Affiliate Link Tracking vtrunk
2.3.9 2.3.8 2.3.7 2.3.6 2.3.5 2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.0 2.2.1 2.1.0 2.0.8 2.0.7 2.0.6 2.0.5 2.0.4 2.0.3 2.0.2 2.0.1 2.0 1.2.9 1.2.9.1 1.2.9.2 All 87 releases
affiliatex / includes / modules / PricingAPI.php

PricingAPI.php in AffiliateX – Amazon Affiliate Plugin, Product Boxes, Comparison Tables & Affiliate Link Tracking trunk, at includes/modules/PricingAPI.php

161 lines 3.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace AffiliateX\Modules;
4
5 defined( 'ABSPATH' ) || exit;
6
7 /**
8 * Upgrade / Pricing REST API — serves live Freemius plan + pricing data.
9 *
10 * @package AffiliateX
11 */
12 class PricingAPI {
13 use \AffiliateX\Helpers\ResponseHelper;
14
15 const CACHE_KEY = 'affiliatex_upgrade_pricing';
16 const CACHE_TTL = HOUR_IN_SECONDS;
17
18 public function register_routes(): void {
19 register_rest_route(
20 'affiliatex/v1/upgrade',
21 '/pricing',
22 array(
23 'methods' => 'GET',
24 'callback' => array( $this, 'get_pricing' ),
25 'permission_callback' => function () {
26 return current_user_can( 'manage_options' );
27 },
28 )
29 );
30 }
31
32 public function get_pricing(): void {
33 $cached = get_transient( self::CACHE_KEY );
34 if ( false !== $cached ) {
35 $this->send_json_plain_success( $cached );
36 return;
37 }
38
39 $data = $this->fetch_pricing();
40 if ( empty( $data['tiers'] ) ) {
41 $this->send_json_plain_error( array( 'message' => esc_html__( 'Unable to load pricing right now.', 'affiliatex' ) ) );
42 return;
43 }
44
45 set_transient( self::CACHE_KEY, $data, self::CACHE_TTL );
46 $this->send_json_plain_success( $data );
47 }
48
49 /**
50 * Fetch and normalise plan + pricing data from the Freemius plugin scope.
51 *
52 * @return array
53 */
54 private function fetch_pricing(): array {
55 $result = affiliatex_fs()->get_api_plugin_scope()->get( 'pricing.json?is_enriched=true' );
56
57 $plans = ( is_object( $result ) && isset( $result->plans ) && is_array( $result->plans ) ) ? $result->plans : array();
58
59 $paid_plan = $this->find_paid_plan( $plans );
60 if ( null === $paid_plan ) {
61 return array();
62 }
63
64 $currency = 'usd';
65 $tiers = array();
66
67 foreach ( (array) $paid_plan->pricing as $pricing ) {
68 $annual = $this->price( $pricing, 'annual_price' );
69 $monthly = $this->price( $pricing, 'monthly_price' );
70 $lifetime = $this->price( $pricing, 'lifetime_price' );
71
72 if ( null === $annual && null === $monthly && null === $lifetime ) {
73 continue;
74 }
75
76 if ( ! empty( $pricing->currency ) ) {
77 $currency = $pricing->currency;
78 }
79
80 $licenses = isset( $pricing->licenses ) && is_numeric( $pricing->licenses ) ? (int) $pricing->licenses : 0;
81
82 $tiers[] = array(
83 'pricing_id' => isset( $pricing->id ) ? (int) $pricing->id : 0,
84 'licenses' => $licenses,
85 'annual' => $annual,
86 'monthly' => $monthly,
87 'lifetime' => $lifetime,
88 );
89 }
90
91 usort(
92 $tiers,
93 function ( $a, $b ) {
94 // Unlimited (0) goes last.
95 if ( 0 === $a['licenses'] ) {
96 return 1;
97 }
98 if ( 0 === $b['licenses'] ) {
99 return -1;
100 }
101 return $a['licenses'] - $b['licenses'];
102 }
103 );
104
105 return array(
106 'plan_id' => (int) $paid_plan->id,
107 'currency' => $currency,
108 'tiers' => $tiers,
109 );
110 }
111
112 /**
113 * Pick the main paid plan (the one carrying the most priced tiers).
114 *
115 * @param array $plans
116 * @return object|null
117 */
118 private function find_paid_plan( array $plans ) {
119 $best = null;
120 $best_count = 0;
121
122 foreach ( $plans as $plan ) {
123 if ( empty( $plan->pricing ) || ! is_array( $plan->pricing ) ) {
124 continue;
125 }
126
127 $count = 0;
128 foreach ( $plan->pricing as $pricing ) {
129 if (
130 null !== $this->price( $pricing, 'annual_price' ) ||
131 null !== $this->price( $pricing, 'monthly_price' ) ||
132 null !== $this->price( $pricing, 'lifetime_price' )
133 ) {
134 ++$count;
135 }
136 }
137
138 if ( $count > $best_count ) {
139 $best_count = $count;
140 $best = $plan;
141 }
142 }
143
144 return $best;
145 }
146
147 /**
148 * Read a positive numeric price off a pricing object, else null.
149 *
150 * @param object $pricing
151 * @param string $key
152 * @return float|null
153 */
154 private function price( $pricing, string $key ) {
155 if ( isset( $pricing->{$key} ) && is_numeric( $pricing->{$key} ) && $pricing->{$key} > 0 ) {
156 return (float) $pricing->{$key};
157 }
158 return null;
159 }
160 }
161