PluginProbe
Elementor Website Builder – more than just a page builder / 4.0.0-dev3
Elementor Website Builder – more than just a page builder v4.0.0-dev3
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
← All changes | modules/atomic-widgets/styles/css-files-manager.php +21 -123 4.3.0-beta34.0.0-dev3 View file →
@@ -1,119 +1,59 @@
1 1 <?php
2 2
3 3 namespace Elementor\Modules\AtomicWidgets\Styles;
4 4
5 -use Elementor\Core\Files\Base as Base_File;
6 -use Elementor\Modules\AtomicWidgets\Styles\CacheValidity\Cache_Validity;
7 -
8 5 class CSS_Files_Manager {
9 - const DEFAULT_CSS_DIR = 'css/';
6 + const DEFAULT_CSS_DIR = 'elementor/css/';
10 7 const FILE_EXTENSION = '.css';
11 8 // Read and write permissions for the owner
12 9 const PERMISSIONS = 0644;
13 10
14 - private Cache_Validity $cache_validity;
15 -
16 - public function __construct( ?Cache_Validity $cache_validity = null ) {
17 - $this->cache_validity = $cache_validity ?? new Cache_Validity();
18 - }
19 -
20 - /**
21 - * Return the CSS file to enqueue for the given cache path, generating it on demand.
22 - *
23 - * The `should_exist` meta flag distinguishes an intentionally empty file from one
24 - * that went missing after being generated, and cache is regenerated whenever it's
25 - * invalid or the expected file can't be found on disk.
26 - *
27 - * @param string $handle
28 - * @param string $media
29 - * @param callable $get_css
30 - * @param array<string> $cache_path Cache-validity leaf path.
31 - * @return Style_File|null
32 - */
33 - public function get( string $handle, string $media, callable $get_css, array $cache_path ): ?Style_File {
11 + public function get( string $handle, string $media, callable $get_css, bool $is_valid_cache ): ?Style_File {
12 + $filesystem = $this->get_filesystem();
34 13 $path = $this->get_path( $handle );
35 - $is_cache_valid = $this->cache_validity->is_valid( $cache_path );
36 - $should_exist = $this->get_should_exist_meta( $cache_path );
37 14
38 - if ( $is_cache_valid ) {
39 - if ( false === $should_exist ) {
15 + if ( $is_valid_cache ) {
16 + if ( ! $filesystem->exists( $path ) ) {
40 17 return null;
41 18 }
42 19
43 - if ( $this->has_non_empty_file( $path ) ) {
44 - return $this->create_style_file( $handle, $path, $media );
45 - }
20 + // Return the existing file
21 + return Style_File::create(
22 + $this->sanitize_handle( $handle ),
23 + $this->get_filesystem_path( $this->get_path( $handle ) ),
24 + $this->get_url( $handle ),
25 + $media,
26 + );
46 27 }
47 28
48 29 $css = $get_css();
49 30
50 31 if ( empty( $css ) ) {
51 - // Nothing to serve for this path; purge any stale file and record the state
52 - // so we don't try to regenerate on every subsequent request.
53 - $this->delete_if_exists( $path );
54 - $this->cache_validity->validate( $cache_path, [ 'should_exist' => false ] );
55 -
56 32 return null;
57 33 }
58 34
59 35 $filesystem_path = $this->get_filesystem_path( $path );
60 36
61 - if ( ! $this->write_atomically( $filesystem_path, $css ) ) {
62 - // Hard write failure: leave the cache invalid so the next request retries.
63 - return null;
64 - }
37 + $is_created = $filesystem->put_contents( $filesystem_path, $css, self::PERMISSIONS );
65 38
66 - $this->cache_validity->validate( $cache_path, [ 'should_exist' => true ] );
67 -
68 - return $this->create_style_file( $handle, $path, $media );
69 - }
70 -
71 - public function delete( string $handle ): void {
72 - $this->delete_if_exists( $this->get_path( $handle ) );
73 - }
74 -
75 - private function get_should_exist_meta( array $cache_path ): ?bool {
76 - $meta = $this->cache_validity->get_meta( $cache_path );
77 -
78 - if ( ! is_array( $meta ) || ! array_key_exists( 'should_exist', $meta ) ) {
39 + if ( false === $is_created ) {
79 40 return null;
80 41 }
81 42
82 - return (bool) $meta['should_exist'];
83 - }
84 -
85 - private function create_style_file( string $handle, string $path, string $media ): Style_File {
86 43 return Style_File::create(
87 44 $this->sanitize_handle( $handle ),
88 - $this->get_filesystem_path( $path ),
45 + $filesystem_path,
89 46 $this->get_url( $handle ),
90 47 $media
91 48 );
92 49 }
93 50
94 - private function has_non_empty_file( string $path ): bool {
51 + public function delete( string $handle ): void {
95 52 $filesystem = $this->get_filesystem();
53 + $path = $this->get_path( $handle );
96 54
97 55 if ( ! $filesystem->exists( $path ) ) {
98 - return false;
99 - }
100 -
101 - $size = $filesystem->size( $path );
102 -
103 - // `size()` may return false on filesystems that don't support it; treat that as
104 - // "we don't know" and fall back to trusting the existence check.
105 - if ( false === $size ) {
106 - return true;
107 - }
108 -
109 - return $size > 0;
110 - }
111 -
112 - private function delete_if_exists( string $path ): void {
113 - $filesystem = $this->get_filesystem();
114 -
115 - if ( ! $filesystem->exists( $path ) ) {
116 56 return;
117 57 }
118 58
119 59 $filesystem->delete( $path );
@@ -118,52 +58,8 @@
118 58
119 59 $filesystem->delete( $path );
120 60 }
121 61
122 - /**
123 - * Write to a temp file first and then move it into place. The move step is atomic on
124 - * POSIX filesystems, so the public URL cannot serve a partial or zero-byte asset while a
125 - * concurrent render is in progress. If the atomic move is not supported by the current
126 - * filesystem adapter, fall back to a direct write.
127 - */
128 - private function write_atomically( string $filesystem_path, string $css ): bool {
129 - $filesystem = $this->get_filesystem();
130 -
131 - if ( ! $this->ensure_directory_exists( dirname( $filesystem_path ) ) ) {
132 - return false;
133 - }
134 -
135 - $tmp_path = $filesystem_path . '.tmp-' . wp_generate_password( 8, false, false );
136 -
137 - $is_written = $filesystem->put_contents( $tmp_path, $css, self::PERMISSIONS );
138 -
139 - if ( false === $is_written ) {
140 - return false;
141 - }
142 -
143 - if ( ! method_exists( $filesystem, 'move' ) || ! $filesystem->move( $tmp_path, $filesystem_path, true ) ) {
144 - $fallback = $filesystem->put_contents( $filesystem_path, $css, self::PERMISSIONS );
145 -
146 - if ( $filesystem->exists( $tmp_path ) ) {
147 - $filesystem->delete( $tmp_path );
148 - }
149 -
150 - return false !== $fallback;
151 - }
152 -
153 - return true;
154 - }
155 -
156 - private function ensure_directory_exists( string $directory ): bool {
157 - $filesystem = $this->get_filesystem();
158 -
159 - if ( $filesystem->is_dir( $directory ) ) {
160 - return true;
161 - }
162 -
163 - return wp_mkdir_p( $directory );
164 - }
165 -
166 62 private function get_filesystem(): \WP_Filesystem_Base {
167 63 global $wp_filesystem;
168 64
169 65 if ( empty( $wp_filesystem ) ) {
@@ -180,19 +76,21 @@
180 76 return str_replace( ABSPATH, $filesystem->abspath(), $path );
181 77 }
182 78
183 79 private function get_url( string $handle ): string {
80 + $upload_dir = wp_upload_dir();
184 81 $sanitized_handle = $this->sanitize_handle( $handle );
185 82 $handle = $sanitized_handle . self::FILE_EXTENSION;
186 83
187 - return Base_File::get_base_uploads_url() . self::DEFAULT_CSS_DIR . $handle;
84 + return trailingslashit( $upload_dir['baseurl'] ) . self::DEFAULT_CSS_DIR . $handle;
188 85 }
189 86
190 87 private function get_path( string $handle ): string {
88 + $upload_dir = wp_upload_dir();
191 89 $sanitized_handle = $this->sanitize_handle( $handle );
192 90 $handle = $sanitized_handle . self::FILE_EXTENSION;
193 91
194 - return Base_File::get_base_uploads_dir() . self::DEFAULT_CSS_DIR . $handle;
92 + return trailingslashit( $upload_dir['basedir'] ) . self::DEFAULT_CSS_DIR . $handle;
195 93 }
196 94
197 95 private function sanitize_handle( string $handle ): string {
198 96 return preg_replace( '/[^a-zA-Z0-9_-]/', '', $handle );