PluginProbe ʕ •ᴥ•ʔ
Starter Sites & Templates by Neve / 1.4.1
Starter Sites & Templates by Neve v1.4.1
1.4.1 1.4.0 1.3.0 1.2.29 1.2.28 1.2.6 1.2.7 1.2.8 1.2.9 trunk 1.0.10 1.0.11 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.20 1.1.21 1.1.22 1.1.23 1.1.24 1.1.25 1.1.26 1.1.27 1.1.28 1.1.29 1.1.3 1.1.30 1.1.31 1.1.32 1.1.33 1.1.34 1.1.35 1.1.36 1.1.37 1.1.38 1.1.39 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.3 1.2.4 1.2.5
templates-patterns-collection / includes / Sites_Listing.php
templates-patterns-collection / includes Last commit date
Importers 2 months ago Admin.php 2 weeks ago Editor.php 1 year ago Elementor.php 1 year ago License.php 1 year ago Logger.php 2 years ago Main.php 1 day ago Rest_Server.php 3 weeks ago Sites_Listing.php 1 day ago Starter_Ranking.php 2 weeks ago TI_Beaver.php 1 year ago WP_Cli.php 3 months ago White_Label_Config.php 3 years ago
Sites_Listing.php
277 lines
1 <?php
2 /**
3 * Theme Onboarding Sites_Listing
4 *
5 * @package templates-patterns-collection
6 */
7
8 namespace TIOB;
9
10 /**
11 * Class Sites_Listing
12 */
13 class Sites_Listing {
14
15 /**
16 * Sites Listing API URL
17 */
18 const API = 'https://api.themeisle.com/sites/wp-json/demosites-api/sites';
19
20 /**
21 * Key of transient where we save the sites list.
22 *
23 * The key is version-stamped so that a plugin update always busts a
24 * potentially stuck cache.
25 *
26 * @var string
27 */
28 private $transient_key = 'tiob_sites_' . TIOB_VERSION;
29
30 /**
31 * How long the sites list cache is considered fresh, in seconds.
32 *
33 * @var int
34 */
35 private $cache_ttl = 12 * HOUR_IN_SECONDS;
36
37 /**
38 * The onboarding config.
39 *
40 * @var array
41 */
42 private $onboarding_config = array();
43
44 /**
45 * Initialize the Class.
46 */
47 public function init() {
48 // Personalization is applied on the client via /starter_order.
49 $this->onboarding_config = array(
50 'remote' => $this->get_sites(),
51 'upsell' => array(),
52 'can_migrate' => array(
53 'zerif-pro' => array(
54 'theme_name' => 'Zelle Pro',
55 'theme_mod_check' => 'zelle_frontpage_was_imported',
56 'template' => 'zelle',
57 'heading' => __( 'Want to keep using Zelle\'s homepage?', 'templates-patterns-collection' ),
58 'description' => __( 'Hi! We\'ve noticed you were using Zelle before. To make your transition easier, we can help you keep the same beautiful homepage you had before, by converting it into an Elementor template. This option will also import your homepage content.', 'templates-patterns-collection' ),
59 'mandatory_plugins' => array(
60 'elementor' => 'Elementor Page Builder',
61 ),
62 ),
63 'zerif-lite' => array(
64 'theme_name' => 'Zelle Lite',
65 'theme_mod_check' => 'zelle_frontpage_was_imported',
66 'template' => 'zelle',
67 'heading' => __( 'Want to keep using Zelle\'s homepage?', 'templates-patterns-collection' ),
68 'description' => __( 'Hi! We\'ve noticed you were using Zelle before. To make your transition easier, we can help you keep the same beautiful homepage you had before, by converting it into an Elementor template. This option will also import your homepage content.', 'templates-patterns-collection' ),
69 'mandatory_plugins' => array(
70 'elementor' => 'Elementor Page Builder',
71 ),
72 ),
73 ),
74 'pro_link' => tsdk_translate_link( tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'onboarding' ), 'query' ),
75 );
76 $this->add_sites_library_support();
77 }
78
79 /**
80 * Return the API path
81 *
82 * @return string
83 */
84 final public static function get_api_path() {
85 if ( defined( 'TPC_USE_STAGING' ) && TPC_USE_STAGING === true ) {
86 return ( ( defined( 'TPC_API_STAGING' ) && ! empty( TPC_API_STAGING ) ) ? TPC_API_STAGING : self::API ) . self::add_query_args();
87 }
88 return self::API . self::add_query_args();
89 }
90
91 /**
92 * Allows adding $_GET arguments to API path.
93 *
94 * @return string
95 */
96 private static function add_query_args() {
97 $query_args = array();
98 $allowed_keys = array(
99 'show-legacy-sites',
100 );
101 // filter all keys that are not in $allowed_keys since the filter can provide third parties access to the URL.
102 $query_args = array_intersect_key( apply_filters( 'tpc_starter_api_query_filter', $query_args ), array_flip( $allowed_keys ) );
103 $query_string = http_build_query( $query_args );
104
105 return ( ! empty( $query_string ) ) ? '?' . $query_string : '';
106 }
107
108 /**
109 * Add theme support
110 */
111 public function add_sites_library_support() {
112 add_theme_support( 'themeisle-demo-import', $this->get_ti_demo_content_support_data() );
113 }
114
115 /**
116 * Get the sites
117 *
118 * @return array
119 */
120 private function get_sites() {
121 $response = $this->get_cached_sites();
122
123 if ( $response === false ) {
124 $response = wp_remote_get( esc_url( self::get_api_path() ) );
125
126 if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
127 return array();
128 }
129
130 $response = wp_remote_retrieve_body( $response );
131
132 $response = json_decode( $response, true );
133
134 if ( ! is_array( $response ) || empty( $response ) ) {
135 return array();
136 }
137 }
138
139 require_once ABSPATH . 'wp-admin/includes/plugin.php';
140 $upsell_status = $this->get_upsell_status();
141
142 $divi = array(
143 array(
144 'name' => 'Divi Builder',
145 'active' => is_plugin_active( 'divi-builder/divi-builder.php' ),
146 'author_url' => esc_url( 'https://www.elegantthemes.com/gallery/divi/' ),
147 ),
148 );
149 $thive = array(
150 array(
151 'name' => 'Thrive Architect',
152 'active' => is_plugin_active( 'thrive-visual-editor/thrive-visual-editor.php' ),
153 'author_url' => esc_url( 'https://thrivethemes.com/architect/' ),
154 ),
155 );
156
157 foreach ( $response as $editor => $sites ) {
158 foreach ( $sites as $slug => $site_data ) {
159 if ( $editor === 'divi builder' ) {
160 $response[ $editor ][ $slug ]['external_plugins'] = $divi;
161 }
162 if ( $editor === 'thrive architect' ) {
163 $response[ $editor ][ $slug ]['external_plugins'] = $thive;
164 }
165 if ( isset( $site_data['upsell'] ) ) {
166 $response[ $editor ][ $slug ]['upsell'] = $upsell_status;
167 }
168 }
169 }
170
171 set_transient(
172 $this->transient_key,
173 array(
174 'fetched_at' => time(),
175 'data' => $response,
176 ),
177 $this->cache_ttl
178 );
179
180 return $response;
181 }
182
183 /**
184 * Get the cached sites list, if it is still fresh.
185 *
186 * Instead of relying solely on the transient timeout row - which external
187 * DB/transient cleanup tools can strip, leaving the value non-expiring and
188 * served forever - we embed our own `fetched_at` timestamp in the payload
189 * and validate it on read.
190 *
191 * @return array|false The cached sites data, or false when there is no
192 * fresh cache and a fresh fetch is required.
193 */
194 private function get_cached_sites() {
195 $cache = get_transient( $this->transient_key );
196
197 if ( ! is_array( $cache ) || ! isset( $cache['fetched_at'], $cache['data'] ) ) {
198 return false;
199 }
200
201 if ( ( time() - (int) $cache['fetched_at'] ) >= $this->cache_ttl ) {
202 return false;
203 }
204
205 return $cache['data'];
206 }
207
208 /**
209 * Get the themeisle demo content support data.
210 *
211 * @return array
212 */
213 private function get_ti_demo_content_support_data() {
214 $this->reorder_starter_sites();
215 return apply_filters( 'neve_filter_onboarding_sites', $this->onboarding_config );
216 }
217
218 /**
219 * Reorder starter sites based on previous theme
220 *
221 * @return bool
222 */
223 private function reorder_starter_sites() {
224 $previous_theme = get_theme_mod( 'ti_prev_theme' );
225 if ( empty( $previous_theme ) ) {
226 return false;
227 }
228
229 $slug_association = array(
230 'zerif-pro' => 'neve-zelle',
231 'zerif-lite' => 'neve-zelle',
232 'themotion' => 'neve-themotion',
233 'themotion-lite' => 'neve-themotion',
234 'amadeus' => 'neve-amadeus',
235 'rokophoto-lite' => 'neve-rokophoto',
236 'rokophoto' => 'neve-rokophoto',
237 'oblique' => 'neve-oblique',
238 'shop-isle' => 'neve-shop',
239 'shop-isle-pro' => 'neve-shop',
240 'lawyeria-lite' => 'neve-lawyer',
241 'lawyeria' => 'neve-lawyer',
242 );
243 if ( ! array_key_exists( $previous_theme, $slug_association ) ) {
244 return false;
245 }
246 if ( ! isset( $this->onboarding_config['local']['elementor'][ $slug_association[ $previous_theme ] ] ) ) {
247 return false;
248 }
249 $starter_site = $this->onboarding_config['local']['elementor'][ $slug_association[ $previous_theme ] ];
250 unset( $this->onboarding_config['local']['elementor'][ $slug_association[ $previous_theme ] ] );
251 $this->onboarding_config['local']['elementor'] = array( $slug_association[ $previous_theme ] => $starter_site ) + $this->onboarding_config['local']['elementor'];
252
253 return true;
254 }
255
256 /**
257 * Get upsell status.
258 *
259 * @return bool
260 */
261 private function get_upsell_status() {
262 $category = apply_filters( 'product_neve_license_plan', -1 );
263 $category_mapping = array(
264 1 => 1,
265 2 => 1,
266 3 => 2,
267 4 => 2,
268 5 => 3,
269 6 => 3,
270 7 => 1,
271 8 => 2,
272 9 => 3,
273 );
274 return apply_filters( 'product_neve_license_status', false ) !== 'valid' || ! isset( $category_mapping[ $category ] ) || $category_mapping[ $category ] < 2;
275 }
276 }
277