Brizy – Page Builder - Version 2.3.29

Version Description

  • 2022-02-03 =
  • Fixed: Font url validation
  • Fixed: Do shortcode on render brizy content of the shop page
  • Fixed: Brizy and Complianz GDPR/CCPA Cookie Consent plugin incompatibility
  • Fixed: Saves scripts relative to the plugin main folder
  • Fixed: WPML menu switcher, WPML sync menu, WPML fatal error on duplicate non brizy posts
  • Fixed: Brizy Overview dashboard widget
  • Fixed: Allow br tags on render lead list in admin dashboard
Download this release

Release Info

Developer themefusecom
Plugin Icon 128x128 Brizy – Page Builder
Version 2.3.29
Comparing to
See all releases

Code changes from version 2.3.28 to 2.3.29

Files changed (47) hide show
  1. README.md +11 -2
  2. admin/dashboard-widget.php +3 -20
  3. admin/form-entries.php +8 -3
  4. admin/views/form-data.html.twig +11 -1
  5. brizy.php +2 -2
  6. compatibilities/complianz-gpdr.php +22 -0
  7. compatibilities/init.php +4 -0
  8. compatibilities/wpml.php +52 -7
  9. config.php +1 -1
  10. editor/editor/editor.php +1 -1
  11. editor/post.php +0 -41
  12. editor/url-builder.php +7 -4
  13. public/asset-enqueue-manager.php +15 -3
  14. public/main.php +1 -1
  15. readme.txt +11 -2
  16. site-url-replacer.php +0 -4
  17. vendor/autoload.php +1 -1
  18. vendor/bagrinsergiu/content-placeholder/lib/Extractor.php +1 -0
  19. vendor/composer/InstalledVersions.php +13 -14
  20. vendor/composer/autoload_real.php +7 -7
  21. vendor/composer/autoload_static.php +5 -5
  22. vendor/composer/installed.json +36 -30
  23. vendor/composer/installed.php +13 -14
  24. vendor/shortpixel/shortpixel-php/bin/shortpixel +2 -0
  25. vendor/shortpixel/shortpixel-php/lib/ShortPixel.php +2 -2
  26. vendor/shortpixel/shortpixel-php/lib/ShortPixel/Result.php +1 -1
  27. vendor/shortpixel/shortpixel-php/lib/ShortPixel/SPCache.php +12 -4
  28. vendor/shortpixel/shortpixel-php/lib/ShortPixel/SPLog.php +13 -0
  29. vendor/shortpixel/shortpixel-php/lib/ShortPixel/Source.php +2 -2
  30. vendor/shortpixel/shortpixel-php/lib/ShortPixel/persist/TextPersister.php +21 -11
  31. vendor/shortpixel/shortpixel-php/lib/cmdShortpixelOptimize.php +18 -14
  32. vendor/shortpixel/shortpixel-php/test.php +74 -0
  33. vendor/symfony/dotenv/Command/DebugCommand.php +143 -0
  34. vendor/symfony/dotenv/Command/DotenvDumpCommand.php +113 -0
  35. vendor/symfony/dotenv/Dotenv.php +20 -18
  36. vendor/symfony/dotenv/LICENSE +1 -1
  37. vendor/symfony/dotenv/Tests/Command/DebugCommandTest.php +153 -0
  38. vendor/symfony/dotenv/Tests/Command/DotenvDumpCommandTest.php +102 -0
  39. vendor/symfony/dotenv/Tests/Command/Fixtures/Scenario1/.env +2 -0
  40. vendor/symfony/dotenv/Tests/Command/Fixtures/Scenario1/.env.local +1 -0
  41. vendor/symfony/dotenv/Tests/Command/Fixtures/Scenario1/.env.prod.local +1 -0
  42. vendor/symfony/dotenv/Tests/Command/Fixtures/Scenario1/.env.test +1 -0
  43. vendor/symfony/dotenv/Tests/Command/Fixtures/Scenario2/.env.local.php +5 -0
  44. vendor/symfony/dotenv/Tests/Command/Fixtures/Scenario2/.env.prod +2 -0
  45. vendor/symfony/dotenv/Tests/Command/Fixtures/Scenario3/.env +1 -0
  46. vendor/symfony/dotenv/Tests/DotenvTest.php +127 -25
  47. vendor/symfony/polyfill-ctype/Ctype.php +29 -24
README.md CHANGED
@@ -1,9 +1,9 @@
1
  # Brizy - Page Builder
2
  Contributors: themefuse<br>
3
  Requires at least: 4.5<br>
4
- Tested up to: 5.8.3<br>
5
  Requires PHP: 5.6.20<br>
6
- Stable tag: 2.3.28<br>
7
  License: GPLv3<br>
8
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
9
 
@@ -118,6 +118,15 @@ $bodyHtml = apply_filters( 'brizy_content', $html->get_body(), Brizy_Editor_Proj
118
 
119
  ## Changelog
120
 
 
 
 
 
 
 
 
 
 
121
  ### 2.3.28 - 2022-01-17
122
  * Fixed: Color and align for text element
123
 
1
  # Brizy - Page Builder
2
  Contributors: themefuse<br>
3
  Requires at least: 4.5<br>
4
+ Tested up to: 5.9<br>
5
  Requires PHP: 5.6.20<br>
6
+ Stable tag: 2.3.29<br>
7
  License: GPLv3<br>
8
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
9
 
118
 
119
  ## Changelog
120
 
121
+ ### 2.3.29 - 2022-02-03
122
+ * Fixed: Font url validation
123
+ * Fixed: Do shortcode on render brizy content of the shop page
124
+ * Fixed: Brizy and Complianz – GDPR/CCPA Cookie Consent plugin incompatibility
125
+ * Fixed: Saves scripts relative to the plugin main folder
126
+ * Fixed: WPML menu switcher, WPML sync menu, WPML fatal error on duplicate non brizy posts
127
+ * Fixed: Brizy Overview dashboard widget
128
+ * Fixed: Allow br tags on render lead list in admin dashboard
129
+
130
  ### 2.3.28 - 2022-01-17
131
  * Fixed: Color and align for text element
132
 
admin/dashboard-widget.php CHANGED
@@ -74,9 +74,9 @@ class Brizy_Admin_DashboardWidget extends Brizy_Admin_AbstractWidget {
74
 
75
  $dom = Brizy_Parser_Pquery::parseStr( $request['body'] );
76
  $news = [];
77
- $titles = $dom->query( '.brz-wp-title .brz-a .brz-wp-title-content' );
78
- $links = $dom->query( '.brz-wp-title .brz-a' );
79
- $excerpts = $dom->query( '.brz-posts .brz-posts__item .brz-css-qtnxu' );
80
 
81
  if ( count( $titles ) !== 5 || count( $links ) !== 5 || count( $excerpts ) !== 5 ) {
82
  throw new Exception( __( 'Parsing failed!', 'brizy' ) );
@@ -104,23 +104,6 @@ class Brizy_Admin_DashboardWidget extends Brizy_Admin_AbstractWidget {
104
  return $news;
105
  }
106
 
107
- /**
108
- * @throws Exception
109
- */
110
- private function parseQuery( $selector, $dom, &$news, $key, $callback ) {
111
- $items = $dom->query( $selector );
112
-
113
- if ( ! $items || count( $items ) !== 5 ) {
114
- throw new Exception( __( 'Parsing failed!', 'brizy' ) );
115
- }
116
-
117
- foreach ( $items as $i => $item ) {
118
- if ( isset( $news[ $i ] ) ) {
119
- $news[ $i ][$key] = wp_strip_all_tags( $item->{$callback}() );
120
- }
121
- }
122
- }
123
-
124
  /**
125
  * @return string
126
  */
74
 
75
  $dom = Brizy_Parser_Pquery::parseStr( $request['body'] );
76
  $news = [];
77
+ $titles = $dom->query( '.wp-api-title' );
78
+ $links = $dom->query( '.wp-api-title .brz-a' );
79
+ $excerpts = $dom->query( '.wp-api-excerpt' );
80
 
81
  if ( count( $titles ) !== 5 || count( $links ) !== 5 || count( $excerpts ) !== 5 ) {
82
  throw new Exception( __( 'Parsing failed!', 'brizy' ) );
104
  return $news;
105
  }
106
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  /**
108
  * @return string
109
  */
admin/form-entries.php CHANGED
@@ -284,15 +284,20 @@ class Brizy_Admin_FormEntries {
284
  }
285
 
286
  $title = '';
287
- foreach ( $fields as $i => $field ) {
288
  if ( strtolower( $field->type ) == 'email' ) {
289
  $title = $field->value;
290
  }
291
 
292
  // We use htmlentities the user can insert text in some languages like German, Hindi, etc.
293
  // and the function json_encode broke the json or encode the characters.
294
- $fields[ $i ]->name = htmlentities( $field->name, ENT_COMPAT | ENT_HTML401, 'UTF-8' );
295
- $fields[ $i ]->value = htmlentities( $field->value, ENT_COMPAT | ENT_HTML401, 'UTF-8' );
 
 
 
 
 
296
  }
297
 
298
  $params = array(
284
  }
285
 
286
  $title = '';
287
+ foreach ( $fields as $field ) {
288
  if ( strtolower( $field->type ) == 'email' ) {
289
  $title = $field->value;
290
  }
291
 
292
  // We use htmlentities the user can insert text in some languages like German, Hindi, etc.
293
  // and the function json_encode broke the json or encode the characters.
294
+ $field->name = htmlentities( $field->name, ENT_COMPAT | ENT_HTML401, 'UTF-8' );
295
+
296
+ if ( $field->type == 'Paragraph' ) {
297
+ $field->value = preg_replace( "/\r\n|\r|\n/", '<br/>', $field->value );
298
+ }
299
+
300
+ $field->value = htmlentities( $field->value, ENT_COMPAT | ENT_HTML401, 'UTF-8' );
301
  }
302
 
303
  $params = array(
admin/views/form-data.html.twig CHANGED
@@ -5,7 +5,7 @@
5
  {% if field.type == "FileUpload" %}
6
  <span id="{{ field.name }}"><a href="{{ field.value }}" target="_blank">{{ field.value }}</a></span>
7
  {% else %}
8
- <span id="{{ field.name }}">{{ field.value }}</span>
9
  {% endif %}
10
  </li>
11
  {% endfor %}
@@ -22,4 +22,14 @@
22
  .formData span {
23
  vertical-align: middle;
24
  }
 
 
 
 
 
 
 
 
 
 
25
  </style>
5
  {% if field.type == "FileUpload" %}
6
  <span id="{{ field.name }}"><a href="{{ field.value }}" target="_blank">{{ field.value }}</a></span>
7
  {% else %}
8
+ <span id="{{ field.name }}" class="formData-{{ field.type|lower|escape('html_attr') }}">{{ field.value|striptags('<br>')|raw }}</span>
9
  {% endif %}
10
  </li>
11
  {% endfor %}
22
  .formData span {
23
  vertical-align: middle;
24
  }
25
+
26
+ .formData .formData-paragraph {
27
+ display: block;
28
+ height: auto;
29
+ max-height: 100px;
30
+ overflow: auto;
31
+ padding-left: 10px;
32
+ padding-top: 5px;
33
+ padding-bottom: 10px;
34
+ }
35
  </style>
brizy.php CHANGED
@@ -5,7 +5,7 @@
5
  * Plugin URI: https://brizy.io/
6
  * Author: Brizy.io
7
  * Author URI: https://brizy.io/
8
- * Version: 2.3.28
9
  * Text Domain: brizy
10
  * License: GPLv3
11
  * Domain Path: /languages
@@ -19,7 +19,7 @@ if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && stripos( $_SERVER['HTTP_X_FO
19
 
20
  define( 'BRIZY_DEVELOPMENT', false );
21
  define( 'BRIZY_LOG', false );
22
- define( 'BRIZY_VERSION', '2.3.28' );
23
  define( 'BRIZY_MINIMUM_PRO_VERSION', '2.3.0' );
24
  define( 'BRIZY_EDITOR_VERSION', BRIZY_DEVELOPMENT ? 'dev' : '216-wp' );
25
  define( 'BRIZY_SYNC_VERSION', '216' );
5
  * Plugin URI: https://brizy.io/
6
  * Author: Brizy.io
7
  * Author URI: https://brizy.io/
8
+ * Version: 2.3.29
9
  * Text Domain: brizy
10
  * License: GPLv3
11
  * Domain Path: /languages
19
 
20
  define( 'BRIZY_DEVELOPMENT', false );
21
  define( 'BRIZY_LOG', false );
22
+ define( 'BRIZY_VERSION', '2.3.29' );
23
  define( 'BRIZY_MINIMUM_PRO_VERSION', '2.3.0' );
24
  define( 'BRIZY_EDITOR_VERSION', BRIZY_DEVELOPMENT ? 'dev' : '216-wp' );
25
  define( 'BRIZY_SYNC_VERSION', '216' );
compatibilities/complianz-gpdr.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Compatibility with the plugin Complianz – GDPR/CCPA Cookie Consent: https://wordpress.org/plugins/complianz-gdpr/
5
+ */
6
+ class Brizy_Compatibilities_ComplianzGpdr {
7
+
8
+ public function __construct() {
9
+ if ( isset( $_GET[ Brizy_Editor::prefix( '-edit' ) ] ) || isset( $_GET[ Brizy_Editor::prefix( '-edit-iframe' ) ] ) ) {
10
+ add_action( 'template_redirect', [ $this, 'template_redirect' ], 9 );
11
+ add_action( 'shutdown', [ $this, 'shutdown' ], 998 );
12
+ }
13
+ }
14
+
15
+ public function template_redirect() {
16
+ remove_action( 'template_redirect', [ COMPLIANZ::$cookie_blocker, 'start_buffer' ] );
17
+ }
18
+
19
+ public function shutdown() {
20
+ remove_action( 'shutdown', [ COMPLIANZ::$cookie_blocker, 'end_buffer' ], 999 );
21
+ }
22
+ }
compatibilities/init.php CHANGED
@@ -122,6 +122,10 @@ class Brizy_Compatibilities_Init {
122
  if ( defined( 'PERFMATTERS_VERSION' ) ) {
123
  new Brizy_Compatibilities_Perfmatters();
124
  }
 
 
 
 
125
  }
126
 
127
  public function after_setup_theme() {
122
  if ( defined( 'PERFMATTERS_VERSION' ) ) {
123
  new Brizy_Compatibilities_Perfmatters();
124
  }
125
+
126
+ if ( class_exists( 'COMPLIANZ' ) ) {
127
+ new Brizy_Compatibilities_ComplianzGpdr();
128
+ }
129
  }
130
 
131
  public function after_setup_theme() {
compatibilities/wpml.php CHANGED
@@ -6,10 +6,13 @@
6
  class Brizy_Compatibilities_WPML {
7
 
8
  public function __construct() {
9
- add_action( 'wp_insert_post', array( $this, 'insertNewPost' ), - 10000, 3 );
10
- add_action( 'wp_insert_post', array( $this, 'duplicatePosts' ), - 10000, 3 );
11
- add_action( 'pre_get_posts', [ $this, 'pre_get_posts' ], 11 );
12
- add_action( 'wp_ajax_wpml-ls-save-settings', [ $this, 'save_settings' ] );
 
 
 
13
  }
14
 
15
  /**
@@ -18,7 +21,6 @@ class Brizy_Compatibilities_WPML {
18
  * @param $postId
19
  * @param $post
20
  *
21
- * @throws Brizy_Editor_Exceptions_NotFound
22
  */
23
  public function duplicatePosts( $postId, $post ) {
24
  global $wpml_post_translations;
@@ -26,8 +28,12 @@ class Brizy_Compatibilities_WPML {
26
 
27
  if ( isset( $_POST['langs'] ) ) {
28
  if ( $wpml_post_translations && is_post_type_translated( $postType ) ) {
29
- $currentBrizyPost = Brizy_Editor_Post::get( (int) $_POST['post_id'] );
30
- $currentBrizyPost->duplicateTo( (int) $postId );
 
 
 
 
31
  }
32
  }
33
 
@@ -87,4 +93,43 @@ class Brizy_Compatibilities_WPML {
87
 
88
  Brizy_Editor_Post::mark_all_for_compilation();
89
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  }
6
  class Brizy_Compatibilities_WPML {
7
 
8
  public function __construct() {
9
+ add_action( 'wp_insert_post', [ $this, 'insertNewPost' ], - 10000, 3 );
10
+ add_action( 'wp_insert_post', [ $this, 'duplicatePosts' ], - 10000, 3 );
11
+ add_action( 'pre_get_posts', [ $this, 'pre_get_posts' ], 11 );
12
+ add_action( 'wp_ajax_wpml-ls-save-settings', [ $this, 'save_settings' ] );
13
+ add_action( 'wp_ajax_icl_msync_confirm', [ $this, 'syncMenus' ] );
14
+ add_action( 'brizy_create_editor_config_before', [ $this, 'rmMenusDuplicate' ] );
15
+ add_filter( 'brizy_content', [ $this, 'brizyContent' ] );
16
  }
17
 
18
  /**
21
  * @param $postId
22
  * @param $post
23
  *
 
24
  */
25
  public function duplicatePosts( $postId, $post ) {
26
  global $wpml_post_translations;
28
 
29
  if ( isset( $_POST['langs'] ) ) {
30
  if ( $wpml_post_translations && is_post_type_translated( $postType ) ) {
31
+ try {
32
+ $currentBrizyPost = Brizy_Editor_Post::get( (int) $_POST['post_id'] );
33
+ $currentBrizyPost->duplicateTo( (int) $postId );
34
+ } catch ( Exception $e ) {
35
+ return;
36
+ }
37
  }
38
  }
39
 
93
 
94
  Brizy_Editor_Post::mark_all_for_compilation();
95
  }
96
+
97
+ /**
98
+ * On sync menus recompile everything again
99
+ */
100
+ public function syncMenus() {
101
+ Brizy_Editor_Post::mark_all_for_compilation();
102
+ }
103
+
104
+ /**
105
+ * Remove duplicate menus in the editor
106
+ */
107
+ public function rmMenusDuplicate() {
108
+
109
+ $adjustIdUrlCopy = isset( $GLOBALS['icl_adjust_id_url_filter_off'] ) ? $GLOBALS['icl_adjust_id_url_filter_off'] : null;
110
+
111
+ $GLOBALS['icl_adjust_id_url_filter_off'] = true;
112
+
113
+ add_action( 'brizy_create_editor_config_after', function() use ( $adjustIdUrlCopy ) {
114
+ $GLOBALS['icl_adjust_id_url_filter_off'] = $adjustIdUrlCopy;
115
+ } );
116
+ }
117
+
118
+ /**
119
+ * Fix the url of the switcher languages in the menu when we have in the url ?preview_id=postId
120
+ *
121
+ * @param string $content
122
+ *
123
+ * @return string
124
+ */
125
+ public function brizyContent( $content ) {
126
+
127
+ if ( ! is_preview() ) {
128
+ return $content;
129
+ }
130
+
131
+ add_action( 'wpml_should_filter_preview_lang', '__return_false' );
132
+
133
+ return $content;
134
+ }
135
  }
config.php CHANGED
@@ -29,7 +29,7 @@ class Brizy_Config {
29
  const GO_PRO_DASHBOARD_URL = "https://www.brizy.io/brizy-pro-pricing/?utm_source=wp-menu&utm_campaign=gopro&utm_medium=wp-dash/";
30
 
31
  const EDITOR_BUILD_PATH = BRIZY_PLUGIN_PATH . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'editor-build' . DIRECTORY_SEPARATOR . BRIZY_EDITOR_VERSION;
32
- const EDITOR_BUILD_URL = BRIZY_PLUGIN_URL . '/public/editor-build/' . BRIZY_EDITOR_VERSION;
33
 
34
  const CLOUD_APP_KEY = 'YTVhMDEwMGUyNGE4OTQ5OWM2NTY3OGM3N2MxNzMzMTBjOWVlNTg0OGM0NWU1NGYzY2QxMGEzOWQ3NWNjMDk3Zg';
35
  const CLOUD_ENDPOINT = 'https://www.brizy.cloud';
29
  const GO_PRO_DASHBOARD_URL = "https://www.brizy.io/brizy-pro-pricing/?utm_source=wp-menu&utm_campaign=gopro&utm_medium=wp-dash/";
30
 
31
  const EDITOR_BUILD_PATH = BRIZY_PLUGIN_PATH . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'editor-build' . DIRECTORY_SEPARATOR . BRIZY_EDITOR_VERSION;
32
+ const EDITOR_BUILD_RELATIVE_PATH = 'public/editor-build/' . BRIZY_EDITOR_VERSION;
33
 
34
  const CLOUD_APP_KEY = 'YTVhMDEwMGUyNGE4OTQ5OWM2NTY3OGM3N2MxNzMzMTBjOWVlNTg0OGM0NWU1NGYzY2QxMGEzOWQ3NWNjMDk3Zg';
35
  const CLOUD_ENDPOINT = 'https://www.brizy.cloud';
editor/editor/editor.php CHANGED
@@ -116,7 +116,7 @@ class Brizy_Editor_Editor_Editor
116
  'urls' => array(
117
  'site' => home_url(),
118
  'api' => home_url('/wp-json/v1'),
119
- 'assets' => $context == self::COMPILE_CONTEXT?Brizy_SiteUrlReplacer::hideSiteUrl($this->urlBuilder->editor_build_url()):$this->urlBuilder->editor_build_url(),
120
  'image' => $this->urlBuilder->external_media_url() . "",
121
  'blockThumbnails' => $this->urlBuilder->external_asset_url('thumbs') . "",
122
  'templateThumbnails' => $this->urlBuilder->external_asset_url('thumbs') . "",
116
  'urls' => array(
117
  'site' => home_url(),
118
  'api' => home_url('/wp-json/v1'),
119
+ 'assets' => $context == self::COMPILE_CONTEXT ? Brizy_Config::EDITOR_BUILD_RELATIVE_PATH : $this->urlBuilder->editor_build_url(),
120
  'image' => $this->urlBuilder->external_media_url() . "",
121
  'blockThumbnails' => $this->urlBuilder->external_asset_url('thumbs') . "",
122
  'templateThumbnails' => $this->urlBuilder->external_asset_url('thumbs') . "",
editor/post.php CHANGED
@@ -319,47 +319,6 @@ class Brizy_Editor_Post extends Brizy_Editor_Entity {
319
  $compiledData = Brizy_Editor_User::get()->compile_page( Brizy_Editor_Project::get(), $this );
320
  $compiledData['pageHtml'] = Brizy_SiteUrlReplacer::hideSiteUrl( $compiledData['pageHtml'] );
321
 
322
- foreach ( $compiledData['pageScripts'] as $i => $set ) { //pro || free
323
- foreach ( $set as $k => $scripts ) { // groups
324
- if ( $k == 'libsSelectors' ) {
325
- continue;
326
- }
327
- if ( $k == 'main' ) {
328
- if ( isset( $compiledData['pageScripts'][ $i ][ $k ]['content']['url'] ) ) {
329
- $compiledData['pageScripts'][ $i ][ $k ]['content']['url'] = Brizy_SiteUrlReplacer::hideSiteUrl( $compiledData['pageScripts'][ $i ][ $k ]['content']['url'] );
330
- continue;
331
- }
332
- }
333
-
334
- foreach ( $scripts as $l => $script ) {
335
- if ( isset( $compiledData['pageScripts'][ $i ][ $k ][ $l ]['content']['url'] ) ) {
336
- $compiledData['pageScripts'][ $i ][ $k ][ $l ]['content']['url'] = Brizy_SiteUrlReplacer::hideSiteUrl( $script['content']['url'] );
337
- }
338
- }
339
-
340
- }
341
- }
342
- foreach ( $compiledData['pageStyles'] as $i => $set ) {
343
- foreach ( $set as $k => $styles ) {
344
- if ( $k == 'libsSelectors' ) {
345
- continue;
346
- }
347
- if ( $k == 'main' ) {
348
- if ( isset( $compiledData['pageStyles'][ $i ][ $k ]['content']['url'] ) ) {
349
- $compiledData['pageStyles'][ $i ][ $k ]['content']['url'] = Brizy_SiteUrlReplacer::hideSiteUrl( $compiledData['pageStyles'][ $i ][ $k ]['content']['url'] );
350
- }
351
- continue;
352
- }
353
- foreach ( $styles as $l => $style ) {
354
- if ( isset( $compiledData['pageStyles'][ $i ][ $k ][ $l ]['content']['url'] ) ) {
355
- $compiledData['pageStyles'][ $i ][ $k ][ $l ]['content']['url'] = Brizy_SiteUrlReplacer::hideSiteUrl(
356
- $style['content']['url']
357
- );
358
- }
359
- }
360
- }
361
- }
362
-
363
  $this->set_compiled_html( $compiledData['pageHtml'] );
364
  $this->set_compiled_html_head( null );
365
  $this->set_compiled_html_body( null );
319
  $compiledData = Brizy_Editor_User::get()->compile_page( Brizy_Editor_Project::get(), $this );
320
  $compiledData['pageHtml'] = Brizy_SiteUrlReplacer::hideSiteUrl( $compiledData['pageHtml'] );
321
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
322
  $this->set_compiled_html( $compiledData['pageHtml'] );
323
  $this->set_compiled_html_head( null );
324
  $this->set_compiled_html_body( null );
editor/url-builder.php CHANGED
@@ -60,7 +60,6 @@ class Brizy_Editor_UrlBuilder
60
  */
61
  public function plugin_url($path = '')
62
  {
63
-
64
  if ($path) {
65
  $path = '/' . ltrim($path, '/');
66
  }
@@ -302,13 +301,17 @@ class Brizy_Editor_UrlBuilder
302
  }
303
 
304
  /**
305
- * @param null $path
306
  *
307
  * @return string
308
  */
309
- public function editor_build_url()
310
  {
311
- return Brizy_Config::EDITOR_BUILD_URL;
 
 
 
 
312
  }
313
 
314
  /**
60
  */
61
  public function plugin_url($path = '')
62
  {
 
63
  if ($path) {
64
  $path = '/' . ltrim($path, '/');
65
  }
301
  }
302
 
303
  /**
304
+ * @param string $path
305
  *
306
  * @return string
307
  */
308
+ public function editor_build_url( $path = '' )
309
  {
310
+ if ( $path ) {
311
+ $path = '/' . ltrim( $path, '/' );
312
+ }
313
+
314
+ return $this->plugin_url( Brizy_Config::EDITOR_BUILD_RELATIVE_PATH . $path );
315
  }
316
 
317
  /**
public/asset-enqueue-manager.php CHANGED
@@ -11,6 +11,7 @@ class Brizy_Public_AssetEnqueueManager {
11
  private $enqueued = [];
12
  private $mainJsHandle = null;
13
  private $mainCssHandle = null;
 
14
 
15
  /**
16
  * @var Brizy_Editor_Project
@@ -31,7 +32,9 @@ class Brizy_Public_AssetEnqueueManager {
31
  * @throws Exception
32
  */
33
  private function __construct() {
34
- $this->project = Brizy_Editor_Project::get();
 
 
35
  $this->registerActions();
36
  }
37
 
@@ -214,7 +217,7 @@ class Brizy_Public_AssetEnqueueManager {
214
  $this->enqueued[ $handle ] = $asset;
215
  break;
216
  case Asset::TYPE_FILE:
217
- wp_register_style( $handle, Brizy_SiteUrlReplacer::restoreAssetUrl( $asset->getUrl() ), [], BRIZY_VERSION );
218
  wp_enqueue_style( $handle );
219
  $this->enqueued[ $handle ] = $asset;
220
  break;
@@ -229,13 +232,22 @@ class Brizy_Public_AssetEnqueueManager {
229
  $this->enqueued[ $handle ] = $asset;
230
  break;
231
  case Asset::TYPE_FILE:
232
- wp_register_script( $handle, Brizy_SiteUrlReplacer::restoreAssetUrl( $asset->getUrl() ), [], BRIZY_VERSION, true );
233
  wp_enqueue_script( $handle );
234
  $this->enqueued[ $handle ] = $asset;
235
  break;
236
  }
237
  }
238
 
 
 
 
 
 
 
 
 
 
239
  private function getAttributes( $asset ) {
240
  $attrs = $asset->getAttrs();
241
 
11
  private $enqueued = [];
12
  private $mainJsHandle = null;
13
  private $mainCssHandle = null;
14
+ private $urlBuilder;
15
 
16
  /**
17
  * @var Brizy_Editor_Project
32
  * @throws Exception
33
  */
34
  private function __construct() {
35
+ $this->project = Brizy_Editor_Project::get();
36
+ $this->urlBuilder = new Brizy_Editor_UrlBuilder( $this->project );
37
+
38
  $this->registerActions();
39
  }
40
 
217
  $this->enqueued[ $handle ] = $asset;
218
  break;
219
  case Asset::TYPE_FILE:
220
+ wp_register_style( $handle, $this->getAssetUrl( $asset ), [], apply_filters( 'brizy_asset_version', BRIZY_VERSION, $asset ) );
221
  wp_enqueue_style( $handle );
222
  $this->enqueued[ $handle ] = $asset;
223
  break;
232
  $this->enqueued[ $handle ] = $asset;
233
  break;
234
  case Asset::TYPE_FILE:
235
+ wp_register_script( $handle, $this->getAssetUrl( $asset ), [], apply_filters( 'brizy_asset_version', BRIZY_VERSION, $asset ), true );
236
  wp_enqueue_script( $handle );
237
  $this->enqueued[ $handle ] = $asset;
238
  break;
239
  }
240
  }
241
 
242
+ private function getAssetUrl( Asset $asset ) {
243
+
244
+ if ( strpos( $asset->getUrl(), '://' ) ) {
245
+ return $asset->getUrl();
246
+ }
247
+
248
+ return apply_filters( 'brizy_asset_url', $this->urlBuilder->plugin_url( $asset->getUrl() ), $asset );
249
+ }
250
+
251
  private function getAttributes( $asset ) {
252
  $attrs = $asset->getAttrs();
253
 
public/main.php CHANGED
@@ -484,7 +484,7 @@ class Brizy_Public_Main
484
 
485
  public function brizy_the_content()
486
  {
487
- echo $this->insert_page_content( 'brz-root__container' );
488
  }
489
 
490
  /**
484
 
485
  public function brizy_the_content()
486
  {
487
+ echo do_shortcode( $this->insert_page_content( 'brz-root__container' ) );
488
  }
489
 
490
  /**
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: themefuse
3
  Tags: page builder, website builder, brizy, editor, visual editor, unyson, wysiwyg, landing page, drag-and-drop, design, landing page builder, front-end builder
4
  Requires at least: 4.5
5
- Tested up to: 5.8.3
6
  Requires PHP: 5.6.20
7
- Stable tag: 2.3.28
8
  License: GPLv3
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
10
 
@@ -133,6 +133,15 @@ Don't worry if you make a mistake or delete something that you shouldn't have. W
133
 
134
  == Changelog ==
135
 
 
 
 
 
 
 
 
 
 
136
  = 2.3.28 - 2022-01-17 =
137
  * Fixed: Color and align for text element
138
 
2
  Contributors: themefuse
3
  Tags: page builder, website builder, brizy, editor, visual editor, unyson, wysiwyg, landing page, drag-and-drop, design, landing page builder, front-end builder
4
  Requires at least: 4.5
5
+ Tested up to: 5.9
6
  Requires PHP: 5.6.20
7
+ Stable tag: 2.3.29
8
  License: GPLv3
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
10
 
133
 
134
  == Changelog ==
135
 
136
+ = 2.3.29 - 2022-02-03 =
137
+ * Fixed: Font url validation
138
+ * Fixed: Do shortcode on render brizy content of the shop page
139
+ * Fixed: Brizy and Complianz – GDPR/CCPA Cookie Consent plugin incompatibility
140
+ * Fixed: Saves scripts relative to the plugin main folder
141
+ * Fixed: WPML menu switcher, WPML sync menu, WPML fatal error on duplicate non brizy posts
142
+ * Fixed: Brizy Overview dashboard widget
143
+ * Fixed: Allow br tags on render lead list in admin dashboard
144
+
145
  = 2.3.28 - 2022-01-17 =
146
  * Fixed: Color and align for text element
147
 
site-url-replacer.php CHANGED
@@ -27,8 +27,4 @@ class Brizy_SiteUrlReplacer {
27
 
28
  return $content;
29
  }
30
-
31
- static public function restoreAssetUrl( $content ) {
32
- return preg_replace( Brizy_Config::SITE_URL_PLACEHOLDER_REGEX, get_option( 'siteurl' ), $content );
33
- }
34
  }
27
 
28
  return $content;
29
  }
 
 
 
 
30
  }
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit8df122e148193c2171d6337ed219aed3::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit8b84a909a3a5e9e0bfd5aa98543940db::getLoader();
vendor/bagrinsergiu/content-placeholder/lib/Extractor.php CHANGED
@@ -27,6 +27,7 @@ final class Extractor
27
  */
28
  public function __construct($registry)
29
  {
 
30
  $this->registry = $registry;
31
  }
32
 
27
  */
28
  public function __construct($registry)
29
  {
30
+ @ini_set('pcre.backtrack_limit', "2000000");
31
  $this->registry = $registry;
32
  }
33
 
vendor/composer/InstalledVersions.php CHANGED
@@ -30,7 +30,7 @@ private static $installed = array (
30
  'aliases' =>
31
  array (
32
  ),
33
- 'reference' => 'eb4df66ec3586a3de3657544bd1552b12a85828b',
34
  'name' => 'brizy/brizy',
35
  ),
36
  'versions' =>
@@ -56,12 +56,12 @@ private static $installed = array (
56
  ),
57
  'bagrinsergiu/content-placeholder' =>
58
  array (
59
- 'pretty_version' => '2.0.5',
60
- 'version' => '2.0.5.0',
61
  'aliases' =>
62
  array (
63
  ),
64
- 'reference' => '3be1d4e2033c6c074f12391fc796e5ab9a9bc72d',
65
  ),
66
  'brizy/brizy' =>
67
  array (
@@ -70,7 +70,7 @@ private static $installed = array (
70
  'aliases' =>
71
  array (
72
  ),
73
- 'reference' => 'eb4df66ec3586a3de3657544bd1552b12a85828b',
74
  ),
75
  'enshrined/svg-sanitize' =>
76
  array (
@@ -107,15 +107,14 @@ private static $installed = array (
107
  array (
108
  0 => '9999999-dev',
109
  ),
110
- 'reference' => '940c299b7a449d6621103c195d7094b1976861a7',
111
  ),
112
  'symfony/deprecation-contracts' =>
113
  array (
114
- 'pretty_version' => 'dev-main',
115
- 'version' => 'dev-main',
116
  'aliases' =>
117
  array (
118
- 0 => '2.5.x-dev',
119
  ),
120
  'reference' => '6f981ee24cf69ee7ce9736146d1c57c2780598a8',
121
  ),
@@ -125,18 +124,18 @@ private static $installed = array (
125
  'version' => '5.4.9999999.9999999-dev',
126
  'aliases' =>
127
  array (
 
128
  ),
129
- 'reference' => '7189ac0d3f99c7526950f13ff337d2b9a2bedf21',
130
  ),
131
  'symfony/polyfill-ctype' =>
132
  array (
133
- 'pretty_version' => 'dev-main',
134
- 'version' => 'dev-main',
135
  'aliases' =>
136
  array (
137
- 0 => '1.23.x-dev',
138
  ),
139
- 'reference' => '46cd95797e9df938fdd2b03693b5fca5e64b01ce',
140
  ),
141
  'tburry/pquery' =>
142
  array (
30
  'aliases' =>
31
  array (
32
  ),
33
+ 'reference' => '1637a056c167acf3bcd27851edd4c0a44c74f979',
34
  'name' => 'brizy/brizy',
35
  ),
36
  'versions' =>
56
  ),
57
  'bagrinsergiu/content-placeholder' =>
58
  array (
59
+ 'pretty_version' => '2.0.6',
60
+ 'version' => '2.0.6.0',
61
  'aliases' =>
62
  array (
63
  ),
64
+ 'reference' => 'ba8b64a6055615b2294f2b575e303fb3b0331d7e',
65
  ),
66
  'brizy/brizy' =>
67
  array (
70
  'aliases' =>
71
  array (
72
  ),
73
+ 'reference' => '1637a056c167acf3bcd27851edd4c0a44c74f979',
74
  ),
75
  'enshrined/svg-sanitize' =>
76
  array (
107
  array (
108
  0 => '9999999-dev',
109
  ),
110
+ 'reference' => '3ce73d6d5c11031579bb036d7059b570b00e2255',
111
  ),
112
  'symfony/deprecation-contracts' =>
113
  array (
114
+ 'pretty_version' => '2.5.x-dev',
115
+ 'version' => '2.5.9999999.9999999-dev',
116
  'aliases' =>
117
  array (
 
118
  ),
119
  'reference' => '6f981ee24cf69ee7ce9736146d1c57c2780598a8',
120
  ),
124
  'version' => '5.4.9999999.9999999-dev',
125
  'aliases' =>
126
  array (
127
+ 0 => '9999999-dev',
128
  ),
129
+ 'reference' => '84d1af2d39dd81b48eb1cd3af3f107eea7a275bb',
130
  ),
131
  'symfony/polyfill-ctype' =>
132
  array (
133
+ 'pretty_version' => 'v1.24.0',
134
+ 'version' => '1.24.0.0',
135
  'aliases' =>
136
  array (
 
137
  ),
138
+ 'reference' => '30885182c981ab175d4d034db0f6f469898070ab',
139
  ),
140
  'tburry/pquery' =>
141
  array (
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit8df122e148193c2171d6337ed219aed3
6
  {
7
  private static $loader;
8
 
@@ -22,15 +22,15 @@ class ComposerAutoloaderInit8df122e148193c2171d6337ed219aed3
22
  return self::$loader;
23
  }
24
 
25
- spl_autoload_register(array('ComposerAutoloaderInit8df122e148193c2171d6337ed219aed3', 'loadClassLoader'), true, true);
26
  self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
27
- spl_autoload_unregister(array('ComposerAutoloaderInit8df122e148193c2171d6337ed219aed3', 'loadClassLoader'));
28
 
29
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
  if ($useStaticLoader) {
31
  require __DIR__ . '/autoload_static.php';
32
 
33
- call_user_func(\Composer\Autoload\ComposerStaticInit8df122e148193c2171d6337ed219aed3::getInitializer($loader));
34
  } else {
35
  $map = require __DIR__ . '/autoload_namespaces.php';
36
  foreach ($map as $namespace => $path) {
@@ -51,19 +51,19 @@ class ComposerAutoloaderInit8df122e148193c2171d6337ed219aed3
51
  $loader->register(true);
52
 
53
  if ($useStaticLoader) {
54
- $includeFiles = Composer\Autoload\ComposerStaticInit8df122e148193c2171d6337ed219aed3::$files;
55
  } else {
56
  $includeFiles = require __DIR__ . '/autoload_files.php';
57
  }
58
  foreach ($includeFiles as $fileIdentifier => $file) {
59
- composerRequire8df122e148193c2171d6337ed219aed3($fileIdentifier, $file);
60
  }
61
 
62
  return $loader;
63
  }
64
  }
65
 
66
- function composerRequire8df122e148193c2171d6337ed219aed3($fileIdentifier, $file)
67
  {
68
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
69
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit8b84a909a3a5e9e0bfd5aa98543940db
6
  {
7
  private static $loader;
8
 
22
  return self::$loader;
23
  }
24
 
25
+ spl_autoload_register(array('ComposerAutoloaderInit8b84a909a3a5e9e0bfd5aa98543940db', 'loadClassLoader'), true, true);
26
  self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
27
+ spl_autoload_unregister(array('ComposerAutoloaderInit8b84a909a3a5e9e0bfd5aa98543940db', 'loadClassLoader'));
28
 
29
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
  if ($useStaticLoader) {
31
  require __DIR__ . '/autoload_static.php';
32
 
33
+ call_user_func(\Composer\Autoload\ComposerStaticInit8b84a909a3a5e9e0bfd5aa98543940db::getInitializer($loader));
34
  } else {
35
  $map = require __DIR__ . '/autoload_namespaces.php';
36
  foreach ($map as $namespace => $path) {
51
  $loader->register(true);
52
 
53
  if ($useStaticLoader) {
54
+ $includeFiles = Composer\Autoload\ComposerStaticInit8b84a909a3a5e9e0bfd5aa98543940db::$files;
55
  } else {
56
  $includeFiles = require __DIR__ . '/autoload_files.php';
57
  }
58
  foreach ($includeFiles as $fileIdentifier => $file) {
59
+ composerRequire8b84a909a3a5e9e0bfd5aa98543940db($fileIdentifier, $file);
60
  }
61
 
62
  return $loader;
63
  }
64
  }
65
 
66
+ function composerRequire8b84a909a3a5e9e0bfd5aa98543940db($fileIdentifier, $file)
67
  {
68
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
69
  require $file;
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit8df122e148193c2171d6337ed219aed3
8
  {
9
  public static $files = array (
10
  '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
@@ -126,10 +126,10 @@ class ComposerStaticInit8df122e148193c2171d6337ed219aed3
126
  public static function getInitializer(ClassLoader $loader)
127
  {
128
  return \Closure::bind(function () use ($loader) {
129
- $loader->prefixLengthsPsr4 = ComposerStaticInit8df122e148193c2171d6337ed219aed3::$prefixLengthsPsr4;
130
- $loader->prefixDirsPsr4 = ComposerStaticInit8df122e148193c2171d6337ed219aed3::$prefixDirsPsr4;
131
- $loader->prefixesPsr0 = ComposerStaticInit8df122e148193c2171d6337ed219aed3::$prefixesPsr0;
132
- $loader->classMap = ComposerStaticInit8df122e148193c2171d6337ed219aed3::$classMap;
133
 
134
  }, null, ClassLoader::class);
135
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit8b84a909a3a5e9e0bfd5aa98543940db
8
  {
9
  public static $files = array (
10
  '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
126
  public static function getInitializer(ClassLoader $loader)
127
  {
128
  return \Closure::bind(function () use ($loader) {
129
+ $loader->prefixLengthsPsr4 = ComposerStaticInit8b84a909a3a5e9e0bfd5aa98543940db::$prefixLengthsPsr4;
130
+ $loader->prefixDirsPsr4 = ComposerStaticInit8b84a909a3a5e9e0bfd5aa98543940db::$prefixDirsPsr4;
131
+ $loader->prefixesPsr0 = ComposerStaticInit8b84a909a3a5e9e0bfd5aa98543940db::$prefixesPsr0;
132
+ $loader->classMap = ComposerStaticInit8b84a909a3a5e9e0bfd5aa98543940db::$classMap;
133
 
134
  }, null, ClassLoader::class);
135
  }
vendor/composer/installed.json CHANGED
@@ -89,17 +89,17 @@
89
  },
90
  {
91
  "name": "bagrinsergiu/content-placeholder",
92
- "version": "2.0.5",
93
- "version_normalized": "2.0.5.0",
94
  "source": {
95
  "type": "git",
96
  "url": "https://github.com/bagrinsergiu/brizy-content-placeholder.git",
97
- "reference": "3be1d4e2033c6c074f12391fc796e5ab9a9bc72d"
98
  },
99
  "dist": {
100
  "type": "zip",
101
- "url": "https://api.github.com/repos/bagrinsergiu/brizy-content-placeholder/zipball/3be1d4e2033c6c074f12391fc796e5ab9a9bc72d",
102
- "reference": "3be1d4e2033c6c074f12391fc796e5ab9a9bc72d",
103
  "shasum": ""
104
  },
105
  "require": {
@@ -109,7 +109,7 @@
109
  "phpspec/prophecy-phpunit": "^2.0",
110
  "phpunit/phpunit": "^9.4"
111
  },
112
- "time": "2021-07-29T08:06:01+00:00",
113
  "type": "library",
114
  "installation-source": "dist",
115
  "autoload": {
@@ -125,7 +125,7 @@
125
  "placeholders"
126
  ],
127
  "support": {
128
- "source": "https://github.com/bagrinsergiu/brizy-content-placeholder/tree/2.0.5",
129
  "issues": "https://github.com/bagrinsergiu/brizy-content-placeholder/issues"
130
  },
131
  "install-path": "../bagrinsergiu/content-placeholder"
@@ -322,12 +322,12 @@
322
  "source": {
323
  "type": "git",
324
  "url": "https://github.com/short-pixel-optimizer/shortpixel-php.git",
325
- "reference": "940c299b7a449d6621103c195d7094b1976861a7"
326
  },
327
  "dist": {
328
  "type": "zip",
329
- "url": "https://api.github.com/repos/short-pixel-optimizer/shortpixel-php/zipball/940c299b7a449d6621103c195d7094b1976861a7",
330
- "reference": "940c299b7a449d6621103c195d7094b1976861a7",
331
  "shasum": ""
332
  },
333
  "require": {
@@ -340,8 +340,11 @@
340
  "phpunit/phpunit": "~4.0",
341
  "symfony/yaml": "~2.0"
342
  },
343
- "time": "2021-08-29T05:07:47+00:00",
344
  "default-branch": true,
 
 
 
345
  "type": "library",
346
  "installation-source": "source",
347
  "autoload": {
@@ -375,14 +378,14 @@
375
  "support": {
376
  "email": "support@shortpixel.com",
377
  "issues": "https://github.com/short-pixel-optimizer/shortpixel-php/issues",
378
- "source": "https://github.com/short-pixel-optimizer/shortpixel-php/tree/master"
379
  },
380
  "install-path": "../shortpixel/shortpixel-php"
381
  },
382
  {
383
  "name": "symfony/deprecation-contracts",
384
- "version": "dev-main",
385
- "version_normalized": "dev-main",
386
  "source": {
387
  "type": "git",
388
  "url": "https://github.com/symfony/deprecation-contracts.git",
@@ -398,7 +401,6 @@
398
  "php": ">=7.1"
399
  },
400
  "time": "2021-07-12T14:48:14+00:00",
401
- "default-branch": true,
402
  "type": "library",
403
  "extra": {
404
  "branch-alias": {
@@ -457,22 +459,24 @@
457
  "source": {
458
  "type": "git",
459
  "url": "https://github.com/symfony/dotenv.git",
460
- "reference": "7189ac0d3f99c7526950f13ff337d2b9a2bedf21"
461
  },
462
  "dist": {
463
  "type": "zip",
464
- "url": "https://api.github.com/repos/symfony/dotenv/zipball/7189ac0d3f99c7526950f13ff337d2b9a2bedf21",
465
- "reference": "7189ac0d3f99c7526950f13ff337d2b9a2bedf21",
466
  "shasum": ""
467
  },
468
  "require": {
469
  "php": ">=7.2.5",
470
- "symfony/deprecation-contracts": "^2.1"
471
  },
472
  "require-dev": {
 
473
  "symfony/process": "^4.4|^5.0|^6.0"
474
  },
475
- "time": "2021-08-17T14:20:01+00:00",
 
476
  "type": "library",
477
  "installation-source": "source",
478
  "autoload": {
@@ -505,7 +509,7 @@
505
  "environment"
506
  ],
507
  "support": {
508
- "source": "https://github.com/symfony/dotenv/tree/5.4"
509
  },
510
  "funding": [
511
  {
@@ -525,27 +529,29 @@
525
  },
526
  {
527
  "name": "symfony/polyfill-ctype",
528
- "version": "dev-main",
529
- "version_normalized": "dev-main",
530
  "source": {
531
  "type": "git",
532
  "url": "https://github.com/symfony/polyfill-ctype.git",
533
- "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce"
534
  },
535
  "dist": {
536
  "type": "zip",
537
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce",
538
- "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce",
539
  "shasum": ""
540
  },
541
  "require": {
542
  "php": ">=7.1"
543
  },
 
 
 
544
  "suggest": {
545
  "ext-ctype": "For best performance"
546
  },
547
- "time": "2021-02-19T12:13:01+00:00",
548
- "default-branch": true,
549
  "type": "library",
550
  "extra": {
551
  "branch-alias": {
@@ -556,7 +562,7 @@
556
  "url": "https://github.com/symfony/polyfill"
557
  }
558
  },
559
- "installation-source": "source",
560
  "autoload": {
561
  "psr-4": {
562
  "Symfony\\Polyfill\\Ctype\\": ""
@@ -588,7 +594,7 @@
588
  "portable"
589
  ],
590
  "support": {
591
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0"
592
  },
593
  "funding": [
594
  {
89
  },
90
  {
91
  "name": "bagrinsergiu/content-placeholder",
92
+ "version": "2.0.6",
93
+ "version_normalized": "2.0.6.0",
94
  "source": {
95
  "type": "git",
96
  "url": "https://github.com/bagrinsergiu/brizy-content-placeholder.git",
97
+ "reference": "ba8b64a6055615b2294f2b575e303fb3b0331d7e"
98
  },
99
  "dist": {
100
  "type": "zip",
101
+ "url": "https://api.github.com/repos/bagrinsergiu/brizy-content-placeholder/zipball/ba8b64a6055615b2294f2b575e303fb3b0331d7e",
102
+ "reference": "ba8b64a6055615b2294f2b575e303fb3b0331d7e",
103
  "shasum": ""
104
  },
105
  "require": {
109
  "phpspec/prophecy-phpunit": "^2.0",
110
  "phpunit/phpunit": "^9.4"
111
  },
112
+ "time": "2021-12-22T12:23:25+00:00",
113
  "type": "library",
114
  "installation-source": "dist",
115
  "autoload": {
125
  "placeholders"
126
  ],
127
  "support": {
128
+ "source": "https://github.com/bagrinsergiu/brizy-content-placeholder/tree/2.0.6",
129
  "issues": "https://github.com/bagrinsergiu/brizy-content-placeholder/issues"
130
  },
131
  "install-path": "../bagrinsergiu/content-placeholder"
322
  "source": {
323
  "type": "git",
324
  "url": "https://github.com/short-pixel-optimizer/shortpixel-php.git",
325
+ "reference": "3ce73d6d5c11031579bb036d7059b570b00e2255"
326
  },
327
  "dist": {
328
  "type": "zip",
329
+ "url": "https://api.github.com/repos/short-pixel-optimizer/shortpixel-php/zipball/3ce73d6d5c11031579bb036d7059b570b00e2255",
330
+ "reference": "3ce73d6d5c11031579bb036d7059b570b00e2255",
331
  "shasum": ""
332
  },
333
  "require": {
340
  "phpunit/phpunit": "~4.0",
341
  "symfony/yaml": "~2.0"
342
  },
343
+ "time": "2021-11-24T17:05:21+00:00",
344
  "default-branch": true,
345
+ "bin": [
346
+ "bin/shortpixel"
347
+ ],
348
  "type": "library",
349
  "installation-source": "source",
350
  "autoload": {
378
  "support": {
379
  "email": "support@shortpixel.com",
380
  "issues": "https://github.com/short-pixel-optimizer/shortpixel-php/issues",
381
+ "source": "https://github.com/short-pixel-optimizer/shortpixel-php/tree/v1.8.7"
382
  },
383
  "install-path": "../shortpixel/shortpixel-php"
384
  },
385
  {
386
  "name": "symfony/deprecation-contracts",
387
+ "version": "2.5.x-dev",
388
+ "version_normalized": "2.5.9999999.9999999-dev",
389
  "source": {
390
  "type": "git",
391
  "url": "https://github.com/symfony/deprecation-contracts.git",
401
  "php": ">=7.1"
402
  },
403
  "time": "2021-07-12T14:48:14+00:00",
 
404
  "type": "library",
405
  "extra": {
406
  "branch-alias": {
459
  "source": {
460
  "type": "git",
461
  "url": "https://github.com/symfony/dotenv.git",
462
+ "reference": "84d1af2d39dd81b48eb1cd3af3f107eea7a275bb"
463
  },
464
  "dist": {
465
  "type": "zip",
466
+ "url": "https://api.github.com/repos/symfony/dotenv/zipball/84d1af2d39dd81b48eb1cd3af3f107eea7a275bb",
467
+ "reference": "84d1af2d39dd81b48eb1cd3af3f107eea7a275bb",
468
  "shasum": ""
469
  },
470
  "require": {
471
  "php": ">=7.2.5",
472
+ "symfony/deprecation-contracts": "^2.1|^3"
473
  },
474
  "require-dev": {
475
+ "symfony/console": "^4.4|^5.0|^6.0",
476
  "symfony/process": "^4.4|^5.0|^6.0"
477
  },
478
+ "time": "2022-01-26T16:19:10+00:00",
479
+ "default-branch": true,
480
  "type": "library",
481
  "installation-source": "source",
482
  "autoload": {
509
  "environment"
510
  ],
511
  "support": {
512
+ "source": "https://github.com/symfony/dotenv/tree/v5.4.3"
513
  },
514
  "funding": [
515
  {
529
  },
530
  {
531
  "name": "symfony/polyfill-ctype",
532
+ "version": "v1.24.0",
533
+ "version_normalized": "1.24.0.0",
534
  "source": {
535
  "type": "git",
536
  "url": "https://github.com/symfony/polyfill-ctype.git",
537
+ "reference": "30885182c981ab175d4d034db0f6f469898070ab"
538
  },
539
  "dist": {
540
  "type": "zip",
541
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab",
542
+ "reference": "30885182c981ab175d4d034db0f6f469898070ab",
543
  "shasum": ""
544
  },
545
  "require": {
546
  "php": ">=7.1"
547
  },
548
+ "provide": {
549
+ "ext-ctype": "*"
550
+ },
551
  "suggest": {
552
  "ext-ctype": "For best performance"
553
  },
554
+ "time": "2021-10-20T20:35:02+00:00",
 
555
  "type": "library",
556
  "extra": {
557
  "branch-alias": {
562
  "url": "https://github.com/symfony/polyfill"
563
  }
564
  },
565
+ "installation-source": "dist",
566
  "autoload": {
567
  "psr-4": {
568
  "Symfony\\Polyfill\\Ctype\\": ""
594
  "portable"
595
  ],
596
  "support": {
597
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0"
598
  },
599
  "funding": [
600
  {
vendor/composer/installed.php CHANGED
@@ -6,7 +6,7 @@
6
  'aliases' =>
7
  array (
8
  ),
9
- 'reference' => 'eb4df66ec3586a3de3657544bd1552b12a85828b',
10
  'name' => 'brizy/brizy',
11
  ),
12
  'versions' =>
@@ -32,12 +32,12 @@
32
  ),
33
  'bagrinsergiu/content-placeholder' =>
34
  array (
35
- 'pretty_version' => '2.0.5',
36
- 'version' => '2.0.5.0',
37
  'aliases' =>
38
  array (
39
  ),
40
- 'reference' => '3be1d4e2033c6c074f12391fc796e5ab9a9bc72d',
41
  ),
42
  'brizy/brizy' =>
43
  array (
@@ -46,7 +46,7 @@
46
  'aliases' =>
47
  array (
48
  ),
49
- 'reference' => 'eb4df66ec3586a3de3657544bd1552b12a85828b',
50
  ),
51
  'enshrined/svg-sanitize' =>
52
  array (
@@ -83,15 +83,14 @@
83
  array (
84
  0 => '9999999-dev',
85
  ),
86
- 'reference' => '940c299b7a449d6621103c195d7094b1976861a7',
87
  ),
88
  'symfony/deprecation-contracts' =>
89
  array (
90
- 'pretty_version' => 'dev-main',
91
- 'version' => 'dev-main',
92
  'aliases' =>
93
  array (
94
- 0 => '2.5.x-dev',
95
  ),
96
  'reference' => '6f981ee24cf69ee7ce9736146d1c57c2780598a8',
97
  ),
@@ -101,18 +100,18 @@
101
  'version' => '5.4.9999999.9999999-dev',
102
  'aliases' =>
103
  array (
 
104
  ),
105
- 'reference' => '7189ac0d3f99c7526950f13ff337d2b9a2bedf21',
106
  ),
107
  'symfony/polyfill-ctype' =>
108
  array (
109
- 'pretty_version' => 'dev-main',
110
- 'version' => 'dev-main',
111
  'aliases' =>
112
  array (
113
- 0 => '1.23.x-dev',
114
  ),
115
- 'reference' => '46cd95797e9df938fdd2b03693b5fca5e64b01ce',
116
  ),
117
  'tburry/pquery' =>
118
  array (
6
  'aliases' =>
7
  array (
8
  ),
9
+ 'reference' => '1637a056c167acf3bcd27851edd4c0a44c74f979',
10
  'name' => 'brizy/brizy',
11
  ),
12
  'versions' =>
32
  ),
33
  'bagrinsergiu/content-placeholder' =>
34
  array (
35
+ 'pretty_version' => '2.0.6',
36
+ 'version' => '2.0.6.0',
37
  'aliases' =>
38
  array (
39
  ),
40
+ 'reference' => 'ba8b64a6055615b2294f2b575e303fb3b0331d7e',
41
  ),
42
  'brizy/brizy' =>
43
  array (
46
  'aliases' =>
47
  array (
48
  ),
49
+ 'reference' => '1637a056c167acf3bcd27851edd4c0a44c74f979',
50
  ),
51
  'enshrined/svg-sanitize' =>
52
  array (
83
  array (
84
  0 => '9999999-dev',
85
  ),
86
+ 'reference' => '3ce73d6d5c11031579bb036d7059b570b00e2255',
87
  ),
88
  'symfony/deprecation-contracts' =>
89
  array (
90
+ 'pretty_version' => '2.5.x-dev',
91
+ 'version' => '2.5.9999999.9999999-dev',
92
  'aliases' =>
93
  array (
 
94
  ),
95
  'reference' => '6f981ee24cf69ee7ce9736146d1c57c2780598a8',
96
  ),
100
  'version' => '5.4.9999999.9999999-dev',
101
  'aliases' =>
102
  array (
103
+ 0 => '9999999-dev',
104
  ),
105
+ 'reference' => '84d1af2d39dd81b48eb1cd3af3f107eea7a275bb',
106
  ),
107
  'symfony/polyfill-ctype' =>
108
  array (
109
+ 'pretty_version' => 'v1.24.0',
110
+ 'version' => '1.24.0.0',
111
  'aliases' =>
112
  array (
 
113
  ),
114
+ 'reference' => '30885182c981ab175d4d034db0f6f469898070ab',
115
  ),
116
  'tburry/pquery' =>
117
  array (
vendor/shortpixel/shortpixel-php/bin/shortpixel ADDED
@@ -0,0 +1,2 @@
 
 
1
+ #!/bin/bash
2
+ php ../lib/cmdShortpixelOptimize.php $@
vendor/shortpixel/shortpixel-php/lib/ShortPixel.php CHANGED
@@ -4,7 +4,7 @@ namespace ShortPixel;
4
 
5
  class ShortPixel {
6
  const LIBRARY_CODE = "sp-sdk";
7
- const VERSION = "1.8.3";
8
  const DEBUG_LOG = false;
9
 
10
  const MAX_ALLOWED_FILES_PER_CALL = 10;
@@ -340,7 +340,7 @@ function MB_basename($Path, $suffix = false){
340
  if(!$qqPath) { //this is not an UTF8 string!!
341
  $pathElements = explode('/', $Path);
342
  $fileName = end($pathElements);
343
- $pos = strpos($fileName, $suffix);
344
  if($pos !== false) {
345
  return substr($fileName, 0, $pos);
346
  }
4
 
5
  class ShortPixel {
6
  const LIBRARY_CODE = "sp-sdk";
7
+ const VERSION = "1.8.7";
8
  const DEBUG_LOG = false;
9
 
10
  const MAX_ALLOWED_FILES_PER_CALL = 10;
340
  if(!$qqPath) { //this is not an UTF8 string!!
341
  $pathElements = explode('/', $Path);
342
  $fileName = end($pathElements);
343
+ $pos = gettype($suffix) == 'string' ? strpos($fileName, $suffix) : false;
344
  if($pos !== false) {
345
  return substr($fileName, 0, $pos);
346
  }
vendor/shortpixel/shortpixel-php/lib/ShortPixel/Result.php CHANGED
@@ -43,7 +43,7 @@ class Result {
43
 
44
  if($path) {
45
  $path = rtrim($path, '/\\');
46
- if( (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' && preg_match('/^[a-zA-Z]:(\/|\\)/', $path) === 0) //it's Windows and no drive letter X:
47
  || (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN' && substr($path, 0, 1) !== '/')) { //it's not Windows and doesn't start with a /
48
  $path = SPTools::trailingslashit(ShortPixel::opt("base_path") ?: $thisDir) . $path;
49
  }
43
 
44
  if($path) {
45
  $path = rtrim($path, '/\\');
46
+ if( (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' && preg_match('/^[a-zA-Z]:(\/|\\\)/', $path) === 0) //it's Windows and no drive letter X:
47
  || (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN' && substr($path, 0, 1) !== '/')) { //it's not Windows and doesn't start with a /
48
  $path = SPTools::trailingslashit(ShortPixel::opt("base_path") ?: $thisDir) . $path;
49
  }
vendor/shortpixel/shortpixel-php/lib/ShortPixel/SPCache.php CHANGED
@@ -15,26 +15,33 @@ class SPCache {
15
  private $mc;
16
  private $local;
17
  private $time;
 
18
 
19
  private function __construct() {
20
  $this->time = \ShortPixel\opt("cache_time");
 
21
  $this->mc = \ShortPixel\getMemcache();
 
22
  if(!$this->mc) {
 
23
  $this->local = array();
24
  }
25
  }
26
 
27
  public function fetch($key) {
 
28
  if($this->mc) {
29
- return $this->mc->get($key);
30
  } elseif(isset($this->local[$key]) && time() - $this->local[$key]['time'] < $this->time) {
31
- return $this->local[$key]['value'];
32
  }
33
- return false;
 
34
  }
35
 
36
  public function store($key, $value) {
37
  if($this->time) {
 
38
  if($this->mc) {
39
  return $this->mc->set($key, $value, $this->time);
40
  } else {
@@ -45,6 +52,7 @@ class SPCache {
45
  }
46
 
47
  public function delete($key) {
 
48
  if($this->mc) {
49
  return $this->mc->delete($key);
50
  } elseif(isset($this->local[$key])) {
@@ -54,7 +62,7 @@ class SPCache {
54
  }
55
 
56
  /**
57
- * returns the current logger. If the logger is not set to log from that producer or if the log is not initialized, will return a dummy logger which doesn't log.
58
  * @return SPCache
59
  */
60
  public static function Get() {
15
  private $mc;
16
  private $local;
17
  private $time;
18
+ private $logger;
19
 
20
  private function __construct() {
21
  $this->time = \ShortPixel\opt("cache_time");
22
+ $this->logger = SPLog::Get(SPLog::PRODUCER_CACHE);
23
  $this->mc = \ShortPixel\getMemcache();
24
+ $this->logger->log(SPLog::PRODUCER_CACHE, "Cache initialized, Expiry Time: " . $this->time . ' SEC.');
25
  if(!$this->mc) {
26
+ $this->logger->log(SPLog::PRODUCER_CACHE, "Memcache not found, using local array.");
27
  $this->local = array();
28
  }
29
  }
30
 
31
  public function fetch($key) {
32
+ $ret = false;
33
  if($this->mc) {
34
+ $ret = $this->mc->get($key);
35
  } elseif(isset($this->local[$key]) && time() - $this->local[$key]['time'] < $this->time) {
36
+ $ret = $this->local[$key]['value'];
37
  }
38
+ $this->logger->log(SPLog::PRODUCER_CACHE, 'FETCHED KEY: ' . $key . ($ret ? ' VALUE: ' . print_r($ret, true) : ' UNFOUND'));
39
+ return $ret;
40
  }
41
 
42
  public function store($key, $value) {
43
  if($this->time) {
44
+ $this->logger->log(SPLog::PRODUCER_CACHE, 'STORING KEY: ' . $key . ' VALUE: ' . print_r($value, true));
45
  if($this->mc) {
46
  return $this->mc->set($key, $value, $this->time);
47
  } else {
52
  }
53
 
54
  public function delete($key) {
55
+ $this->logger->log(SPLog::PRODUCER_CACHE, 'DELETING KEY: ' . $key);
56
  if($this->mc) {
57
  return $this->mc->delete($key);
58
  } elseif(isset($this->local[$key])) {
62
  }
63
 
64
  /**
65
+ * returns the current cache provider.
66
  * @return SPCache
67
  */
68
  public static function Get() {
vendor/shortpixel/shortpixel-php/lib/ShortPixel/SPLog.php CHANGED
@@ -19,6 +19,7 @@ class SPLog {
19
  const PRODUCER_WEB = 32; //0b00100000;
20
  const PRODUCER_CTRL = 64; //0b01000000;
21
  const PRODUCER_SOURCE = 128; //0b10000000;
 
22
 
23
  const FLAG_NONE = 0;
24
  const FLAG_MEMORY = 1;
@@ -154,4 +155,16 @@ class SPLog {
154
  }
155
  return self::$instance;
156
  }
 
 
 
 
 
 
 
 
 
 
 
 
157
  }
19
  const PRODUCER_WEB = 32; //0b00100000;
20
  const PRODUCER_CTRL = 64; //0b01000000;
21
  const PRODUCER_SOURCE = 128; //0b10000000;
22
+ const PRODUCER_CACHE = 256; //0b100000000;
23
 
24
  const FLAG_NONE = 0;
25
  const FLAG_MEMORY = 1;
155
  }
156
  return self::$instance;
157
  }
158
+
159
+ /**
160
+ * set the target - useful to change the target, for example in order to start logging in a file if a number of retries has been surpassed.
161
+ * @param $target
162
+ * @param false $targetName
163
+ */
164
+ public function setTarget($target, $targetName = false) {
165
+ $this->target = $target;
166
+ if($targetName) {
167
+ $this->targetName = $targetName;
168
+ }
169
+ }
170
  }
vendor/shortpixel/shortpixel-php/lib/ShortPixel/Source.php CHANGED
@@ -127,7 +127,7 @@ class Source {
127
  function(&$item, $key, $repl){
128
  $relPath = str_replace($repl->path, '', $item);
129
  $item = implode('/', array_map('rawurlencode', explode('/', $relPath)));
130
- $item = $repl->web . $this->filter($item);
131
  }, $repl);
132
  ShortPixel::setOptions(array("base_url" => $webPath, "base_source_path" => $path));
133
 
@@ -170,7 +170,7 @@ class Source {
170
  return new Commander($data, $this);
171
  }
172
 
173
- protected function filter($item) {
174
  if(ShortPixel::opt('url_filter') == 'encode') {
175
  //TODO apply base64 or crypt on $item, whichone makes for a shorter string.
176
  $extPos = strripos($item,".");
127
  function(&$item, $key, $repl){
128
  $relPath = str_replace($repl->path, '', $item);
129
  $item = implode('/', array_map('rawurlencode', explode('/', $relPath)));
130
+ $item = $repl->web . Source::filter($item);
131
  }, $repl);
132
  ShortPixel::setOptions(array("base_url" => $webPath, "base_source_path" => $path));
133
 
170
  return new Commander($data, $this);
171
  }
172
 
173
+ protected static function filter($item) {
174
  if(ShortPixel::opt('url_filter') == 'encode') {
175
  //TODO apply base64 or crypt on $item, whichone makes for a shorter string.
176
  $extPos = strripos($item,".");
vendor/shortpixel/shortpixel-php/lib/ShortPixel/persist/TextPersister.php CHANGED
@@ -107,7 +107,7 @@ class TextPersister implements Persister {
107
  $metaFile = TextMetaFile::Get($persistPath);
108
  $dataArr = $metaFile->readAll();
109
  } catch(ClientException $e) {
110
- if(is_null($metaFile) && is_dir($persistPath) && file_exists($persistPath . '/' . ShortPixel::opt("persist_name"))) {
111
  throw $e; //rethrow, there's a problem with the meta file.
112
  }
113
  $dataArr = array(); //there's no problem if the metadata file is missing and cannot be created, for the info call
@@ -276,6 +276,7 @@ class TextPersister implements Persister {
276
  $maxTotalFileSize = $maxTotalFileSizeMb * pow(1024, 2);
277
  $totalFileSize = 0;
278
  $filesWaiting = 0;
 
279
  foreach($files as $file) {
280
  $filePath = $path . '/' . $file;
281
  $targetPath = $persistPath . '/' . $file;
@@ -285,13 +286,17 @@ class TextPersister implements Persister {
285
  if(!file_exists($filePath)) {
286
  continue; // strange but found this for a client..., on windows: HS ID 711715228
287
  }
288
- if( (!ShortPixel::isProcessable($file) && !is_dir($filePath))
289
- || isset($dataArr[$file]) && $dataArr[$file]->status == 'deleted'
290
- || isset($dataArr[$file])
291
- && ( $dataArr[$file]->status == 'success' && !$this->isChanged($dataArr[$file], $file, $persistPath, $path)
292
- || $dataArr[$file]->status == 'skip') ) {
293
- if(!isset($dataArr[$file]) || $dataArr[$file]->status !== 'success')
 
 
 
294
  $this->logger->logFirst($filePath, SPLog::PRODUCER_PERSISTER, "TextPersister->getTodo - SKIPPING $path/$file - status " . (isset($dataArr[$file]) ? $dataArr[$file]->status : "not processable"));
 
295
  continue;
296
  }
297
 
@@ -378,14 +383,18 @@ class TextPersister implements Persister {
378
  }
379
 
380
  clearstatcache(true, $filePath);
381
- if(filesize($filePath) + $totalFileSize > $maxTotalFileSize){
382
- if(filesize($filePath) > $maxTotalFileSize) { //skip this as it won't ever be selected with current settings
 
383
  $dataArr[$file]->status = 'skip';
384
  if(filesize($filePath) > ShortPixel::CLIENT_MAX_BODY_SIZE * pow(1024, 2)) {
385
  $dataArr[$file]->retries = 99;
386
  }
387
  $dataArr[$file]->message = 'File larger than the set limit of ' . $maxTotalFileSizeMb . 'MBytes';
 
388
  $metaFile->update($dataArr[$file]); //this one is too big, we skipped it, just continue with next.
 
 
389
  }
390
  continue; //the total file size would exceed the limit so leave this image out for now. If it's not too large by itself, will take it in the next pass.
391
  }
@@ -413,8 +422,9 @@ class TextPersister implements Persister {
413
  */
414
  protected function isChanged($data, $file, $persistPath, $sourcePath ) {
415
  clearstatcache(true, $sourcePath);
416
- return $persistPath === $sourcePath && filesize($sourcePath . '/' . $file) != $data->optimizedSize
417
- || $persistPath !== $sourcePath && $data->originalSize > 0 && filesize($sourcePath . '/' . $file) != $data->originalSize;
 
418
  }
419
 
420
  function getNextTodo($path, $count)
107
  $metaFile = TextMetaFile::Get($persistPath);
108
  $dataArr = $metaFile->readAll();
109
  } catch(ClientException $e) {
110
+ if(!isset($metaFile) || is_null($metaFile) && is_dir($persistPath) && file_exists($persistPath . '/' . ShortPixel::opt("persist_name"))) {
111
  throw $e; //rethrow, there's a problem with the meta file.
112
  }
113
  $dataArr = array(); //there's no problem if the metadata file is missing and cannot be created, for the info call
276
  $maxTotalFileSize = $maxTotalFileSizeMb * pow(1024, 2);
277
  $totalFileSize = 0;
278
  $filesWaiting = 0;
279
+
280
  foreach($files as $file) {
281
  $filePath = $path . '/' . $file;
282
  $targetPath = $persistPath . '/' . $file;
286
  if(!file_exists($filePath)) {
287
  continue; // strange but found this for a client..., on windows: HS ID 711715228
288
  }
289
+ if( !is_dir($filePath) //never skip folders whatever reason as they can have changes inside them
290
+ //that's a file:
291
+ &&( !ShortPixel::isProcessable($file) //either the file is not processable
292
+ || isset($dataArr[$file]) && $dataArr[$file]->status == 'deleted' //or it's deleted
293
+ || isset($dataArr[$file])
294
+ && ( $dataArr[$file]->status == 'success' && !$this->isChanged($dataArr[$file], $file, $persistPath, $path) //or changed
295
+ || $dataArr[$file]->status == 'skip') ) ) //or skipped
296
+ {
297
+ if(!isset($dataArr[$file]) || $dataArr[$file]->status !== 'success') {
298
  $this->logger->logFirst($filePath, SPLog::PRODUCER_PERSISTER, "TextPersister->getTodo - SKIPPING $path/$file - status " . (isset($dataArr[$file]) ? $dataArr[$file]->status : "not processable"));
299
+ }
300
  continue;
301
  }
302
 
383
  }
384
 
385
  clearstatcache(true, $filePath);
386
+ $fsz = filesize($filePath);
387
+ if($fsz + $totalFileSize > $maxTotalFileSize){
388
+ if($fsz > $maxTotalFileSize) { //skip this as it won't ever be selected with current settings
389
  $dataArr[$file]->status = 'skip';
390
  if(filesize($filePath) > ShortPixel::CLIENT_MAX_BODY_SIZE * pow(1024, 2)) {
391
  $dataArr[$file]->retries = 99;
392
  }
393
  $dataArr[$file]->message = 'File larger than the set limit of ' . $maxTotalFileSizeMb . 'MBytes';
394
+ $this->logger->log(SPLog::PRODUCER_PERSISTER, "TextPersister->getTodo - File too large: $path/$file - size: " . $fsz . "MBytes");
395
  $metaFile->update($dataArr[$file]); //this one is too big, we skipped it, just continue with next.
396
+ } else {
397
+ //$this->logger->log(SPLog::PRODUCER_PERSISTER, "TextPersister->getTodo - File won't fit this round: $path/$file - size: " . $fsz . "MBytes");
398
  }
399
  continue; //the total file size would exceed the limit so leave this image out for now. If it's not too large by itself, will take it in the next pass.
400
  }
422
  */
423
  protected function isChanged($data, $file, $persistPath, $sourcePath ) {
424
  clearstatcache(true, $sourcePath);
425
+ $fileSize = filesize($sourcePath . '/' . $file);
426
+ return $persistPath === $sourcePath && $data->optimizedSize > 0 && $fileSize != $data->optimizedSize
427
+ || $persistPath !== $sourcePath && $data->originalSize > 0 && $fileSize != $data->originalSize;
428
  }
429
 
430
  function getNextTodo($path, $count)
vendor/shortpixel/shortpixel-php/lib/cmdShortpixelOptimize.php CHANGED
@@ -26,7 +26,10 @@ ini_set('memory_limit','256M');
26
 
27
  require_once("shortpixel-php-req.php");
28
 
 
 
29
  use \ShortPixel\SPLog;
 
30
 
31
  $processId = uniqid("CLI");
32
 
@@ -35,7 +38,7 @@ $options = getopt("", array("apiKey::", "folder::", "targetFolder::", "webPath::
35
 
36
  $verbose = isset($options["verbose"]) ? (isset($options["logLevel"]) ? $options["logLevel"] : 0) | SPLog::PRODUCER_CMD_VERBOSE : 0;
37
  $logger = SPLog::Init($processId, $verbose | SPLog::PRODUCER_CMD, SPLog::TARGET_CONSOLE, false, ($verbose ? SPLog::FLAG_MEMORY : SPLog::FLAG_NONE));
38
- $logger->log(SPLog::PRODUCER_CMD_VERBOSE, "ShortPixel CLI version " . \ShortPixel\ShortPixel::VERSION);
39
 
40
  $logger->log(SPLog::PRODUCER_CMD_VERBOSE, "ShortPixel Logging VERBOSE" . ($verbose & SPLog::PRODUCER_PERSISTER ? ", PERSISTER" : "") . ($verbose & SPLog::PRODUCER_CLIENT ? ", CLIENT" : ""));
41
 
@@ -64,14 +67,14 @@ if(!function_exists('curl_version')) {
64
  }
65
 
66
  if($webPath === false && isset($options["webPath"])) {
67
- $logger->bye(SPLog::PRODUCER_CMD, "The Web Path specified is invalid - " . $options["webPath"]);
68
  }
69
 
70
  $bkFolder = $bkFolderRel = false;
71
  if($bkBase) {
72
  if(is_dir($bkBase)) {
73
- $bkBase = \ShortPixel\SPTools::trailingslashit($bkBase);
74
- $bkFolder = $bkBase . (strpos($bkBase, \ShortPixel\SPTools::trailingslashit($folder)) === 0 ? 'ShortPixelBackups' : basename($folder) . (strpos($bkBase, \ShortPixel\SPTools::trailingslashit(dirname($folder))) === 0 ? "_SP_BKP" : "" ));
75
  $bkFolderRel = \ShortPixel\Settings::pathToRelative($bkFolder, $targetFolder);
76
  } else {
77
  $logger->bye(SPLog::PRODUCER_CMD, "Backup path does not exist ($bkFolder)");
@@ -94,9 +97,9 @@ if(!$folder || strlen($folder) == 0) {
94
  }
95
 
96
  if($targetFolder != $folder) {
97
- if(strpos($targetFolder, \ShortPixel\SPTools::trailingslashit($folder)) === 0) {
98
  $logger->bye(SPLog::PRODUCER_CMD, "Target folder cannot be a subfolder of the source folder. ( $targetFolder $folder)");
99
- } elseif (strpos($folder, \ShortPixel\SPTools::trailingslashit($targetFolder)) === 0) {
100
  $logger->bye(SPLog::PRODUCER_CMD, "Target folder cannot be a parent folder of the source folder.");
101
  } else {
102
  @mkdir($targetFolder, 0777, true);
@@ -108,7 +111,7 @@ $logger->log(SPLog::PRODUCER_CMD_VERBOSE, "Using notifier: " . get_class($notifi
108
 
109
  try {
110
  //check if the folder is not locked by another ShortPixel process
111
- $splock = new \ShortPixel\Lock($processId, $targetFolder, $clearLock);
112
  try {
113
  $splock->lock();
114
  } catch(\Exception $ex) {
@@ -117,9 +120,9 @@ try {
117
  $logger->log(SPLog::PRODUCER_CMD_VERBOSE, "Lock aquired");
118
  }
119
 
120
- $logger->log(SPLog::PRODUCER_CMD, "Starting to optimize folder $folder using API Key $apiKey ...");
121
 
122
- ShortPixel\setKey($apiKey);
123
 
124
  //try to get optimization options from the folder .sp-options
125
  $optionsHandler = new \ShortPixel\Settings();
@@ -172,7 +175,7 @@ try {
172
  }
173
  $optimizationOptions = array_merge($folderOptions, $overrides, array("persist_type" => "text", "notify_progress" => true, "cache_time" => $cacheTime));
174
  $logger->log(SPLog::PRODUCER_CMD_VERBOSE, "Using OPTIONS: ", $optimizationOptions);
175
- \ShortPixel\ShortPixel::setOptions($optimizationOptions);
176
 
177
  $imageCount = $failedImageCount = $sameImageCount = 0;
178
  $tries = 0;
@@ -206,8 +209,9 @@ try {
206
  if ($webPath) {
207
  $result = \ShortPixel\fromWebFolder($folder, $webPath, $exclude, $targetFolderParam, $recurseDepth)->wait(300)->toFiles($targetFolder);
208
  } else {
209
- $speed = ($speed ? $speed : \ShortPixel\ShortPixel::MAX_ALLOWED_FILES_PER_CALL);
210
- $result = \ShortPixel\fromFolder($folder, $speed, $exclude, $targetFolderParam, \ShortPixel\ShortPixel::CLIENT_MAX_BODY_SIZE, $recurseDepth)->wait(300)->toFiles($targetFolder);
 
211
  }
212
  if(time() - $tempus > $lockTimeout - 100) {
213
  //increase the timeout of the lock file if a pass takes too long (for large folders)
@@ -221,7 +225,7 @@ try {
221
  } else {
222
  $logger->log(SPLog::PRODUCER_CMD, "ClientException: " . $ex->getMessage() . " (CODE: " . $ex->getCode() . ")");
223
  $tries++;
224
- if(++$consecutiveExceptions > \ShortPixel\ShortPixel::MAX_RETRIES) {
225
  $logger->log(SPLog::PRODUCER_CMD, "Too many exceptions. Exiting.");
226
  break;
227
  }
@@ -232,7 +236,7 @@ try {
232
  catch (\ShortPixel\ServerException $ex) {
233
  if($ex->getCode() == 502) {
234
  $logger->log(SPLog::PRODUCER_CMD, "ServerException: " . $ex->getMessage() . " (CODE: " . $ex->getCode() . ")");
235
- if(++$consecutiveExceptions > \ShortPixel\ShortPixel::MAX_RETRIES) {
236
  $logger->log(SPLog::PRODUCER_CMD, "Too many exceptions. Exiting.");
237
  break;
238
  }
26
 
27
  require_once("shortpixel-php-req.php");
28
 
29
+ use ShortPixel\Lock;
30
+ use ShortPixel\ShortPixel;
31
  use \ShortPixel\SPLog;
32
+ use ShortPixel\SPTools;
33
 
34
  $processId = uniqid("CLI");
35
 
38
 
39
  $verbose = isset($options["verbose"]) ? (isset($options["logLevel"]) ? $options["logLevel"] : 0) | SPLog::PRODUCER_CMD_VERBOSE : 0;
40
  $logger = SPLog::Init($processId, $verbose | SPLog::PRODUCER_CMD, SPLog::TARGET_CONSOLE, false, ($verbose ? SPLog::FLAG_MEMORY : SPLog::FLAG_NONE));
41
+ $logger->log(SPLog::PRODUCER_CMD_VERBOSE, "ShortPixel CLI version " . ShortPixel::VERSION);
42
 
43
  $logger->log(SPLog::PRODUCER_CMD_VERBOSE, "ShortPixel Logging VERBOSE" . ($verbose & SPLog::PRODUCER_PERSISTER ? ", PERSISTER" : "") . ($verbose & SPLog::PRODUCER_CLIENT ? ", CLIENT" : ""));
44
 
67
  }
68
 
69
  if($webPath === false && isset($options["webPath"])) {
70
+ $logger->bye(SPLog::PRODUCER_CMD, "The specified Web Path is invalid - " . $options["webPath"]);
71
  }
72
 
73
  $bkFolder = $bkFolderRel = false;
74
  if($bkBase) {
75
  if(is_dir($bkBase)) {
76
+ $bkBase = SPTools::trailingslashit($bkBase);
77
+ $bkFolder = $bkBase . (strpos($bkBase, SPTools::trailingslashit($folder)) === 0 ? 'ShortPixelBackups' : basename($folder) . (strpos($bkBase, SPTools::trailingslashit(dirname($folder))) === 0 ? "_SP_BKP" : "" ));
78
  $bkFolderRel = \ShortPixel\Settings::pathToRelative($bkFolder, $targetFolder);
79
  } else {
80
  $logger->bye(SPLog::PRODUCER_CMD, "Backup path does not exist ($bkFolder)");
97
  }
98
 
99
  if($targetFolder != $folder) {
100
+ if(strpos($targetFolder, SPTools::trailingslashit($folder)) === 0) {
101
  $logger->bye(SPLog::PRODUCER_CMD, "Target folder cannot be a subfolder of the source folder. ( $targetFolder $folder)");
102
+ } elseif (strpos($folder, SPTools::trailingslashit($targetFolder)) === 0) {
103
  $logger->bye(SPLog::PRODUCER_CMD, "Target folder cannot be a parent folder of the source folder.");
104
  } else {
105
  @mkdir($targetFolder, 0777, true);
111
 
112
  try {
113
  //check if the folder is not locked by another ShortPixel process
114
+ $splock = new Lock($processId, $targetFolder, $clearLock);
115
  try {
116
  $splock->lock();
117
  } catch(\Exception $ex) {
120
  $logger->log(SPLog::PRODUCER_CMD_VERBOSE, "Lock aquired");
121
  }
122
 
123
+ $logger->log(SPLog::PRODUCER_CMD, "ShortPixel CLI " . ShortPixel::VERSION . " starting to optimize folder $folder using API Key $apiKey ...");
124
 
125
+ \ShortPixel\setKey($apiKey);
126
 
127
  //try to get optimization options from the folder .sp-options
128
  $optionsHandler = new \ShortPixel\Settings();
175
  }
176
  $optimizationOptions = array_merge($folderOptions, $overrides, array("persist_type" => "text", "notify_progress" => true, "cache_time" => $cacheTime));
177
  $logger->log(SPLog::PRODUCER_CMD_VERBOSE, "Using OPTIONS: ", $optimizationOptions);
178
+ ShortPixel::setOptions($optimizationOptions);
179
 
180
  $imageCount = $failedImageCount = $sameImageCount = 0;
181
  $tries = 0;
209
  if ($webPath) {
210
  $result = \ShortPixel\fromWebFolder($folder, $webPath, $exclude, $targetFolderParam, $recurseDepth)->wait(300)->toFiles($targetFolder);
211
  } else {
212
+ $speed = ($speed ? $speed : ShortPixel::MAX_ALLOWED_FILES_PER_CALL);
213
+ $logger->log(SPLog::PRODUCER_CMD, "\n\n\nPASS $tries ....");
214
+ $result = \ShortPixel\fromFolder($folder, $speed, $exclude, $targetFolderParam, ShortPixel::CLIENT_MAX_BODY_SIZE, $recurseDepth)->wait(300)->toFiles($targetFolder);
215
  }
216
  if(time() - $tempus > $lockTimeout - 100) {
217
  //increase the timeout of the lock file if a pass takes too long (for large folders)
225
  } else {
226
  $logger->log(SPLog::PRODUCER_CMD, "ClientException: " . $ex->getMessage() . " (CODE: " . $ex->getCode() . ")");
227
  $tries++;
228
+ if(++$consecutiveExceptions > ShortPixel::MAX_RETRIES) {
229
  $logger->log(SPLog::PRODUCER_CMD, "Too many exceptions. Exiting.");
230
  break;
231
  }
236
  catch (\ShortPixel\ServerException $ex) {
237
  if($ex->getCode() == 502) {
238
  $logger->log(SPLog::PRODUCER_CMD, "ServerException: " . $ex->getMessage() . " (CODE: " . $ex->getCode() . ")");
239
+ if(++$consecutiveExceptions > ShortPixel::MAX_RETRIES) {
240
  $logger->log(SPLog::PRODUCER_CMD, "Too many exceptions. Exiting.");
241
  break;
242
  }
vendor/shortpixel/shortpixel-php/test.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Created by PhpStorm.
4
+ * User: simon
5
+ * Date: 04.02.2020
6
+ * Time: 18:00
7
+ */
8
+
9
+ // Set up the API Key.
10
+ ShortPixel\setKey("YOUR_API_KEY");
11
+
12
+ // Compress with default settings
13
+ ShortPixel\fromUrls("https://your.site/img/unoptimized.png")->toFiles("/path/to/save/to");
14
+ // Compress with default settings but specifying a different file name
15
+ ShortPixel\fromUrls("https://your.site/img/unoptimized.png")->toFiles("/path/to/save/to", "optimized.png");
16
+
17
+ // Compress with default settings from a local file
18
+ ShortPixel\fromFile("/path/to/your/local/unoptimized.png")->toFiles("/path/to/save/to");
19
+ // Compress with default settings from several local files
20
+ ShortPixel\fromFiles(array("/path/to/your/local/unoptimized1.png", "/path/to/your/local/unoptimized2.png"))->toFiles("/path/to/save/to");
21
+ //Compres and rename each file
22
+ \ShortPixel\fromFiles(array("/path/to/your/local/unoptimized1.png", "/path/to/your/local/unoptimized2.png"))->toFiles("/path/to/save/to", ['renamed-one.png', 'renamed-two.png']);
23
+
24
+ // Compress with a specific compression level: 0 - lossless, 1 - lossy (default), 2 - glossy
25
+ ShortPixel\fromFile("/path/to/your/local/unoptimized.png")->optimize(2)->toFiles("/path/to/save/to");
26
+
27
+ // Compress and resize - image is resized to have the either width equal to specified or height equal to specified
28
+ // but not LESS (with settings below, a 300x200 image will be resized to 150x100)
29
+ ShortPixel\fromUrls("https://your.site/img/unoptimized.png")->resize(100, 100)->toFiles("/path/to/save/to");
30
+ // Compress and resize - have the either width equal to specified or height equal to specified
31
+ // but not MORE (with settings below, a 300x200 image will be resized to 100x66)
32
+ ShortPixel\fromUrls("https://your.site/img/unoptimized.png")->resize(100, 100, true)->toFiles("/path/to/save/to");
33
+
34
+ // Keep the exif when compressing
35
+ ShortPixel\fromUrls("https://your.site/img/unoptimized.png")->keepExif()->toFiles("/path/to/save/to");
36
+
37
+ // Also generate and save a WebP version of the file - the WebP file will be saved next to the optimized file, with same basename and .webp extension
38
+ ShortPixel\fromUrls("https://your.site/img/unoptimized.png")->generateWebP()->toFiles("/path/to/save/to");
39
+
40
+ //Compress from a folder - the status of the compressed images is saved in a text file named .shortpixel in each image folder
41
+ \ShortPixel\ShortPixel::setOptions(array("persist_type" => "text"));
42
+ //Each call will optimize up to 10 images from the specified folder and mark in the .shortpixel file.
43
+ //It automatically recurses a subfolder when finds it
44
+ //Save to the same folder, set wait time to 300 to allow enough time for the images to be processed
45
+ $ret = ShortPixel\fromFolder("/path/to/your/local/folder")->wait(300)->toFiles("/path/to/your/local/folder");
46
+ //Save to a different folder. CURRENT LIMITATION: When using the text persist type and saving to a different folder, you also need to specify the destination folder as the fourth parameter to fromFolder ( it indicates where the persistence files should be created)
47
+ $ret = ShortPixel\fromFolder("/path/to/your/local/folder", 0, array(), "/different/path/to/save/to")->wait(300)->toFiles("/different/path/to/save/to");
48
+ //use a URL to map the folder to a WEB path in order for our servers to download themselves the images instead of receiving them via POST - faster and less exposed to connection timeouts
49
+ $ret = ShortPixel\fromWebFolder("/path/to/your/local/folder", "http://web.path/to/your/local/folder")->wait(300)->toFiles("/path/to/save/to");
50
+ //let ShortPixel back-up all your files, before overwriting them (third parameter of toFiles).
51
+ $ret = ShortPixel\fromFolder("/path/to/your/local/folder")->wait(300)->toFiles("/path/to/save/to", null, "/back-up/path");
52
+ //Recurse only $N levels down into the subfolders of the folder ( N == 0 means do not recurse )
53
+ $ret = ShortPixel\fromFolder("/path/to/your/local/folder", 0, array(), false, ShortPixel::CLIENT_MAX_BODY_SIZE, $N)->wait(300)->toFiles("/path/to/save/to");
54
+
55
+ //Set custom cURL options (proxy)
56
+ \ShortPixel\setCurlOptions(array(CURLOPT_PROXY => '66.96.200.39:80', CURLOPT_REFERER => 'https://shortpixel.com/'));
57
+
58
+
59
+ //A simple loop to optimize all images from a folder
60
+ $stop = false;
61
+ while(!$stop) {
62
+ $ret = ShortPixel\fromFolder("/path/to/your/local/folder")->wait(300)->toFiles("/path/to/save/to");
63
+ if(count($ret->succeeded) + count($ret->failed) + count($ret->same) + count($ret->pending) == 0) {
64
+ $stop = true;
65
+ }
66
+ }
67
+
68
+ //Compress from an image in memory
69
+ $myImage = file_get_contents($pathTo_shortpixel.png);
70
+ $ret = \ShortPixel\fromBuffer('shortpixel.png', $myImage)->wait(300)->toFiles(self::$tempDir);
71
+
72
+ //Get account status and credits info:
73
+ $ret = \ShortPixel\ShortPixel::getClient()->apiStatus(YOUR_API_KEY);
74
+
vendor/symfony/dotenv/Command/DebugCommand.php ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Dotenv\Command;
13
+
14
+ use Symfony\Component\Console\Command\Command;
15
+ use Symfony\Component\Console\Input\InputInterface;
16
+ use Symfony\Component\Console\Output\OutputInterface;
17
+ use Symfony\Component\Console\Style\SymfonyStyle;
18
+ use Symfony\Component\Dotenv\Dotenv;
19
+
20
+ /**
21
+ * A console command to debug current dotenv files with variables and values.
22
+ *
23
+ * @author Christopher Hertel <mail@christopher-hertel.de>
24
+ */
25
+ final class DebugCommand extends Command
26
+ {
27
+ protected static $defaultName = 'debug:dotenv';
28
+ protected static $defaultDescription = 'Lists all dotenv files with variables and values';
29
+
30
+ private $kernelEnvironment;
31
+ private $projectDirectory;
32
+
33
+ public function __construct(string $kernelEnvironment, string $projectDirectory)
34
+ {
35
+ $this->kernelEnvironment = $kernelEnvironment;
36
+ $this->projectDirectory = $projectDirectory;
37
+
38
+ parent::__construct();
39
+ }
40
+
41
+ protected function execute(InputInterface $input, OutputInterface $output): int
42
+ {
43
+ $io = new SymfonyStyle($input, $output);
44
+ $io->title('Dotenv Variables & Files');
45
+
46
+ if (!\array_key_exists('SYMFONY_DOTENV_VARS', $_SERVER)) {
47
+ $io->error('Dotenv component is not initialized.');
48
+
49
+ return 1;
50
+ }
51
+
52
+ $envFiles = $this->getEnvFiles();
53
+ $availableFiles = array_filter($envFiles, function (string $file) {
54
+ return is_file($this->getFilePath($file));
55
+ });
56
+
57
+ if (\in_array('.env.local.php', $availableFiles, true)) {
58
+ $io->warning('Due to existing dump file (.env.local.php) all other dotenv files are skipped.');
59
+ }
60
+
61
+ if (is_file($this->getFilePath('.env')) && is_file($this->getFilePath('.env.dist'))) {
62
+ $io->warning('The file .env.dist gets skipped due to the existence of .env.');
63
+ }
64
+
65
+ $io->section('Scanned Files (in descending priority)');
66
+ $io->listing(array_map(static function (string $envFile) use ($availableFiles) {
67
+ return \in_array($envFile, $availableFiles, true)
68
+ ? sprintf('<fg=green>✓</> %s', $envFile)
69
+ : sprintf('<fg=red>⨯</> %s', $envFile);
70
+ }, $envFiles));
71
+
72
+ $io->section('Variables');
73
+ $io->table(
74
+ array_merge(['Variable', 'Value'], $availableFiles),
75
+ $this->getVariables($availableFiles)
76
+ );
77
+
78
+ $io->comment('Note real values might be different between web and CLI.');
79
+
80
+ return 0;
81
+ }
82
+
83
+ private function getVariables(array $envFiles): array
84
+ {
85
+ $vars = explode(',', $_SERVER['SYMFONY_DOTENV_VARS'] ?? '');
86
+ sort($vars);
87
+
88
+ $output = [];
89
+ $fileValues = [];
90
+ foreach ($vars as $var) {
91
+ $realValue = $_SERVER[$var];
92
+ $varDetails = [$var, $realValue];
93
+ foreach ($envFiles as $envFile) {
94
+ $values = $fileValues[$envFile] ?? $fileValues[$envFile] = $this->loadValues($envFile);
95
+
96
+ $varString = $values[$var] ?? '<fg=yellow>n/a</>';
97
+ $shortenedVar = $this->getHelper('formatter')->truncate($varString, 30);
98
+ $varDetails[] = $varString === $realValue ? '<fg=green>'.$shortenedVar.'</>' : $shortenedVar;
99
+ }
100
+
101
+ $output[] = $varDetails;
102
+ }
103
+
104
+ return $output;
105
+ }
106
+
107
+ private function getEnvFiles(): array
108
+ {
109
+ $files = [
110
+ '.env.local.php',
111
+ sprintf('.env.%s.local', $this->kernelEnvironment),
112
+ sprintf('.env.%s', $this->kernelEnvironment),
113
+ ];
114
+
115
+ if ('test' !== $this->kernelEnvironment) {
116
+ $files[] = '.env.local';
117
+ }
118
+
119
+ if (!is_file($this->getFilePath('.env')) && is_file($this->getFilePath('.env.dist'))) {
120
+ $files[] = '.env.dist';
121
+ } else {
122
+ $files[] = '.env';
123
+ }
124
+
125
+ return $files;
126
+ }
127
+
128
+ private function getFilePath(string $file): string
129
+ {
130
+ return $this->projectDirectory.\DIRECTORY_SEPARATOR.$file;
131
+ }
132
+
133
+ private function loadValues(string $file): array
134
+ {
135
+ $filePath = $this->getFilePath($file);
136
+
137
+ if (str_ends_with($filePath, '.php')) {
138
+ return include $filePath;
139
+ }
140
+
141
+ return (new Dotenv())->parse(file_get_contents($filePath));
142
+ }
143
+ }
vendor/symfony/dotenv/Command/DotenvDumpCommand.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Dotenv\Command;
13
+
14
+ use Symfony\Component\Console\Command\Command;
15
+ use Symfony\Component\Console\Input\InputArgument;
16
+ use Symfony\Component\Console\Input\InputInterface;
17
+ use Symfony\Component\Console\Input\InputOption;
18
+ use Symfony\Component\Console\Output\OutputInterface;
19
+ use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
20
+ use Symfony\Component\Dotenv\Dotenv;
21
+
22
+ /**
23
+ * A console command to compile .env files into a PHP-optimized file called .env.local.php.
24
+ *
25
+ * @internal
26
+ */
27
+ #[Autoconfigure(bind: ['$dotenvPath' => '%kernel.project_dir%/.env', '$defaultEnv' => '%kernel.environment%'])]
28
+ final class DotenvDumpCommand extends Command
29
+ {
30
+ protected static $defaultName = 'dotenv:dump';
31
+ protected static $defaultDescription = 'Compiles .env files to .env.local.php';
32
+
33
+ private $dotenvPath;
34
+ private $defaultEnv;
35
+
36
+ public function __construct(string $dotenvPath, string $defaultEnv = null)
37
+ {
38
+ $this->dotenvPath = $dotenvPath;
39
+ $this->defaultEnv = $defaultEnv;
40
+
41
+ parent::__construct();
42
+ }
43
+
44
+ /**
45
+ * {@inheritdoc}
46
+ */
47
+ protected function configure()
48
+ {
49
+ $this
50
+ ->setDefinition([
51
+ new InputArgument('env', null === $this->defaultEnv ? InputArgument::REQUIRED : InputArgument::OPTIONAL, 'The application environment to dump .env files for - e.g. "prod".'),
52
+ ])
53
+ ->addOption('empty', null, InputOption::VALUE_NONE, 'Ignore the content of .env files')
54
+ ->setHelp(<<<'EOT'
55
+ The <info>%command.name%</info> command compiles .env files into a PHP-optimized file called .env.local.php.
56
+
57
+ <info>%command.full_name%</info>
58
+ EOT
59
+ )
60
+ ;
61
+ }
62
+
63
+ /**
64
+ * {@inheritdoc}
65
+ */
66
+ protected function execute(InputInterface $input, OutputInterface $output): int
67
+ {
68
+ $env = $input->getArgument('env') ?? $this->defaultEnv;
69
+
70
+ if ($input->getOption('empty')) {
71
+ $vars = ['APP_ENV' => $env];
72
+ } else {
73
+ $vars = $this->loadEnv($env);
74
+ $env = $vars['APP_ENV'];
75
+ }
76
+
77
+ $vars = var_export($vars, true);
78
+ $vars = <<<EOF
79
+ <?php
80
+
81
+ // This file was generated by running "php bin/console dotenv:dump $env"
82
+
83
+ return $vars;
84
+
85
+ EOF;
86
+ file_put_contents($this->dotenvPath.'.local.php', $vars, \LOCK_EX);
87
+
88
+ $output->writeln(sprintf('Successfully dumped .env files in <info>.env.local.php</> for the <info>%s</> environment.', $env));
89
+
90
+ return 0;
91
+ }
92
+
93
+ private function loadEnv(string $env): array
94
+ {
95
+ $dotenv = new Dotenv();
96
+ $composerFile = \dirname($this->dotenvPath).'/composer.json';
97
+ $testEnvs = (is_file($composerFile) ? json_decode(file_get_contents($composerFile), true) : [])['extra']['runtime']['test_envs'] ?? ['test'];
98
+
99
+ $globalsBackup = [$_SERVER, $_ENV];
100
+ unset($_SERVER['APP_ENV']);
101
+ $_ENV = ['APP_ENV' => $env];
102
+ $_SERVER['SYMFONY_DOTENV_VARS'] = implode(',', array_keys($_SERVER));
103
+
104
+ try {
105
+ $dotenv->loadEnv($this->dotenvPath, null, 'dev', $testEnvs);
106
+ unset($_ENV['SYMFONY_DOTENV_VARS']);
107
+
108
+ return $_ENV;
109
+ } finally {
110
+ [$_SERVER, $_ENV] = $globalsBackup;
111
+ }
112
+ }
113
+ }
vendor/symfony/dotenv/Dotenv.php CHANGED
@@ -81,8 +81,8 @@ final class Dotenv
81
  /**
82
  * Loads one or several .env files.
83
  *
84
- * @param string $path A file to load
85
- * @param ...string $extraPaths A list of additional files to load
86
  *
87
  * @throws FormatException when a file has a syntax error
88
  * @throws PathException when a file does not exist or is not readable
@@ -106,22 +106,22 @@ final class Dotenv
106
  * @throws FormatException when a file has a syntax error
107
  * @throws PathException when a file does not exist or is not readable
108
  */
109
- public function loadEnv(string $path, string $envKey = null, string $defaultEnv = 'dev', array $testEnvs = ['test']): void
110
  {
111
  $k = $envKey ?? $this->envKey;
112
 
113
  if (is_file($path) || !is_file($p = "$path.dist")) {
114
- $this->load($path);
115
  } else {
116
- $this->load($p);
117
  }
118
 
119
  if (null === $env = $_SERVER[$k] ?? $_ENV[$k] ?? null) {
120
- $this->populate([$k => $env = $defaultEnv]);
121
  }
122
 
123
  if (!\in_array($env, $testEnvs, true) && is_file($p = "$path.local")) {
124
- $this->load($p);
125
  $env = $_SERVER[$k] ?? $_ENV[$k] ?? $env;
126
  }
127
 
@@ -130,11 +130,11 @@ final class Dotenv
130
  }
131
 
132
  if (is_file($p = "$path.$env")) {
133
- $this->load($p);
134
  }
135
 
136
  if (is_file($p = "$path.$env.local")) {
137
- $this->load($p);
138
  }
139
  }
140
 
@@ -145,16 +145,16 @@ final class Dotenv
145
  *
146
  * See method loadEnv() for rules related to .env files.
147
  */
148
- public function bootEnv(string $path, string $defaultEnv = 'dev', array $testEnvs = ['test']): void
149
  {
150
  $p = $path.'.local.php';
151
  $env = is_file($p) ? include $p : null;
152
  $k = $this->envKey;
153
 
154
- if (\is_array($env) && (!isset($env[$k]) || ($_SERVER[$k] ?? $_ENV[$k] ?? $env[$k]) === $env[$k])) {
155
- $this->populate($env);
156
  } else {
157
- $this->loadEnv($path, $k, $defaultEnv, $testEnvs);
158
  }
159
 
160
  $_SERVER += $_ENV;
@@ -167,8 +167,8 @@ final class Dotenv
167
  /**
168
  * Loads one or several .env files and enables override existing vars.
169
  *
170
- * @param string $path A file to load
171
- * @param ...string $extraPaths A list of additional files to load
172
  *
173
  * @throws FormatException when a file has a syntax error
174
  * @throws PathException when a file does not exist or is not readable
@@ -191,8 +191,12 @@ final class Dotenv
191
 
192
  foreach ($values as $name => $value) {
193
  $notHttpName = 0 !== strpos($name, 'HTTP_');
 
 
 
 
194
  // don't check existence with getenv() because of thread safety issues
195
- if (!isset($loadedVars[$name]) && (!$overrideExistingVars && (isset($_ENV[$name]) || (isset($_SERVER[$name]) && $notHttpName)))) {
196
  continue;
197
  }
198
 
@@ -227,8 +231,6 @@ final class Dotenv
227
  * @param string $data The data to be parsed
228
  * @param string $path The original file name where data where stored (used for more meaningful error messages)
229
  *
230
- * @return array
231
- *
232
  * @throws FormatException when a file has a syntax error
233
  */
234
  public function parse(string $data, string $path = '.env'): array
81
  /**
82
  * Loads one or several .env files.
83
  *
84
+ * @param string $path A file to load
85
+ * @param string[] ...$extraPaths A list of additional files to load
86
  *
87
  * @throws FormatException when a file has a syntax error
88
  * @throws PathException when a file does not exist or is not readable
106
  * @throws FormatException when a file has a syntax error
107
  * @throws PathException when a file does not exist or is not readable
108
  */
109
+ public function loadEnv(string $path, string $envKey = null, string $defaultEnv = 'dev', array $testEnvs = ['test'], bool $overrideExistingVars = false): void
110
  {
111
  $k = $envKey ?? $this->envKey;
112
 
113
  if (is_file($path) || !is_file($p = "$path.dist")) {
114
+ $this->doLoad($overrideExistingVars, [$path]);
115
  } else {
116
+ $this->doLoad($overrideExistingVars, [$p]);
117
  }
118
 
119
  if (null === $env = $_SERVER[$k] ?? $_ENV[$k] ?? null) {
120
+ $this->populate([$k => $env = $defaultEnv], $overrideExistingVars);
121
  }
122
 
123
  if (!\in_array($env, $testEnvs, true) && is_file($p = "$path.local")) {
124
+ $this->doLoad($overrideExistingVars, [$p]);
125
  $env = $_SERVER[$k] ?? $_ENV[$k] ?? $env;
126
  }
127
 
130
  }
131
 
132
  if (is_file($p = "$path.$env")) {
133
+ $this->doLoad($overrideExistingVars, [$p]);
134
  }
135
 
136
  if (is_file($p = "$path.$env.local")) {
137
+ $this->doLoad($overrideExistingVars, [$p]);
138
  }
139
  }
140
 
145
  *
146
  * See method loadEnv() for rules related to .env files.
147
  */
148
+ public function bootEnv(string $path, string $defaultEnv = 'dev', array $testEnvs = ['test'], bool $overrideExistingVars = false): void
149
  {
150
  $p = $path.'.local.php';
151
  $env = is_file($p) ? include $p : null;
152
  $k = $this->envKey;
153
 
154
+ if (\is_array($env) && ($overrideExistingVars || !isset($env[$k]) || ($_SERVER[$k] ?? $_ENV[$k] ?? $env[$k]) === $env[$k])) {
155
+ $this->populate($env, $overrideExistingVars);
156
  } else {
157
+ $this->loadEnv($path, $k, $defaultEnv, $testEnvs, $overrideExistingVars);
158
  }
159
 
160
  $_SERVER += $_ENV;
167
  /**
168
  * Loads one or several .env files and enables override existing vars.
169
  *
170
+ * @param string $path A file to load
171
+ * @param string[] ...$extraPaths A list of additional files to load
172
  *
173
  * @throws FormatException when a file has a syntax error
174
  * @throws PathException when a file does not exist or is not readable
191
 
192
  foreach ($values as $name => $value) {
193
  $notHttpName = 0 !== strpos($name, 'HTTP_');
194
+ if (isset($_SERVER[$name]) && $notHttpName && !isset($_ENV[$name])) {
195
+ $_ENV[$name] = $_SERVER[$name];
196
+ }
197
+
198
  // don't check existence with getenv() because of thread safety issues
199
+ if (!isset($loadedVars[$name]) && !$overrideExistingVars && isset($_ENV[$name])) {
200
  continue;
201
  }
202
 
231
  * @param string $data The data to be parsed
232
  * @param string $path The original file name where data where stored (used for more meaningful error messages)
233
  *
 
 
234
  * @throws FormatException when a file has a syntax error
235
  */
236
  public function parse(string $data, string $path = '.env'): array
vendor/symfony/dotenv/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2016-2021 Fabien Potencier
2
 
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
  of this software and associated documentation files (the "Software"), to deal
1
+ Copyright (c) 2016-2022 Fabien Potencier
2
 
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
  of this software and associated documentation files (the "Software"), to deal
vendor/symfony/dotenv/Tests/Command/DebugCommandTest.php ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Dotenv\Tests\Command;
13
+
14
+ use PHPUnit\Framework\TestCase;
15
+ use Symfony\Component\Console\Helper\FormatterHelper;
16
+ use Symfony\Component\Console\Helper\HelperSet;
17
+ use Symfony\Component\Console\Tester\CommandTester;
18
+ use Symfony\Component\Dotenv\Command\DebugCommand;
19
+ use Symfony\Component\Dotenv\Dotenv;
20
+
21
+ class DebugCommandTest extends TestCase
22
+ {
23
+ /**
24
+ * @runInSeparateProcess
25
+ */
26
+ public function testErrorOnUninitializedDotenv()
27
+ {
28
+ $command = new DebugCommand('dev', __DIR__.'/Fixtures/Scenario1');
29
+ $command->setHelperSet(new HelperSet([new FormatterHelper()]));
30
+ $tester = new CommandTester($command);
31
+ $tester->execute([]);
32
+ $output = $tester->getDisplay();
33
+
34
+ $this->assertStringContainsString('[ERROR] Dotenv component is not initialized', $output);
35
+ }
36
+
37
+ public function testScenario1InDevEnv()
38
+ {
39
+ $output = $this->executeCommand(__DIR__.'/Fixtures/Scenario1', 'dev');
40
+
41
+ // Scanned Files
42
+ $this->assertStringContainsString('⨯ .env.local.php', $output);
43
+ $this->assertStringContainsString('⨯ .env.dev.local', $output);
44
+ $this->assertStringContainsString('⨯ .env.dev', $output);
45
+ $this->assertStringContainsString('✓ .env.local', $output);
46
+ $this->assertStringContainsString('✓ .env'.\PHP_EOL, $output);
47
+
48
+ // Skipped Files
49
+ $this->assertStringNotContainsString('.env.prod', $output);
50
+ $this->assertStringNotContainsString('.env.test', $output);
51
+ $this->assertStringNotContainsString('.env.dist', $output);
52
+
53
+ // Variables
54
+ $this->assertStringContainsString('Variable Value .env.local .env', $output);
55
+ $this->assertStringContainsString('FOO baz baz bar', $output);
56
+ $this->assertStringContainsString('TEST123 true n/a true', $output);
57
+ }
58
+
59
+ public function testScenario1InTestEnv()
60
+ {
61
+ $output = $this->executeCommand(__DIR__.'/Fixtures/Scenario1', 'test');
62
+
63
+ // Scanned Files
64
+ $this->assertStringContainsString('⨯ .env.local.php', $output);
65
+ $this->assertStringContainsString('⨯ .env.test.local', $output);
66
+ $this->assertStringContainsString('✓ .env.test', $output);
67
+ $this->assertStringContainsString('✓ .env'.\PHP_EOL, $output);
68
+
69
+ // Skipped Files
70
+ $this->assertStringNotContainsString('.env.prod', $output);
71
+ $this->assertStringNotContainsString('.env.dev', $output);
72
+ $this->assertStringNotContainsString('.env.dist', $output);
73
+
74
+ // Variables
75
+ $this->assertStringContainsString('Variable Value .env.test .env', $output);
76
+ $this->assertStringContainsString('FOO bar n/a bar', $output);
77
+ $this->assertStringContainsString('TEST123 false false true', $output);
78
+ }
79
+
80
+ public function testScenario1InProdEnv()
81
+ {
82
+ $output = $this->executeCommand(__DIR__.'/Fixtures/Scenario1', 'prod');
83
+
84
+ // Scanned Files
85
+ $this->assertStringContainsString('⨯ .env.local.php', $output);
86
+ $this->assertStringContainsString('✓ .env.prod.local', $output);
87
+ $this->assertStringContainsString('⨯ .env.prod', $output);
88
+ $this->assertStringContainsString('✓ .env.local', $output);
89
+ $this->assertStringContainsString('✓ .env'.\PHP_EOL, $output);
90
+
91
+ // Skipped Files
92
+ $this->assertStringNotContainsString('.env.dev', $output);
93
+ $this->assertStringNotContainsString('.env.test', $output);
94
+ $this->assertStringNotContainsString('.env.dist', $output);
95
+
96
+ // Variables
97
+ $this->assertStringContainsString('Variable Value .env.prod.local .env.local .env', $output);
98
+ $this->assertStringContainsString('FOO baz n/a baz bar', $output);
99
+ $this->assertStringContainsString('HELLO world world n/a n/a', $output);
100
+ $this->assertStringContainsString('TEST123 true n/a n/a true', $output);
101
+ }
102
+
103
+ public function testScenario2InProdEnv()
104
+ {
105
+ $output = $this->executeCommand(__DIR__.'/Fixtures/Scenario2', 'prod');
106
+
107
+ // Scanned Files
108
+ $this->assertStringContainsString('✓ .env.local.php', $output);
109
+ $this->assertStringContainsString('⨯ .env.prod.local', $output);
110
+ $this->assertStringContainsString('✓ .env.prod', $output);
111
+ $this->assertStringContainsString('⨯ .env.local', $output);
112
+ $this->assertStringContainsString('✓ .env.dist', $output);
113
+
114
+ // Skipped Files
115
+ $this->assertStringNotContainsString('.env'.\PHP_EOL, $output);
116
+ $this->assertStringNotContainsString('.env.dev', $output);
117
+ $this->assertStringNotContainsString('.env.test', $output);
118
+
119
+ // Variables
120
+ $this->assertStringContainsString('Variable Value .env.local.php .env.prod .env.dist', $output);
121
+ $this->assertStringContainsString('FOO BaR BaR BaR n/a', $output);
122
+ $this->assertStringContainsString('TEST 1234 1234 1234 0000', $output);
123
+ }
124
+
125
+ public function testWarningOnEnvAndEnvDistFile()
126
+ {
127
+ $output = $this->executeCommand(__DIR__.'/Fixtures/Scenario3', 'dev');
128
+
129
+ // Warning
130
+ $this->assertStringContainsString('[WARNING] The file .env.dist gets skipped', $output);
131
+ }
132
+
133
+ public function testWarningOnPhpEnvFile()
134
+ {
135
+ $output = $this->executeCommand(__DIR__.'/Fixtures/Scenario2', 'prod');
136
+
137
+ // Warning
138
+ $this->assertStringContainsString('[WARNING] Due to existing dump file (.env.local.php)', $output);
139
+ }
140
+
141
+ private function executeCommand(string $projectDirectory, string $env): string
142
+ {
143
+ $_SERVER['TEST_ENV_KEY'] = $env;
144
+ (new Dotenv('TEST_ENV_KEY'))->bootEnv($projectDirectory.'/.env');
145
+
146
+ $command = new DebugCommand($env, $projectDirectory);
147
+ $command->setHelperSet(new HelperSet([new FormatterHelper()]));
148
+ $tester = new CommandTester($command);
149
+ $tester->execute([]);
150
+
151
+ return $tester->getDisplay();
152
+ }
153
+ }
vendor/symfony/dotenv/Tests/Command/DotenvDumpCommandTest.php ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Dotenv\Tests\Command;
13
+
14
+ use PHPUnit\Framework\TestCase;
15
+ use Symfony\Component\Console\Application;
16
+ use Symfony\Component\Console\Tester\CommandTester;
17
+ use Symfony\Component\Dotenv\Command\DotenvDumpCommand;
18
+
19
+ class DotenvDumpCommandTest extends TestCase
20
+ {
21
+ protected function setUp(): void
22
+ {
23
+ file_put_contents(__DIR__.'/.env', <<<EOF
24
+ APP_ENV=dev
25
+ APP_SECRET=abc123
26
+ EOF
27
+ );
28
+
29
+ file_put_contents(__DIR__.'/.env.local', <<<EOF
30
+ APP_LOCAL=yes
31
+ EOF
32
+ );
33
+ }
34
+
35
+ protected function tearDown(): void
36
+ {
37
+ @unlink(__DIR__.'/.env');
38
+ @unlink(__DIR__.'/.env.local');
39
+ @unlink(__DIR__.'/.env.local.php');
40
+ @unlink(__DIR__.'/composer.json');
41
+ }
42
+
43
+ public function testExecute()
44
+ {
45
+ $command = $this->createCommand();
46
+ $command->execute([
47
+ 'env' => 'test',
48
+ ]);
49
+
50
+ $this->assertFileExists(__DIR__.'/.env.local.php');
51
+
52
+ $vars = require __DIR__.'/.env.local.php';
53
+ $this->assertSame([
54
+ 'APP_ENV' => 'test',
55
+ 'APP_SECRET' => 'abc123',
56
+ ], $vars);
57
+ }
58
+
59
+ public function testExecuteEmpty()
60
+ {
61
+ $command = $this->createCommand();
62
+ $command->execute([
63
+ 'env' => 'test',
64
+ '--empty' => true,
65
+ ]);
66
+
67
+ $this->assertFileExists(__DIR__.'/.env.local.php');
68
+
69
+ $vars = require __DIR__.'/.env.local.php';
70
+ $this->assertSame(['APP_ENV' => 'test'], $vars);
71
+ }
72
+
73
+ public function testExecuteTestEnvs()
74
+ {
75
+ file_put_contents(__DIR__.'/composer.json', <<<EOF
76
+ {"extra":{"runtime":{"test_envs":[]}}}
77
+ EOF
78
+ );
79
+
80
+ $command = $this->createCommand();
81
+ $command->execute([
82
+ 'env' => 'test',
83
+ ]);
84
+
85
+ $this->assertFileExists(__DIR__.'/.env.local.php');
86
+
87
+ $vars = require __DIR__.'/.env.local.php';
88
+ $this->assertSame([
89
+ 'APP_ENV' => 'test',
90
+ 'APP_SECRET' => 'abc123',
91
+ 'APP_LOCAL' => 'yes',
92
+ ], $vars);
93
+ }
94
+
95
+ private function createCommand(): CommandTester
96
+ {
97
+ $application = new Application();
98
+ $application->add(new DotenvDumpCommand(__DIR__.'/.env'));
99
+
100
+ return new CommandTester($application->find('dotenv:dump'));
101
+ }
102
+ }
vendor/symfony/dotenv/Tests/Command/Fixtures/Scenario1/.env ADDED
@@ -0,0 +1,2 @@
 
 
1
+ TEST123=true
2
+ FOO=bar
vendor/symfony/dotenv/Tests/Command/Fixtures/Scenario1/.env.local ADDED
@@ -0,0 +1 @@
 
1
+ FOO=baz
vendor/symfony/dotenv/Tests/Command/Fixtures/Scenario1/.env.prod.local ADDED
@@ -0,0 +1 @@
 
1
+ HELLO=world
vendor/symfony/dotenv/Tests/Command/Fixtures/Scenario1/.env.test ADDED
@@ -0,0 +1 @@
 
1
+ TEST123=false
vendor/symfony/dotenv/Tests/Command/Fixtures/Scenario2/.env.local.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ return [
3
+ 'FOO' => 'BaR',
4
+ 'TEST' => '1234',
5
+ ];
vendor/symfony/dotenv/Tests/Command/Fixtures/Scenario2/.env.prod ADDED
@@ -0,0 +1,2 @@
 
 
1
+ FOO=BaR
2
+ TEST=1234
vendor/symfony/dotenv/Tests/Command/Fixtures/Scenario3/.env ADDED
@@ -0,0 +1 @@
 
1
+ FOO=BAR
vendor/symfony/dotenv/Tests/DotenvTest.php CHANGED
@@ -226,63 +226,127 @@ class DotenvTest extends TestCase
226
 
227
  public function testLoadEnv()
228
  {
229
- unset($_ENV['FOO']);
230
- unset($_ENV['BAR']);
231
- unset($_SERVER['FOO']);
232
- unset($_SERVER['BAR']);
233
- putenv('FOO');
234
- putenv('BAR');
 
 
 
 
 
 
 
 
235
 
236
  @mkdir($tmpdir = sys_get_temp_dir().'/dotenv');
237
 
238
  $path = tempnam($tmpdir, 'sf-');
239
 
240
  // .env
 
241
 
242
- file_put_contents($path, 'FOO=BAR');
243
  (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
244
  $this->assertSame('BAR', getenv('FOO'));
245
  $this->assertSame('dev', getenv('TEST_APP_ENV'));
 
 
 
 
 
 
 
 
 
246
 
247
  // .env.local
 
248
 
 
249
  $_SERVER['TEST_APP_ENV'] = 'local';
250
- file_put_contents("$path.local", 'FOO=localBAR');
251
  (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
252
  $this->assertSame('localBAR', getenv('FOO'));
 
 
253
 
254
- // special case for test
 
 
 
 
 
255
 
 
 
256
  $_SERVER['TEST_APP_ENV'] = 'test';
257
  (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
258
  $this->assertSame('BAR', getenv('FOO'));
 
 
 
 
 
 
 
 
 
259
 
260
  // .env.dev
 
261
 
262
- unset($_SERVER['TEST_APP_ENV']);
263
- file_put_contents("$path.dev", 'FOO=devBAR');
264
  (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
265
  $this->assertSame('devBAR', getenv('FOO'));
 
 
 
 
 
 
 
 
266
 
267
  // .env.dev.local
 
268
 
269
- file_put_contents("$path.dev.local", 'FOO=devlocalBAR');
270
  (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
271
  $this->assertSame('devlocalBAR', getenv('FOO'));
 
 
 
 
 
 
 
 
 
 
 
272
 
273
  // .env.dist
 
274
 
 
275
  unlink($path);
276
- file_put_contents("$path.dist", 'BAR=distBAR');
277
  (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
278
- $this->assertSame('distBAR', getenv('BAR'));
279
-
280
- putenv('FOO');
281
- putenv('BAR');
 
 
 
 
 
282
  unlink("$path.dist");
283
- unlink("$path.local");
284
- unlink("$path.dev");
285
- unlink("$path.dev.local");
 
286
  rmdir($tmpdir);
287
  }
288
 
@@ -475,26 +539,64 @@ class DotenvTest extends TestCase
475
  $this->assertFalse(getenv('TEST_USE_PUTENV'));
476
  }
477
 
 
 
 
 
 
 
 
 
 
 
478
  public function testBootEnv()
479
  {
 
 
 
 
 
 
 
 
 
480
  @mkdir($tmpdir = sys_get_temp_dir().'/dotenv');
481
  $path = tempnam($tmpdir, 'sf-');
482
 
483
- file_put_contents($path, 'FOO=BAR');
 
484
  (new Dotenv('TEST_APP_ENV', 'TEST_APP_DEBUG'))->bootEnv($path);
485
-
486
  $this->assertSame('BAR', $_SERVER['FOO']);
 
487
 
488
- unset($_SERVER['FOO'], $_ENV['FOO']);
 
 
 
489
  unlink($path);
490
 
491
- file_put_contents($path.'.local.php', '<?php return ["TEST_APP_ENV" => "dev", "FOO" => "BAR"];');
 
492
  (new Dotenv('TEST_APP_ENV', 'TEST_APP_DEBUG'))->bootEnv($path);
493
  $this->assertSame('BAR', $_SERVER['FOO']);
494
  $this->assertSame('1', $_SERVER['TEST_APP_DEBUG']);
 
495
 
496
- unset($_SERVER['FOO'], $_ENV['FOO']);
 
 
 
 
 
 
 
 
 
 
 
497
  unlink($path.'.local.php');
 
 
498
  rmdir($tmpdir);
499
  }
500
  }
226
 
227
  public function testLoadEnv()
228
  {
229
+ $resetContext = static function (): void {
230
+ unset($_ENV['SYMFONY_DOTENV_VARS']);
231
+ unset($_ENV['FOO']);
232
+ unset($_ENV['TEST_APP_ENV']);
233
+ unset($_SERVER['SYMFONY_DOTENV_VARS']);
234
+ unset($_SERVER['FOO']);
235
+ unset($_SERVER['TEST_APP_ENV']);
236
+ putenv('SYMFONY_DOTENV_VARS');
237
+ putenv('FOO');
238
+ putenv('TEST_APP_ENV');
239
+
240
+ $_ENV['EXISTING_KEY'] = $_SERVER['EXISTING_KEY'] = 'EXISTING_VALUE';
241
+ putenv('EXISTING_KEY=EXISTING_VALUE');
242
+ };
243
 
244
  @mkdir($tmpdir = sys_get_temp_dir().'/dotenv');
245
 
246
  $path = tempnam($tmpdir, 'sf-');
247
 
248
  // .env
249
+ file_put_contents($path, "FOO=BAR\nEXISTING_KEY=NEW_VALUE");
250
 
251
+ $resetContext();
252
  (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
253
  $this->assertSame('BAR', getenv('FOO'));
254
  $this->assertSame('dev', getenv('TEST_APP_ENV'));
255
+ $this->assertSame('EXISTING_VALUE', getenv('EXISTING_KEY'));
256
+ $this->assertSame('EXISTING_VALUE', $_ENV['EXISTING_KEY']);
257
+
258
+ $resetContext();
259
+ (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV', 'dev', ['test'], true);
260
+ $this->assertSame('BAR', getenv('FOO'));
261
+ $this->assertSame('dev', getenv('TEST_APP_ENV'));
262
+ $this->assertSame('NEW_VALUE', getenv('EXISTING_KEY'));
263
+ $this->assertSame('NEW_VALUE', $_ENV['EXISTING_KEY']);
264
 
265
  // .env.local
266
+ file_put_contents("$path.local", "FOO=localBAR\nEXISTING_KEY=localNEW_VALUE");
267
 
268
+ $resetContext();
269
  $_SERVER['TEST_APP_ENV'] = 'local';
 
270
  (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
271
  $this->assertSame('localBAR', getenv('FOO'));
272
+ $this->assertSame('EXISTING_VALUE', getenv('EXISTING_KEY'));
273
+ $this->assertSame('EXISTING_VALUE', $_ENV['EXISTING_KEY']);
274
 
275
+ $resetContext();
276
+ $_SERVER['TEST_APP_ENV'] = 'local';
277
+ (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV', 'dev', ['test'], true);
278
+ $this->assertSame('localBAR', getenv('FOO'));
279
+ $this->assertSame('localNEW_VALUE', getenv('EXISTING_KEY'));
280
+ $this->assertSame('localNEW_VALUE', $_ENV['EXISTING_KEY']);
281
 
282
+ // special case for test
283
+ $resetContext();
284
  $_SERVER['TEST_APP_ENV'] = 'test';
285
  (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
286
  $this->assertSame('BAR', getenv('FOO'));
287
+ $this->assertSame('EXISTING_VALUE', getenv('EXISTING_KEY'));
288
+ $this->assertSame('EXISTING_VALUE', $_ENV['EXISTING_KEY']);
289
+
290
+ $resetContext();
291
+ $_SERVER['TEST_APP_ENV'] = 'test';
292
+ (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV', 'dev', ['test'], true);
293
+ $this->assertSame('BAR', getenv('FOO'));
294
+ $this->assertSame('NEW_VALUE', getenv('EXISTING_KEY'));
295
+ $this->assertSame('NEW_VALUE', $_ENV['EXISTING_KEY']);
296
 
297
  // .env.dev
298
+ file_put_contents("$path.dev", "FOO=devBAR\nEXISTING_KEY=devNEW_VALUE");
299
 
300
+ $resetContext();
 
301
  (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
302
  $this->assertSame('devBAR', getenv('FOO'));
303
+ $this->assertSame('EXISTING_VALUE', getenv('EXISTING_KEY'));
304
+ $this->assertSame('EXISTING_VALUE', $_ENV['EXISTING_KEY']);
305
+
306
+ $resetContext();
307
+ (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV', 'dev', ['test'], true);
308
+ $this->assertSame('devBAR', getenv('FOO'));
309
+ $this->assertSame('devNEW_VALUE', getenv('EXISTING_KEY'));
310
+ $this->assertSame('devNEW_VALUE', $_ENV['EXISTING_KEY']);
311
 
312
  // .env.dev.local
313
+ file_put_contents("$path.dev.local", "FOO=devlocalBAR\nEXISTING_KEY=devlocalNEW_VALUE");
314
 
315
+ $resetContext();
316
  (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
317
  $this->assertSame('devlocalBAR', getenv('FOO'));
318
+ $this->assertSame('EXISTING_VALUE', getenv('EXISTING_KEY'));
319
+ $this->assertSame('EXISTING_VALUE', $_ENV['EXISTING_KEY']);
320
+
321
+ $resetContext();
322
+ (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV', 'dev', ['test'], true);
323
+ $this->assertSame('devlocalBAR', getenv('FOO'));
324
+ $this->assertSame('devlocalNEW_VALUE', getenv('EXISTING_KEY'));
325
+ $this->assertSame('devlocalNEW_VALUE', $_ENV['EXISTING_KEY']);
326
+ unlink("$path.local");
327
+ unlink("$path.dev");
328
+ unlink("$path.dev.local");
329
 
330
  // .env.dist
331
+ file_put_contents("$path.dist", "FOO=distBAR\nEXISTING_KEY=distNEW_VALUE");
332
 
333
+ $resetContext();
334
  unlink($path);
 
335
  (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
336
+ $this->assertSame('distBAR', getenv('FOO'));
337
+ $this->assertSame('EXISTING_VALUE', getenv('EXISTING_KEY'));
338
+ $this->assertSame('EXISTING_VALUE', $_ENV['EXISTING_KEY']);
339
+
340
+ $resetContext();
341
+ (new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV', 'dev', ['test'], true);
342
+ $this->assertSame('distBAR', getenv('FOO'));
343
+ $this->assertSame('distNEW_VALUE', getenv('EXISTING_KEY'));
344
+ $this->assertSame('distNEW_VALUE', $_ENV['EXISTING_KEY']);
345
  unlink("$path.dist");
346
+
347
+ $resetContext();
348
+ unset($_ENV['EXISTING_KEY'], $_SERVER['EXISTING_KEY']);
349
+ putenv('EXISTING_KEY');
350
  rmdir($tmpdir);
351
  }
352
 
539
  $this->assertFalse(getenv('TEST_USE_PUTENV'));
540
  }
541
 
542
+ public function testSERVERVarsDuplicationInENV()
543
+ {
544
+ unset($_ENV['SYMFONY_DOTENV_VARS'], $_SERVER['SYMFONY_DOTENV_VARS'], $_ENV['FOO']);
545
+ $_SERVER['FOO'] = 'CCC';
546
+
547
+ (new Dotenv())->populate(['FOO' => 'BAR']);
548
+
549
+ $this->assertSame('CCC', $_ENV['FOO']);
550
+ }
551
+
552
  public function testBootEnv()
553
  {
554
+ $resetContext = static function (): void {
555
+ unset($_SERVER['SYMFONY_DOTENV_VARS'], $_ENV['SYMFONY_DOTENV_VARS']);
556
+ unset($_SERVER['TEST_APP_ENV'], $_ENV['TEST_APP_ENV']);
557
+ unset($_SERVER['TEST_APP_DEBUG'], $_ENV['TEST_APP_DEBUG']);
558
+ unset($_SERVER['FOO'], $_ENV['FOO']);
559
+
560
+ $_ENV['EXISTING_KEY'] = $_SERVER['EXISTING_KEY'] = 'EXISTING_VALUE';
561
+ };
562
+
563
  @mkdir($tmpdir = sys_get_temp_dir().'/dotenv');
564
  $path = tempnam($tmpdir, 'sf-');
565
 
566
+ file_put_contents($path, "FOO=BAR\nEXISTING_KEY=NEW_VALUE");
567
+ $resetContext();
568
  (new Dotenv('TEST_APP_ENV', 'TEST_APP_DEBUG'))->bootEnv($path);
 
569
  $this->assertSame('BAR', $_SERVER['FOO']);
570
+ $this->assertSame('EXISTING_VALUE', $_SERVER['EXISTING_KEY']);
571
 
572
+ $resetContext();
573
+ (new Dotenv('TEST_APP_ENV', 'TEST_APP_DEBUG'))->bootEnv($path, 'dev', ['test'], true);
574
+ $this->assertSame('BAR', $_SERVER['FOO']);
575
+ $this->assertSame('NEW_VALUE', $_SERVER['EXISTING_KEY']);
576
  unlink($path);
577
 
578
+ file_put_contents($path.'.local.php', '<?php return ["TEST_APP_ENV" => "dev", "FOO" => "BAR", "EXISTING_KEY" => "localphpNEW_VALUE"];');
579
+ $resetContext();
580
  (new Dotenv('TEST_APP_ENV', 'TEST_APP_DEBUG'))->bootEnv($path);
581
  $this->assertSame('BAR', $_SERVER['FOO']);
582
  $this->assertSame('1', $_SERVER['TEST_APP_DEBUG']);
583
+ $this->assertSame('EXISTING_VALUE', $_SERVER['EXISTING_KEY']);
584
 
585
+ $resetContext();
586
+ (new Dotenv('TEST_APP_ENV', 'TEST_APP_DEBUG'))->bootEnv($path, 'dev', ['test'], true);
587
+ $this->assertSame('BAR', $_SERVER['FOO']);
588
+ $this->assertSame('1', $_SERVER['TEST_APP_DEBUG']);
589
+ $this->assertSame('localphpNEW_VALUE', $_SERVER['EXISTING_KEY']);
590
+
591
+ $resetContext();
592
+ $_SERVER['TEST_APP_ENV'] = 'ccc';
593
+ (new Dotenv('TEST_APP_ENV', 'TEST_APP_DEBUG'))->bootEnv($path, 'dev', ['test'], true);
594
+ $this->assertSame('BAR', $_SERVER['FOO']);
595
+ $this->assertSame('1', $_SERVER['TEST_APP_DEBUG']);
596
+ $this->assertSame('localphpNEW_VALUE', $_SERVER['EXISTING_KEY']);
597
  unlink($path.'.local.php');
598
+
599
+ $resetContext();
600
  rmdir($tmpdir);
601
  }
602
  }
vendor/symfony/polyfill-ctype/Ctype.php CHANGED
@@ -25,13 +25,13 @@ final class Ctype
25
  *
26
  * @see https://php.net/ctype-alnum
27
  *
28
- * @param string|int $text
29
  *
30
  * @return bool
31
  */
32
  public static function ctype_alnum($text)
33
  {
34
- $text = self::convert_int_to_char_for_ctype($text);
35
 
36
  return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z0-9]/', $text);
37
  }
@@ -41,13 +41,13 @@ final class Ctype
41
  *
42
  * @see https://php.net/ctype-alpha
43
  *
44
- * @param string|int $text
45
  *
46
  * @return bool
47
  */
48
  public static function ctype_alpha($text)
49
  {
50
- $text = self::convert_int_to_char_for_ctype($text);
51
 
52
  return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z]/', $text);
53
  }
@@ -57,13 +57,13 @@ final class Ctype
57
  *
58
  * @see https://php.net/ctype-cntrl
59
  *
60
- * @param string|int $text
61
  *
62
  * @return bool
63
  */
64
  public static function ctype_cntrl($text)
65
  {
66
- $text = self::convert_int_to_char_for_ctype($text);
67
 
68
  return \is_string($text) && '' !== $text && !preg_match('/[^\x00-\x1f\x7f]/', $text);
69
  }
@@ -73,13 +73,13 @@ final class Ctype
73
  *
74
  * @see https://php.net/ctype-digit
75
  *
76
- * @param string|int $text
77
  *
78
  * @return bool
79
  */
80
  public static function ctype_digit($text)
81
  {
82
- $text = self::convert_int_to_char_for_ctype($text);
83
 
84
  return \is_string($text) && '' !== $text && !preg_match('/[^0-9]/', $text);
85
  }
@@ -89,13 +89,13 @@ final class Ctype
89
  *
90
  * @see https://php.net/ctype-graph
91
  *
92
- * @param string|int $text
93
  *
94
  * @return bool
95
  */
96
  public static function ctype_graph($text)
97
  {
98
- $text = self::convert_int_to_char_for_ctype($text);
99
 
100
  return \is_string($text) && '' !== $text && !preg_match('/[^!-~]/', $text);
101
  }
@@ -105,13 +105,13 @@ final class Ctype
105
  *
106
  * @see https://php.net/ctype-lower
107
  *
108
- * @param string|int $text
109
  *
110
  * @return bool
111
  */
112
  public static function ctype_lower($text)
113
  {
114
- $text = self::convert_int_to_char_for_ctype($text);
115
 
116
  return \is_string($text) && '' !== $text && !preg_match('/[^a-z]/', $text);
117
  }
@@ -121,13 +121,13 @@ final class Ctype
121
  *
122
  * @see https://php.net/ctype-print
123
  *
124
- * @param string|int $text
125
  *
126
  * @return bool
127
  */
128
  public static function ctype_print($text)
129
  {
130
- $text = self::convert_int_to_char_for_ctype($text);
131
 
132
  return \is_string($text) && '' !== $text && !preg_match('/[^ -~]/', $text);
133
  }
@@ -137,13 +137,13 @@ final class Ctype
137
  *
138
  * @see https://php.net/ctype-punct
139
  *
140
- * @param string|int $text
141
  *
142
  * @return bool
143
  */
144
  public static function ctype_punct($text)
145
  {
146
- $text = self::convert_int_to_char_for_ctype($text);
147
 
148
  return \is_string($text) && '' !== $text && !preg_match('/[^!-\/\:-@\[-`\{-~]/', $text);
149
  }
@@ -153,13 +153,13 @@ final class Ctype
153
  *
154
  * @see https://php.net/ctype-space
155
  *
156
- * @param string|int $text
157
  *
158
  * @return bool
159
  */
160
  public static function ctype_space($text)
161
  {
162
- $text = self::convert_int_to_char_for_ctype($text);
163
 
164
  return \is_string($text) && '' !== $text && !preg_match('/[^\s]/', $text);
165
  }
@@ -169,13 +169,13 @@ final class Ctype
169
  *
170
  * @see https://php.net/ctype-upper
171
  *
172
- * @param string|int $text
173
  *
174
  * @return bool
175
  */
176
  public static function ctype_upper($text)
177
  {
178
- $text = self::convert_int_to_char_for_ctype($text);
179
 
180
  return \is_string($text) && '' !== $text && !preg_match('/[^A-Z]/', $text);
181
  }
@@ -185,13 +185,13 @@ final class Ctype
185
  *
186
  * @see https://php.net/ctype-xdigit
187
  *
188
- * @param string|int $text
189
  *
190
  * @return bool
191
  */
192
  public static function ctype_xdigit($text)
193
  {
194
- $text = self::convert_int_to_char_for_ctype($text);
195
 
196
  return \is_string($text) && '' !== $text && !preg_match('/[^A-Fa-f0-9]/', $text);
197
  }
@@ -204,11 +204,12 @@ final class Ctype
204
  * (negative values have 256 added in order to allow characters in the Extended ASCII range).
205
  * Any other integer is interpreted as a string containing the decimal digits of the integer.
206
  *
207
- * @param string|int $int
 
208
  *
209
  * @return mixed
210
  */
211
- private static function convert_int_to_char_for_ctype($int)
212
  {
213
  if (!\is_int($int)) {
214
  return $int;
@@ -218,6 +219,10 @@ final class Ctype
218
  return (string) $int;
219
  }
220
 
 
 
 
 
221
  if ($int < 0) {
222
  $int += 256;
223
  }
25
  *
26
  * @see https://php.net/ctype-alnum
27
  *
28
+ * @param mixed $text
29
  *
30
  * @return bool
31
  */
32
  public static function ctype_alnum($text)
33
  {
34
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
35
 
36
  return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z0-9]/', $text);
37
  }
41
  *
42
  * @see https://php.net/ctype-alpha
43
  *
44
+ * @param mixed $text
45
  *
46
  * @return bool
47
  */
48
  public static function ctype_alpha($text)
49
  {
50
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
51
 
52
  return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z]/', $text);
53
  }
57
  *
58
  * @see https://php.net/ctype-cntrl
59
  *
60
+ * @param mixed $text
61
  *
62
  * @return bool
63
  */
64
  public static function ctype_cntrl($text)
65
  {
66
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
67
 
68
  return \is_string($text) && '' !== $text && !preg_match('/[^\x00-\x1f\x7f]/', $text);
69
  }
73
  *
74
  * @see https://php.net/ctype-digit
75
  *
76
+ * @param mixed $text
77
  *
78
  * @return bool
79
  */
80
  public static function ctype_digit($text)
81
  {
82
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
83
 
84
  return \is_string($text) && '' !== $text && !preg_match('/[^0-9]/', $text);
85
  }
89
  *
90
  * @see https://php.net/ctype-graph
91
  *
92
+ * @param mixed $text
93
  *
94
  * @return bool
95
  */
96
  public static function ctype_graph($text)
97
  {
98
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
99
 
100
  return \is_string($text) && '' !== $text && !preg_match('/[^!-~]/', $text);
101
  }
105
  *
106
  * @see https://php.net/ctype-lower
107
  *
108
+ * @param mixed $text
109
  *
110
  * @return bool
111
  */
112
  public static function ctype_lower($text)
113
  {
114
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
115
 
116
  return \is_string($text) && '' !== $text && !preg_match('/[^a-z]/', $text);
117
  }
121
  *
122
  * @see https://php.net/ctype-print
123
  *
124
+ * @param mixed $text
125
  *
126
  * @return bool
127
  */
128
  public static function ctype_print($text)
129
  {
130
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
131
 
132
  return \is_string($text) && '' !== $text && !preg_match('/[^ -~]/', $text);
133
  }
137
  *
138
  * @see https://php.net/ctype-punct
139
  *
140
+ * @param mixed $text
141
  *
142
  * @return bool
143
  */
144
  public static function ctype_punct($text)
145
  {
146
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
147
 
148
  return \is_string($text) && '' !== $text && !preg_match('/[^!-\/\:-@\[-`\{-~]/', $text);
149
  }
153
  *
154
  * @see https://php.net/ctype-space
155
  *
156
+ * @param mixed $text
157
  *
158
  * @return bool
159
  */
160
  public static function ctype_space($text)
161
  {
162
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
163
 
164
  return \is_string($text) && '' !== $text && !preg_match('/[^\s]/', $text);
165
  }
169
  *
170
  * @see https://php.net/ctype-upper
171
  *
172
+ * @param mixed $text
173
  *
174
  * @return bool
175
  */
176
  public static function ctype_upper($text)
177
  {
178
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
179
 
180
  return \is_string($text) && '' !== $text && !preg_match('/[^A-Z]/', $text);
181
  }
185
  *
186
  * @see https://php.net/ctype-xdigit
187
  *
188
+ * @param mixed $text
189
  *
190
  * @return bool
191
  */
192
  public static function ctype_xdigit($text)
193
  {
194
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
195
 
196
  return \is_string($text) && '' !== $text && !preg_match('/[^A-Fa-f0-9]/', $text);
197
  }
204
  * (negative values have 256 added in order to allow characters in the Extended ASCII range).
205
  * Any other integer is interpreted as a string containing the decimal digits of the integer.
206
  *
207
+ * @param mixed $int
208
+ * @param string $function
209
  *
210
  * @return mixed
211
  */
212
+ private static function convert_int_to_char_for_ctype($int, $function)
213
  {
214
  if (!\is_int($int)) {
215
  return $int;
219
  return (string) $int;
220
  }
221
 
222
+ if (\PHP_VERSION_ID >= 80100) {
223
+ @trigger_error($function.'(): Argument of type int will be interpreted as string in the future', \E_USER_DEPRECATED);
224
+ }
225
+
226
  if ($int < 0) {
227
  $int += 256;
228
  }