forked from woocommerce/woocommerce-blocks
-
Notifications
You must be signed in to change notification settings - Fork 0
/
woocommerce-gutenberg-products-block.php
247 lines (219 loc) · 8.9 KB
/
woocommerce-gutenberg-products-block.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
<?php
/**
* Plugin Name: WooCommerce Blocks
* Plugin URI: https://github.com/woocommerce/woocommerce-gutenberg-products-block
* Description: WooCommerce blocks for the Gutenberg editor.
* Version: 6.6.0-dev
* Author: Automattic
* Author URI: https://woocommerce.com
* Text Domain: woo-gutenberg-products-block
* Requires at least: 5.8
* Requires PHP: 7.0
* WC requires at least: 5.8
* WC tested up to: 5.9
*
* @package WooCommerce\Blocks
* @internal This file is only used when running as a feature plugin.
*/
defined( 'ABSPATH' ) || exit;
$minimum_wp_version = '5.8';
if ( ! defined( 'WC_BLOCKS_IS_FEATURE_PLUGIN' ) ) {
define( 'WC_BLOCKS_IS_FEATURE_PLUGIN', true );
}
/**
* Whether notices must be displayed in the current page (plugins and WooCommerce pages).
*
* @since 2.5.0
*/
function should_display_compatibility_notices() {
$current_screen = get_current_screen();
if ( ! isset( $current_screen ) ) {
return false;
}
$is_plugins_page =
property_exists( $current_screen, 'id' ) &&
'plugins' === $current_screen->id;
$is_woocommerce_page =
property_exists( $current_screen, 'parent_base' ) &&
'woocommerce' === $current_screen->parent_base;
return $is_plugins_page || $is_woocommerce_page;
}
if ( version_compare( $GLOBALS['wp_version'], $minimum_wp_version, '<' ) ) {
/**
* Outputs for an admin notice about running WooCommerce Blocks on outdated WordPress.
*
* @since 2.5.0
*/
function woocommerce_blocks_admin_unsupported_wp_notice() {
if ( should_display_compatibility_notices() ) {
?>
<div class="notice notice-error">
<p><?php esc_html_e( 'The WooCommerce Blocks feature plugin requires a more recent version of WordPress and has been paused. Please update WordPress to continue enjoying WooCommerce Blocks.', 'woo-gutenberg-products-block' ); ?></p>
</div>
<?php
}
}
add_action( 'admin_notices', 'woocommerce_blocks_admin_unsupported_wp_notice' );
return;
}
/**
* Returns whether the current version is a development version
* Note this relies on composer.json version, not plugin version.
* Development installs of the plugin don't have a version defined in
* composer json.
*
* @return bool True means the current version is a development version.
*/
function woocommerce_blocks_is_development_version() {
$composer_file = __DIR__ . '/composer.json';
if ( ! is_readable( $composer_file ) ) {
return false;
}
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- including local file
$composer_config = json_decode( file_get_contents( $composer_file ), true );
return ! isset( $composer_config['version'] );
}
/**
* If development version is detected and the Jetpack constant is not defined, show a notice.
*/
if ( woocommerce_blocks_is_development_version() && ! defined( 'JETPACK_AUTOLOAD_DEV' ) ) {
add_action(
'admin_notices',
function() {
echo '<div class="error"><p>';
printf(
/* translators: %1$s is referring to a php constant name, %2$s is referring to the wp-config.php file. */
esc_html__( 'WooCommerce Blocks development mode requires the %1$s constant to be defined and true in your %2$s file. Otherwise you are loading the blocks package from WooCommerce core.', 'woo-gutenberg-products-block' ),
'JETPACK_AUTOLOAD_DEV',
'wp-config.php'
);
echo '</p></div>';
}
);
}
/**
* Autoload packages.
*
* The package autoloader includes version information which prevents classes in this feature plugin
* conflicting with WooCommerce core.
*
* We want to fail gracefully if `composer install` has not been executed yet, so we are checking for the autoloader.
* If the autoloader is not present, let's log the failure and display a nice admin notice.
*/
$autoloader = __DIR__ . '/vendor/autoload_packages.php';
if ( is_readable( $autoloader ) ) {
require $autoloader;
} else {
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( // phpcs:ignore
sprintf(
/* translators: 1: composer command. 2: plugin directory */
esc_html__( 'Your installation of the WooCommerce Blocks feature plugin is incomplete. Please run %1$s within the %2$s directory.', 'woo-gutenberg-products-block' ),
'`composer install`',
'`' . esc_html( str_replace( ABSPATH, '', __DIR__ ) ) . '`'
)
);
}
/**
* Outputs an admin notice if composer install has not been ran.
*/
add_action(
'admin_notices',
function() {
?>
<div class="notice notice-error">
<p>
<?php
printf(
/* translators: 1: composer command. 2: plugin directory */
esc_html__( 'Your installation of the WooCommerce Blocks feature plugin is incomplete. Please run %1$s within the %2$s directory.', 'woo-gutenberg-products-block' ),
'<code>composer install</code>',
'<code>' . esc_html( str_replace( ABSPATH, '', __DIR__ ) ) . '</code>'
);
?>
</p>
</div>
<?php
}
);
return;
}
add_action( 'plugins_loaded', array( '\Automattic\WooCommerce\Blocks\Package', 'init' ) );
/**
* Pre-filters script translations for the given file, script handle and text domain.
*
* @param string|false|null $translations JSON-encoded translation data. Default null.
* @param string|false $file Path to the translation file to load. False if there isn't one.
* @param string $handle Name of the script to register a translation domain to.
* @param string $domain The text domain.
* @return string JSON translations.
*/
function woocommerce_blocks_get_i18n_data_json( $translations, $file, $handle, $domain ) {
if ( 'woo-gutenberg-products-block' !== $domain ) {
return $translations;
}
global $wp_scripts;
if ( ! isset( $wp_scripts->registered[ $handle ], $wp_scripts->registered[ $handle ]->src ) ) {
return $translations;
}
$handle_filename = basename( $wp_scripts->registered[ $handle ]->src );
$locale = determine_locale();
$lang_dir = WP_LANG_DIR . '/plugins';
// Translations are always based on the unminified filename.
if ( substr( $handle_filename, -7 ) === '.min.js' ) {
$handle_filename = substr( $handle_filename, 0, -7 ) . '.js';
}
// WordPress 5.0 uses md5 hashes of file paths to associate translation
// JSON files with the file they should be included for. This is an md5
// of 'packages/woocommerce-blocks/build/FILENAME.js'.
$core_path_md5 = md5( 'packages/woocommerce-blocks/build/' . $handle_filename );
$core_json_file = $lang_dir . '/woocommerce-' . $locale . '-' . $core_path_md5 . '.json';
$json_translations = is_file( $core_json_file ) && is_readable( $core_json_file ) ? file_get_contents( $core_json_file ) : false; // phpcs:ignore
if ( ! $json_translations ) {
return $translations;
}
// Rather than short circuit pre_load_script_translations, we will output
// core translations using an inline script. This will allow us to continue
// to load feature-plugin translations which may exist as well.
$output = <<<JS
( function( domain, translations ) {
var localeData = translations.locale_data[ domain ] || translations.locale_data.messages;
localeData[""].domain = domain;
wp.i18n.setLocaleData( localeData, domain );
} )( "{$domain}", {$json_translations} );
JS;
printf( "<script type='text/javascript'>\n%s\n</script>\n", $output ); // phpcs:ignore
// Finally, short circuit the pre_load_script_translations hook by returning
// the translation JSON from the feature plugin, if it exists so this hook
// does not run again for the current handle.
$path_md5 = md5( 'build/' . $handle_filename );
$json_file = $lang_dir . '/' . $domain . '-' . $locale . '-' . $path_md5 . '.json';
$translations = is_file( $json_file ) && is_readable( $json_file ) ? file_get_contents( $json_file ) : false; // phpcs:ignore
if ( $translations ) {
return $translations;
}
// Return valid empty Jed locale.
return '{ "locale_data": { "messages": { "": {} } } }';
}
add_filter( 'pre_load_script_translations', 'woocommerce_blocks_get_i18n_data_json', 10, 4 );
/**
* Filter translations so we can retrieve translations from Core when the original and the translated
* texts are the same (which happens when translations are missing).
*
* @param string $translation Translated text based on WC Blocks translations.
* @param string $text Text to translate.
* @param string $domain The text domain.
* @return string WC Blocks translation. In case it's the same as $text, Core translation.
*/
function woocommerce_blocks_get_php_translation_from_core( $translation, $text, $domain ) {
if ( 'woo-gutenberg-products-block' !== $domain ) {
return $translation;
}
// When translation is the same, that could mean the string is not translated.
// In that case, load it from core.
if ( $translation === $text ) {
return translate( $text, 'woocommerce' ); // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction, WordPress.WP.I18n.NonSingularStringLiteralText, WordPress.WP.I18n.TextDomainMismatch
}
return $translation;
}
add_filter( 'gettext', 'woocommerce_blocks_get_php_translation_from_core', 10, 3 );