PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.0-beta3
Elementor Website Builder – more than just a page builder v4.3.0-beta3
4.3.0-beta3 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 All 452 releases
elementor / modules / variables / services / variables-service.php

variables-service.php in Elementor Website Builder – more than just a page builder 4.3.0-beta3, at modules/variables/services/variables-service.php

275 lines 7.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Elementor\Modules\Variables\Services;
4
5 use Elementor\Modules\Variables\Services\Batch_Operations\Batch_Error_Formatter;
6 use Elementor\Modules\Variables\Services\Batch_Operations\Batch_Processor;
7 use Elementor\Modules\Variables\Storage\Entities\Variable;
8 use Elementor\Modules\Variables\Storage\Exceptions\BatchOperationFailed;
9 use Elementor\Modules\Variables\Storage\Variables_Repository;
10 use Elementor\Modules\Variables\Storage\Exceptions\FatalError;
11 use Elementor\Modules\Variables\PropTypes\Size_Variable_Prop_Type;
12 use Elementor\Utils as ElementorUtils;
13
14 class Variables_Service {
15 private Variables_Repository $repo;
16 private Batch_Processor $batch_processor;
17
18 public function __construct( Variables_Repository $repository, Batch_Processor $batch_processor ) {
19 $this->repo = $repository;
20 $this->batch_processor = $batch_processor;
21 }
22
23 public function get_variables_list(): array {
24 return $this->load()['data'];
25 }
26
27 public function find_by_label_or_id( string $needle ): ?array {
28 $needle = trim( $needle );
29 $needle = ltrim( $needle, '-' );
30
31 if ( '' === $needle ) {
32 return null;
33 }
34
35 $variables = $this->get_variables_list();
36
37 if ( isset( $variables[ $needle ] ) ) {
38 $variable = $variables[ $needle ];
39
40 if ( ! empty( $variable['deleted'] ) ) {
41 return null;
42 }
43
44 return array_merge( [ 'id' => $needle ], $variable );
45 }
46
47 foreach ( $variables as $id => $variable ) {
48 if ( ! empty( $variable['deleted'] ) ) {
49 continue;
50 }
51
52 if ( strcasecmp( $variable['label'] ?? '', $needle ) === 0 ) {
53 return array_merge( [ 'id' => $id ], $variable );
54 }
55 }
56
57 return null;
58 }
59
60 public function load() {
61 $collection = $this->repo->load()->serialize( true );
62 foreach ( $collection['data'] as $id => $variable ) {
63 if ( ! ElementorUtils::has_pro() && Size_Variable_Prop_Type::get_key() === $variable['type'] ) {
64 unset( $collection['data'][ $id ] );
65 }
66 }
67 return $collection;
68 }
69
70 /**
71 * @throws BatchOperationFailed Thrown when one of the operations fails and $lenient is false.
72 * @throws FatalError Failed to save after batch.
73 */
74 public function process_batch( array $operations, bool $lenient = false ) {
75 $collection = $this->repo->load();
76 $results = [];
77 $errors = [];
78 $has_success = false;
79
80 $error_formatter = new Batch_Error_Formatter();
81
82 foreach ( $operations as $index => $operation ) {
83 try {
84 $batch_result = $this->batch_processor->apply_operation( $collection, $operation );
85 $has_success = true;
86
87 if ( $lenient ) {
88 $results[] = $this->format_lenient_success_result( $index, $batch_result );
89 } else {
90 $results[] = $batch_result;
91 }
92 } catch ( \Exception $e ) {
93 if ( $lenient ) {
94 $results[] = [
95 'index' => $index,
96 'status' => 'error',
97 'action' => $operation['type'] ?? '',
98 'id' => $operation['id'] ?? ( $operation['variable']['id'] ?? null ),
99 'code' => $error_formatter->error_code_for( $e ),
100 'message' => $e->getMessage(),
101 ];
102 } else {
103 $errors[ $this->batch_processor->operation_id( $operation, $index ) ] = [
104 'status' => $error_formatter->status_for( $e ),
105 'code' => $error_formatter->error_code_for( $e ),
106 'message' => $e->getMessage(),
107 ];
108 }
109 }
110 }
111
112 if ( ! $lenient && ! empty( $errors ) ) {
113 // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped
114 throw new BatchOperationFailed( 'Batch failed', $errors );
115 }
116
117 if ( ! $has_success ) {
118 return [
119 'success' => false,
120 'results' => $results,
121 'watermark' => $collection->watermark(),
122 ];
123 }
124
125 $watermark = $this->repo->save( $collection );
126
127 if ( false === $watermark ) {
128 throw new FatalError( 'Failed to save batch operations' );
129 }
130
131 return [
132 'success' => true,
133 'results' => $results,
134 'watermark' => $watermark,
135 ];
136 }
137
138 private function format_lenient_success_result( int $index, array $batch_result ): array {
139 $result = [
140 'index' => $index,
141 'status' => 'ok',
142 'action' => $batch_result['type'] ?? '',
143 'id' => $batch_result['id'] ?? null,
144 ];
145
146 if ( isset( $batch_result['variable']['label'] ) ) {
147 $result['label'] = $batch_result['variable']['label'];
148 }
149
150 if ( isset( $batch_result['variable']['type'] ) ) {
151 $result['type'] = $batch_result['variable']['type'];
152 }
153
154 return $result;
155 }
156
157 /**
158 * @throws FatalError If variable create fails or validation errors occur.
159 */
160 public function create( array $data ): array {
161 $collection = $this->repo->load();
162
163 $collection->assert_limit_not_reached();
164 $collection->assert_label_is_unique( $data['label'] );
165
166 $id = $collection->next_id();
167 $data['id'] = $id;
168
169 // TODO: we need to look into this maybe we dont need order to be sent from client. Just implemented as it was
170 if ( ! isset( $data['order'] ) ) {
171 $data['order'] = $collection->get_next_order();
172 }
173
174 $variable = Variable::from_array( $data );
175 $variable->validate();
176
177 $collection->add_variable( $variable );
178
179 $watermark = $this->repo->save( $collection );
180
181 if ( false === $watermark ) {
182 throw new FatalError( 'Failed to create variable' );
183 }
184
185 return [
186 'variable' => array_merge( [ 'id' => $id ], $variable->to_array() ),
187 'watermark' => $collection->watermark(),
188 ];
189 }
190
191 /**
192 * @throws FatalError If variable update fails.
193 */
194 public function update( string $id, array $data ): array {
195 $collection = $this->repo->load();
196 $variable = $collection->find_or_fail( $id );
197
198 if ( isset( $data['label'] ) ) {
199 $collection->assert_label_is_unique( $data['label'], $id );
200 }
201
202 $variable->apply_changes( $data );
203 $variable->validate();
204
205 $watermark = $this->repo->save( $collection );
206
207 if ( false === $watermark ) {
208 throw new FatalError( 'Failed to update variable' );
209 }
210
211 return [
212 'variable' => array_merge( [ 'id' => $id ], $variable->to_array() ),
213 'watermark' => $watermark,
214 ];
215 }
216
217 /**
218 * @throws FatalError If variable delete fails.
219 */
220 public function delete( string $id ) {
221 $collection = $this->repo->load();
222 $variable = $collection->find_or_fail( $id );
223
224 $variable->soft_delete();
225
226 $watermark = $this->repo->save( $collection );
227
228 if ( false === $watermark ) {
229 throw new FatalError( 'Failed to delete variable' );
230 }
231
232 return [
233 'watermark' => $watermark,
234 'variable' => array_merge( [
235 'id' => $id,
236 'deleted' => true,
237 ], $variable->to_array() ),
238 ];
239 }
240
241 /**
242 * @throws FatalError If variable restore fails.
243 */
244 public function restore( string $id, $overrides = [] ) {
245 $collection = $this->repo->load();
246 $variable = $collection->find_or_fail( $id );
247
248 $label = $variable->label();
249
250 if ( isset( $overrides['label'] ) ) {
251 $label = $overrides['label'];
252 }
253
254 $collection->assert_limit_not_reached();
255
256 $collection->assert_label_is_unique( $label, $variable->id() );
257
258 $variable->apply_changes( $overrides );
259 $variable->validate();
260
261 $variable->restore();
262
263 $watermark = $this->repo->save( $collection );
264
265 if ( false === $watermark ) {
266 throw new FatalError( 'Failed to delete variable' );
267 }
268
269 return [
270 'variable' => array_merge( [ 'id' => $id ], $variable->to_array() ),
271 'watermark' => $watermark,
272 ];
273 }
274 }
275