PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.0-beta1
Elementor Website Builder – more than just a page builder v4.3.0-beta1
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
elementor / includes / editor-assets-api.php

editor-assets-api.php in Elementor Website Builder – more than just a page builder 4.3.0-beta1, at includes/editor-assets-api.php

163 lines 4.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor\Includes;
3
4 class EditorAssetsAPI {
5 protected array $config;
6
7 const ASSETS_DATA_TRANSIENT_KEY = 'ASSETS_DATA_TRANSIENT_KEY';
8
9 const ASSETS_DATA_URL = 'ASSETS_DATA_URL';
10
11 const ASSETS_DATA_KEY = 'ASSETS_DATA_KEY';
12
13 const ASSETS_DATA_EXPIRATION = 'ASSETS_DATA_EXPIRATION';
14
15 const DEFAULT_EXPIRATION_TIME = '+1 hour';
16
17 const PRODUCTION_URL = 'https://assets.elementor.com';
18 const STAGING_URL = 'https://assets.stg.elementor.red';
19 const DEV_URL = 'https://assets.dev.builder.elementor.red';
20
21 private static ?array $allowed_hosts = null;
22
23 public function __construct( array $config ) {
24 $this->config = $config;
25 }
26
27 public function config( $key ): string {
28 return $this->config[ $key ] ?? '';
29 }
30
31 public function get_assets_data( $force_request = false ): array {
32 $assets_data = $this->get_transient( $this->config( static::ASSETS_DATA_TRANSIENT_KEY ) );
33
34 if ( $force_request || false === $assets_data ) {
35 $fresh_data = $this->fetch_data();
36
37 if ( empty( $fresh_data ) ) {
38 return ! empty( $assets_data ) ? $assets_data : [];
39 }
40
41 $assets_data = $fresh_data;
42 $this->set_transient( $this->config( static::ASSETS_DATA_TRANSIENT_KEY ), $assets_data, $this->get_expiration_time() );
43 }
44
45 return $assets_data;
46 }
47
48 private function fetch_data(): array {
49 $url = $this->config( static::ASSETS_DATA_URL );
50 $data = self::do_safe_get_request( $url );
51
52 if ( ! $this->has_valid_data( $data ) ) {
53 return [];
54 }
55
56 return $data[ $this->config( static::ASSETS_DATA_KEY ) ];
57 }
58
59 private function get_transient( $cache_key ) {
60 $cache = get_option( $cache_key );
61
62 if ( empty( $cache['timeout'] ) ) {
63 return false;
64 }
65
66 if ( current_time( 'timestamp' ) > $cache['timeout'] ) {
67 return false;
68 }
69
70 return json_decode( $cache['value'], true );
71 }
72
73 private function set_transient( $cache_key, $value, $expiration ): bool {
74 $data = [
75 'timeout' => strtotime( $expiration, current_time( 'timestamp' ) ),
76 'value' => wp_json_encode( $value ),
77 ];
78
79 return update_option( $cache_key, $data, false );
80 }
81
82 private function get_expiration_time(): string {
83 $expiration = $this->config( static::ASSETS_DATA_EXPIRATION );
84 return $expiration ? $expiration : static::DEFAULT_EXPIRATION_TIME;
85 }
86
87 private function has_valid_data( $data ): bool {
88 if ( ! is_array( $data ) ) {
89 return false;
90 }
91
92 $key = $this->config( static::ASSETS_DATA_KEY );
93 return static::is_non_empty_array( $data[ $key ] ?? null );
94 }
95
96 public static function has_valid_nested_array( $data, array $nested_array_path ): bool {
97 $current = $data;
98
99 foreach ( $nested_array_path as $nested_key ) {
100 if ( ! is_array( $current ) || ! array_key_exists( $nested_key, $current ) ) {
101 return false;
102 }
103 $current = $current[ $nested_key ];
104 }
105
106 if ( ! static::is_non_empty_array( $current ) ) {
107 return false;
108 }
109
110 return true;
111 }
112
113 public static function is_valid_data( $data ): bool {
114 return static::is_non_empty_array( $data );
115 }
116
117 private static function is_non_empty_array( $value ): bool {
118 return is_array( $value ) && ! empty( $value );
119 }
120
121 private static function get_allowed_hosts(): array {
122 if ( null !== self::$allowed_hosts ) {
123 return self::$allowed_hosts;
124 }
125
126 self::$allowed_hosts = array_values( array_filter( array_map(
127 fn( $url ) => wp_parse_url( $url, PHP_URL_HOST ),
128 [ self::PRODUCTION_URL, self::STAGING_URL, self::DEV_URL ]
129 ) ) );
130
131 return self::$allowed_hosts;
132 }
133
134 public static function is_allowed_url( $url ): bool {
135 if ( ! is_string( $url ) || ! wp_http_validate_url( $url ) ) {
136 return false;
137 }
138
139 if ( 'https' !== wp_parse_url( $url, PHP_URL_SCHEME ) ) {
140 return false;
141 }
142
143 return in_array( wp_parse_url( $url, PHP_URL_HOST ), self::get_allowed_hosts(), true );
144 }
145
146 public static function do_safe_get_request( $url ) {
147 if ( ! self::is_allowed_url( $url ) ) {
148 return null;
149 }
150
151 $response = wp_safe_remote_get( $url, [
152 'timeout' => 5,
153 'limit_response_size' => 512 * KB_IN_BYTES,
154 ] );
155
156 if ( is_wp_error( $response ) || \WP_Http::OK !== (int) wp_remote_retrieve_response_code( $response ) ) {
157 return null;
158 }
159
160 return json_decode( wp_remote_retrieve_body( $response ), true );
161 }
162 }
163