PluginProbe
Elementor Website Builder – more than just a page builder / 4.2.0
Elementor Website Builder – more than just a page builder v4.2.0
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 / modules / components / components-repository.php

components-repository.php in Elementor Website Builder – more than just a page builder 4.2.0, at modules/components/components-repository.php

214 lines 5.8 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\Components;
4
5 use Elementor\Core\Utils\Collection;
6 use Elementor\Modules\Components\Documents\Component as Component_Document;
7 use Elementor\Plugin;
8 use Elementor\Core\Base\Document;
9
10 if ( ! defined( 'ABSPATH' ) ) {
11 exit; // Exit if accessed directly.
12 }
13
14 class Components_Repository {
15
16 public static function make(): Components_Repository {
17 return new self();
18 }
19
20 public function all(): Collection {
21 // Components count is limited to 100, if we increase this number, we need to iterate the posts in batches.
22 $posts = get_posts( [
23 'post_type' => Component_Document::TYPE,
24 'post_status' => 'any',
25 'posts_per_page' => Components_REST_API::MAX_COMPONENTS,
26 ] );
27
28 $components = [];
29
30 foreach ( $posts as $post ) {
31 $component = $this->get( $post->ID );
32
33 if ( ! $component ) {
34 continue;
35 }
36
37 $components[] = [
38 'id' => $component->get_main_id(),
39 'title' => $component->get_post()->post_title,
40 'uid' => $component->get_component_uid(),
41 'is_archived' => $component->get_is_archived(),
42 'styles' => $this->extract_styles( $component->get_elements_data() ),
43 ];
44 }
45
46 return Collection::make( $components );
47 }
48
49 public function get( $id, bool $include_autosave = true ) {
50 $doc = $include_autosave
51 ? Plugin::$instance->documents->get_doc_or_auto_save( $id, get_current_user_id() )
52 : Plugin::$instance->documents->get( $id );
53
54 if ( ! $doc instanceof Component_Document ) {
55 return null;
56 }
57
58 return $doc;
59 }
60
61 public function create( string $title, array $content, string $status, string $uid, array $settings = [] ) {
62 $document = Plugin::$instance->documents->create(
63 Component_Document::get_type(),
64 [
65 'post_title' => $title,
66 'post_status' => $status,
67 ],
68 [
69 Component_Document::COMPONENT_UID_META_KEY => $uid,
70 ]
71 );
72
73 try {
74 $saved = $document->save( [
75 'elements' => $content,
76 'settings' => $settings,
77 ] );
78 } catch ( \Exception $e ) {
79 $document->force_delete();
80 throw $e;
81 }
82
83 if ( ! $saved ) {
84 $document->force_delete();
85 throw new \Exception( 'Failed to create component' );
86 }
87
88 return $document->get_main_id();
89 }
90 private function extract_styles( array $elements, array $styles = [] ) {
91 foreach ( $elements as $element ) {
92 if ( isset( $element['styles'] ) ) {
93 $styles = array_merge( $styles, $element['styles'] );
94 }
95
96 if ( isset( $element['elements'] ) ) {
97 $styles = $this->extract_styles( $element['elements'], $styles );
98 }
99 }
100
101 return $styles;
102 }
103
104 public function archive( array $ids, string $status ) {
105 $failed_ids = [];
106 $success_ids = [];
107
108 foreach ( $ids as $id ) {
109 try {
110 $component = $this->get_component_for_edit( $id, $status );
111
112 if ( ! $component ) {
113 $failed_ids[] = $id;
114 continue;
115 }
116
117 $component->archive();
118 $success_ids[] = $id;
119 } catch ( \Exception $e ) {
120 $failed_ids[] = $id;
121 }
122 }
123
124 return [
125 'failedIds' => $failed_ids,
126 'successIds' => $success_ids,
127 ];
128 }
129
130 public function update_title( int $component_id, string $title, string $status ): bool {
131 $component = $this->get_component_for_edit( $component_id, $status );
132
133 if ( ! $component ) {
134 return false;
135 }
136
137 return $component->update_title( $title );
138 }
139
140 /**
141 * Get the component for edit.
142 *
143 * @param int $component_id The component ID.
144 * @param string $target_status The target status, means the status the component should be saved as.
145 * @return ?Component_Document The component document for edit.
146 *
147 * If target status is an autosave / draft:
148 * - If the component main document is autosave / draft, it will return the main document.
149 * - If the component main document is published, it will create a new autosave document and return it.
150
151 * If target status is publish:
152 * - Will return the main document. If it's an autosave, it will be published later by the publish_component method.
153 */
154 private function get_component_for_edit( int $component_id, string $target_status ): ?Component_Document {
155 $component = $this->get( $component_id );
156
157 if ( ! $component ) {
158 return null;
159 }
160
161 $autosave_statuses = [ Document::STATUS_AUTOSAVE, Document::STATUS_DRAFT ];
162 $autosave_exists = $component->is_autosave();
163 $should_create_autosave = in_array( $target_status, $autosave_statuses, true ) && ! $autosave_exists;
164
165 if ( ! $should_create_autosave ) {
166 return $component;
167 }
168
169 // Create a new autosave document, based on the published version.
170 return $component->get_autosave( 0, true );
171 }
172
173 public function publish_component( Component_Document $component ): bool {
174 try {
175 $main_id = $component->get_main_id();
176 $main_component = $this->get( $main_id, false );
177
178 $autosave = $main_component->get_newer_autosave();
179
180 if ( $autosave ) {
181 $success = $this->copy_autosave_data_to_main_component_document_and_publish( $autosave, $main_component, $main_id );
182 } else {
183 $success = $main_component->update_status( Document::STATUS_PUBLISH );
184 }
185
186 if ( ! $success ) {
187 throw new \Exception( 'Failed to publish component' );
188 }
189 } catch ( \Exception $e ) {
190 return false;
191 }
192
193 return true;
194 }
195
196 private function copy_autosave_data_to_main_component_document_and_publish( Component_Document $autosave, Component_Document $main_component_document, int $main_id ): bool {
197 $autosave_id = $autosave->get_post()->ID;
198
199 // Copy component custom meta keys from the autosave to the main component.
200 Plugin::$instance->db->copy_elementor_meta( $autosave_id, $main_id, Component_Document::COMPONENT_CUSTOM_META_KEYS );
201
202 $autosave_elements = $autosave->get_elements_data();
203 $autosave_title = $autosave->get_post()->post_title;
204
205 return $main_component_document->save( [
206 'elements' => $autosave_elements,
207 'settings' => [
208 'post_status' => Document::STATUS_PUBLISH,
209 'post_title' => $autosave_title,
210 ],
211 ] );
212 }
213 }
214