PluginProbe
Photo Gallery by Re Gallery: Responsive Image Gallery with AI SEO / trunk
Photo Gallery by Re Gallery: Responsive Image Gallery with AI SEO vtrunk
1.20.14 1.20.13 1.20.12 1.20.11 1.20.10 1.20.9 1.20.8 1.20.7 1.20.6 1.20.5 1.20.4 1.20.3 1.20.2 1.20.1 1.20.0 1.19.2 1.19.1 1.19.0 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 All 135 releases
regallery / gallery.php

gallery.php in Photo Gallery by Re Gallery: Responsive Image Gallery with AI SEO trunk, at gallery.php

691 lines 28.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: Photo Gallery by Re Gallery: Responsive Image Gallery with AI SEO
4 * Description: Photo gallery plugin that writes your image SEO with a built-in AI. Create responsive image galleries in minutes.
5 * Version: 1.20.14
6 * Requires at least: 5.0
7 * Requires PHP: 7.0
8 * Author: Re Gallery Team
9 * Plugin URI: https://regallery.team/?utm_source=wordpress_plugin&utm_medium=plugin_uri
10 * Author URI: https://regallery.team/?utm_source=wordpress_plugin&utm_medium=auhor_uri
11 * Text Domain: regallery
12 * License: GPLv2 or later
13 * License URI: http://www.gnu.org/licenses/gpl-2.0.html
14 */
15
16 defined('ABSPATH') || die('Access Denied');
17
18 final class REACG {
19 /**
20 * The single instance of the class.
21 */
22 protected static $_instance = null;
23
24 public $plugin_dir = '';
25 public $plugin_url = '';
26 public $main_file = '';
27 public $version = '1.20.14';
28 public $prefix = 'reacg';
29 public $shortcode = 'REACG';
30 public $nicename = 'Re Gallery';
31 public $author = 'Re Gallery Team';
32 public $website_url = 'https://regallery.team';
33 public $pricing_url = 'https://regallery.team/pricing';
34 public $demo_url = 'https://regallery.team/core/demo/';
35 public $blog_url = 'https://regallery.team/core/blog/';
36 public $wp_plugin_url = "https://wordpress.org/support/plugin/regallery";
37 public $core_rest_url_v1 = "https://regallery.team/core/wp-json/reacgcore/v1/";
38 public $core_rest_url_v2 = "https://regallery.team/core/wp-json/reacgcore/v2/";
39 public $core_rest_url_v3 = "https://regallery.team/core/wp-json/reacgcore/v3/";
40 public $nonce = 'reacg_nonce';
41 public $rest_root = "";
42 public $rest_nonce = "";
43 public $no_image = '/assets/images/no_image.png';
44 /* $abspath variable is using as defined APSPATH doesn't work in wordpress.com */
45 public $abspath = '';
46
47 public $allowed_post_types = [];
48 public $woocommerce_is_active = FALSE;
49
50 /**
51 * Ensures only one instance is loaded or can be loaded.
52 *
53 * @return self|null
54 */
55 public static function instance() {
56 if ( is_null( self::$_instance ) ) {
57 self::$_instance = new self();
58 }
59 return self::$_instance;
60 }
61
62 public function __construct() {
63 $this->define_constants();
64 $this->add_actions();
65 }
66
67 private function define_constants() {
68 $this->plugin_dir = WP_PLUGIN_DIR . "/" . plugin_basename(dirname(__FILE__));
69
70 require_once $this->plugin_dir . '/framework/REACGLibrary.php';
71
72 $this->abspath = REACGLibrary::get_abspath();
73 $this->plugin_url = plugins_url(plugin_basename(dirname(__FILE__)));
74 $this->main_file = plugin_basename(__FILE__);
75
76 add_action('init', array($this, 'define_translatable_constants'));
77
78 define('REACG_PLUGIN_DIR', $this->plugin_dir );
79 define('REACG_PLUGIN_URL', $this->plugin_url );
80 $plugin_assets_base_url = $this->plugin_url;
81 // Some hosts inject query tokens before the real path.
82 // Remove only that token while keeping the path segment.
83 $plugin_assets_base_url = preg_replace('/\?[^\/]+(?=\/)/', '', $plugin_assets_base_url);
84 // Also strip any regular trailing query/hash if present.
85 $plugin_assets_base_url = preg_replace('/[?#].*$/', '', $plugin_assets_base_url);
86 define('REACG_PLUGIN_ASSETS_URL', rtrim($plugin_assets_base_url, '/') . '/assets/js/' );
87 define('REACG_CUSTOM_POST_TYPE', 'reacg' );
88 define('REACG_PREFIX', $this->prefix );
89 define('REACG_NICENAME', $this->nicename );
90 define('REACG_AUTHOR', $this->author );
91 define('REACG_WEBSITE_URL', $this->website_url );
92 define('REACG_WEBSITE_URL_UTM', add_query_arg(['utm_source' => 'wordpress_plugin', 'utm_content' => $this->version], $this->website_url) );
93 define('REACG_PRICING_URL', $this->pricing_url );
94 define('REACG_PRICING_URL_UTM', add_query_arg(['utm_source' => 'wordpress_plugin', 'utm_content' => $this->version], $this->pricing_url) );
95 define('REACG_BLOG_URL', $this->blog_url );
96 define('REACG_BLOG_URL_UTM', add_query_arg(['utm_source' => 'wordpress_plugin', 'utm_content' => $this->version], $this->blog_url) );
97 define('REACG_DEMO_URL', $this->demo_url );
98 define('REACG_DEMO_URL_UTM', add_query_arg(['utm_source' => 'wordpress_plugin', 'utm_content' => $this->version], $this->demo_url) );
99 define('REACG_VERSION', $this->version );
100 define('REACG_NONCE', $this->nonce );
101 define('REACG_WP_PLUGIN_URL', $this->wp_plugin_url );
102 define('REACG_WP_PLUGIN_SUPPORT_URL', $this->wp_plugin_url . '/#new-topic-0' );
103 define('REACG_WP_PLUGIN_REVIEW_URL', $this->wp_plugin_url . '/reviews#new-post' );
104 define('REACG_PLAYGROUND', strpos($this->plugin_url, 'playground.wordpress.net') !== FALSE );
105 define('REACG_FREE_TRIAL_DAYS', 7);
106 }
107
108 /**
109 * Actions.
110 */
111 private function add_actions() {
112 add_action('init', array($this, 'post_type_gallery'), 9);
113 add_action('init', array($this, 'shortcode'));
114 add_action('init', array($this, 'deactivation'));
115 add_action('init', array($this, 'form'));
116 add_action('init', array($this, 'demo'));
117 add_action('init', array($this, 'migration'));
118
119 // Register scripts/styles.
120 add_action('wp_enqueue_scripts', array($this, 'register_frontend_scripts'));
121 add_action('admin_enqueue_scripts', array($this, 'register_admin_scripts'));
122
123 // Enqueue block editor assets for Gutenberg.
124 add_action('enqueue_block_editor_assets', array($this, 'enqueue_block_editor_assets'));
125 add_action('enqueue_block_assets', array($this, 'enqueue_block_assets'));
126
127 // Register widget for Elementor.
128 add_action('elementor/widgets/widgets_registered', array($this, 'register_elementor_widget'));
129 // Fires after elementor editor styles are enqueued.
130 add_action('elementor/editor/after_enqueue_styles', array($this, 'enqueue_elementor_styles'), 11);
131
132 // Register Divi module.
133 add_action( 'divi_extensions_init', array($this, 'initialize_divi_extension') );
134 add_action( 'wp_ajax_reacg_divi_preview', array( $this, 'reacg_divi_preview' ) );
135
136 // Register WP Bakery widget.
137 add_action( 'vc_before_init', array($this, 'register_wpbakery_widget') );
138
139 // Register Beaver Builder module.
140 add_action( 'init', array($this, 'register_buiver_builder_widget') );
141
142 // Register Bricks Builder element.
143 add_action( 'init', array($this, 'register_bricks_builder_element'), 11);
144
145 // Actions on the plugin activate/deactivate.
146 register_activation_hook(__FILE__, array($this, 'global_activate'));
147 add_action('wpmu_new_blog', array($this, 'new_blog_added'), 10, 6);
148 register_deactivation_hook( __FILE__, array($this, 'global_deactivate'));
149
150 add_action('init', array($this, 'load_string'), 8);
151 add_action('admin_init', array($this, 'do_activation_redirect'));
152
153 add_filter('body_class', [$this, 'add_body_class']);
154
155 require_once ($this->plugin_dir . '/includes/admin-notices.php');
156 new REACG_Admin_Notices();
157 }
158
159 public function add_body_class($classes) {
160 if (defined('REACG_VERSION')) {
161 $classes[] = 'reacg';
162 }
163
164 return $classes;
165 }
166
167 /**
168 * Translations should be loaded at the init.
169 *
170 * @return void
171 */
172 public function define_translatable_constants() {
173 $this->allowed_post_types = [
174 'post' => ['title' => __('Posts', 'regallery'), 'class' => 'dashicons-admin-post'],
175 'page' => ['title' => __('Pages', 'regallery'), 'class' => 'dashicons-admin-page'],
176 'postdynamic' => ['title' => __('Posts', 'regallery'), 'class' => 'dashicons-admin-post reacg-dynamic'],
177 'pagedynamic' => ['title' => __('Pages', 'regallery'), 'class' => 'dashicons-admin-page reacg-dynamic'],
178 ];
179 $this->woocommerce_is_active = class_exists( 'WooCommerce' );
180 if ( $this->woocommerce_is_active ) {
181 $this->allowed_post_types['product'] = [ 'title' => __('WooCommerce Products', 'regallery'), 'class' => 'dashicons-archive' ];
182 $this->allowed_post_types['productdynamic'] = [ 'title' => __('WooCommerce Products', 'regallery'), 'class' => 'dashicons-archive reacg-dynamic' ];
183 }
184
185 define('REACG_ALLOWED_POST_TYPES', $this->allowed_post_types);
186 define('REACG_BUY_NOW_TEXT', esc_html__('Upgrade to Pro', 'regallery') );
187 }
188
189 /**
190 * Load translated strings.
191 */
192 public function load_string() {
193 load_plugin_textdomain( 'reacg', false, plugin_basename(dirname(__FILE__)) . '/languages' );
194 }
195
196 /**
197 * Register widget for Elementor.
198 */
199 public function register_elementor_widget() {
200 if ( defined('ELEMENTOR_PATH') && class_exists('Elementor\Widget_Base') ) {
201 require_once ($this->plugin_dir . '/builders/elementor/elementor.php');
202 if ( \Elementor\Plugin::instance()->preview->is_preview_mode() ) {
203 // Enqueue scripts only in preview mode.
204 REACGLibrary::enqueue_scripts();
205 }
206 \Elementor\Plugin::instance()->widgets_manager->register( new REACG_Elementor() );
207 }
208 }
209
210 /**
211 * Enqueue Elementor widget styles.
212 *
213 * @return void
214 */
215 public function enqueue_elementor_styles() {
216 wp_enqueue_style($this->prefix . '_elementor', $this->plugin_url . '/builders/elementor/styles/elementor.css', [], $this->version);
217 }
218
219 public function initialize_divi_extension() {
220 // Check for Divi 5 support first.
221 // ET_Core_PortablePlugin is not always loaded this early on frontend requests,
222 // so rely on the version constant here and let the module self-guard later.
223 if ( defined( 'ET_CORE_VERSION' ) ) {
224 $divi_version = (int) explode('.', ET_CORE_VERSION)[0];
225
226 // Load appropriate extension based on Divi version
227 if ( $divi_version >= 5 ) {
228 // $this->divi5_loaded = TRUE;
229 require_once ($this->plugin_dir . '/builders/divi/includes/divi-5.php');
230 } else {
231 // Divi 4 support
232 if ( class_exists( 'ET_Builder_Element' ) ) {
233 require_once ($this->plugin_dir . '/builders/divi/includes/divi.php');
234 }
235 }
236 } elseif ( class_exists( 'ET_Builder_Element' ) ) {
237 // Fallback for older Divi versions without ET_CORE_VERSION
238 require_once ($this->plugin_dir . '/builders/divi/includes/divi.php');
239 }
240 }
241
242 /**
243 * AJAX preview endpoint for the Divi 5 module.
244 *
245 * Divi's extension bootstrap is not guaranteed to run on admin-ajax requests,
246 * so we register the endpoint from the plugin bootstrap and load the module on demand.
247 */
248 public function reacg_divi_preview() {
249 require_once $this->plugin_dir . '/builders/divi/includes/REACGDivi5Module.php';
250
251 if ( class_exists( 'REACG_Divi5Module' ) ) {
252 $module = new REACG_Divi5Module();
253 $module->preview();
254 }
255
256 wp_send_json_error(
257 array(
258 'message' => esc_html__( 'Unable to load the Divi preview handler.', 'regallery' ),
259 ),
260 500
261 );
262 }
263
264 public function register_wpbakery_widget() {
265 if ( ! function_exists( 'vc_map' ) ) {
266 return;
267 }
268 REACGLibrary::enqueue_scripts();
269 require_once ($this->plugin_dir . '/builders/wpbakery/wpbakery.php');
270
271 new REACG_WPBakery($this);
272 }
273
274 public function register_buiver_builder_widget() {
275 if ( class_exists( 'FLBuilder' ) ) {
276 require_once $this->plugin_dir . '/builders/beaverbuilder/beaverbuilder.php';
277 }
278 }
279
280 public function register_bricks_builder_element($elements_manager) {
281 if ( !class_exists('\Bricks\Elements') ) {
282 return;
283 }
284
285 \Bricks\Elements::register_element( $this->plugin_dir . '/builders/bricks/bricks.php' );
286 }
287
288 /**
289 * Create custom post types.
290 */
291 public function post_type_gallery() {
292 $this->rest_root = rest_url() . "reacg/v1/";
293 $this->rest_nonce = wp_create_nonce( 'wp_rest' );
294 define('REACG_REST_NONCE', $this->rest_nonce );
295 require_once($this->plugin_dir . '/includes/gallery.php');
296 new REACG_Gallery( $this );
297 require_once($this->plugin_dir . '/includes/posts.php');
298 new REACG_Posts( $this );
299 }
300
301 /**
302 * Add a shortcode.
303 */
304 public function shortcode() {
305 require_once($this->plugin_dir . '/includes/shortcode.php');
306 new REACG_Shortcode( $this );
307 }
308
309 /**
310 * Add a functional to the deactivation.
311 */
312 public function deactivation() {
313 require_once($this->plugin_dir . '/includes/deactivate.php');
314 new REACG_Deactivate( $this );
315 }
316
317 public function form() {
318 require_once($this->plugin_dir . '/includes/form.php');
319 new REACG_Form( $this, 'support' );
320 }
321
322 /**
323 * Add a functional to import demo content.
324 */
325 public function demo($redirect = FALSE) {
326 require_once($this->plugin_dir . '/includes/demo.php');
327 return new REACG_Demo($redirect);
328 }
329
330 /**
331 * Register universal migration engine.
332 */
333 public function migration() {
334 require_once($this->plugin_dir . '/includes/migration.php');
335 new REACG_Migration($this);
336 }
337
338 /**
339 * Register general scripts/styles.
340 */
341 private function register_general_scripts() {
342 $required_scripts = [];
343 $required_styles = [];
344
345 $used_fonts = is_admin() ? REACGLibrary::get_fonts(FALSE) : REACGLibrary::get_used_fonts();
346 if ( !empty($used_fonts) ) {
347 // Google Fonts CSS API allows a maximum of 120 font families per request.
348 // We chunk the font array into groups of 100 to avoid the "403: Too many font families requested" error.
349 $chunks = array_chunk($used_fonts, 100);
350 foreach ( $chunks as $i => $chunk ) {
351 $query = implode("|", str_replace(' ', '+', $chunk));
352
353 $url = 'https://fonts.googleapis.com/css?family=' . $query;
354 $url .= '&subset=greek,latin,greek-ext,vietnamese,cyrillic-ext,latin-ext,cyrillic';
355 $version = md5( $url ); // Cache bust when fonts change
356 $handle = $this->prefix . '_fonts_' . $i;
357 wp_register_style($handle, $url, [], $version);
358 $required_styles[] = $handle;
359 }
360 }
361
362 wp_register_style($this->prefix . '_general', $this->plugin_url . '/assets/css/general.css', $required_styles, $this->version);
363 wp_register_script($this->prefix . '_thumbnails', $this->plugin_url . '/assets/js/wp-gallery.js', $required_scripts, $this->version, TRUE);
364 wp_localize_script( $this->prefix . '_thumbnails', 'reacg_global', array(
365 'rest_root' => esc_url_raw( $this->rest_root ),
366 'rest_nonce' => $this->rest_nonce,
367 'plugin_url' => $this->plugin_url,
368 'plugin_assets_url' => REACG_PLUGIN_ASSETS_URL,
369 'upgrade' => [
370 'text' => REACG_BUY_NOW_TEXT,
371 'url' => add_query_arg( ['utm_campaign' => 'upgrade'], REACG_PRICING_URL_UTM ),
372 'discount_url' => add_query_arg( ['utm_campaign' => 'upgrade_with_discount'], REACG_PRICING_URL_UTM ),
373 ],
374 'demo_url' => add_query_arg( ['utm_campaign' => 'view_demo'], REACG_DEMO_URL_UTM ),
375 'layout_urls' => [
376 'coverflow' => add_query_arg(['utm_campaign' => 'view_layout_demo', 'utm_source' => 'wordpress_plugin', 'utm_content' => $this->version], $this->website_url . '/core/reacg/depthflow/'),
377 'justified' => add_query_arg(['utm_campaign' => 'view_layout_demo', 'utm_source' => 'wordpress_plugin', 'utm_content' => $this->version], $this->website_url . '/core/reacg/smart-rows/'),
378 'cards' => add_query_arg(['utm_campaign' => 'view_layout_demo', 'utm_source' => 'wordpress_plugin', 'utm_content' => $this->version], $this->website_url . '/core/reacg/spotlight-ad/'),
379 'scroller' => add_query_arg(['utm_campaign' => 'view_layout_demo', 'utm_source' => 'wordpress_plugin', 'utm_content' => $this->version], $this->website_url . '/core/reacg/active-drift/'),
380 ],
381 'compare_plans_url' => add_query_arg( ['utm_campaign' => 'see_all_features'], REACG_PRICING_URL_UTM . '#see-all-features' ),
382 'support_url' => REACG_WP_PLUGIN_SUPPORT_URL,
383 'trial_days' => REACG_FREE_TRIAL_DAYS,
384 'core_rest_url_v1' => $this->core_rest_url_v1,
385 'core_rest_url_v2' => $this->core_rest_url_v2,
386 'core_rest_url_v3' => $this->core_rest_url_v3,
387 'text' => [
388 'load_more' => __('Load more', 'regallery'),
389 'view_more' => __('View more', 'regallery'),
390 'search' => __('Search', 'regallery'),
391 'no_data' => __('There is not data.', 'regallery'),
392 ],
393 ) );
394 }
395
396 /**
397 * Register admin pages scripts/styles.
398 */
399 public function register_admin_scripts() {
400 $required_scripts = array(
401 'jquery',
402 'jquery-ui-sortable',
403 );
404 $required_styles = array(
405 'wp-admin', // admin styles
406 'buttons', // buttons styles
407 'media-views', // media uploader styles
408 'wp-auth-check', // check all
409 );
410
411 wp_register_style($this->prefix . '_select2', $this->plugin_url . '/assets/css/select2.min.css', [], '4.0.3');
412 wp_register_style($this->prefix . '_posts', $this->plugin_url . '/assets/css/posts.css', [$this->prefix . '_select2'], $this->version);
413 $required_styles[] = $this->prefix . '_posts';
414 wp_register_style($this->prefix . '_admin', $this->plugin_url . '/assets/css/admin.css', $required_styles, $this->version);
415 wp_register_style($this->prefix . '_widget_box', $this->plugin_url . '/assets/css/widget_box.css', [], $this->version);
416 wp_register_script($this->prefix . '_widget_box', $this->plugin_url . '/assets/js/widget_box.js', ['jquery'], $this->version, true);
417
418 wp_register_script($this->prefix . '_select2', $this->plugin_url . '/assets/js/select2.min.js', ['jquery'], '4.0.3', TRUE);
419 wp_register_script($this->prefix . '_posts', $this->plugin_url . '/assets/js/posts.js', [$this->prefix . '_select2'], $this->version, TRUE);
420 $required_scripts[] = $this->prefix . '_posts';
421 wp_register_script($this->prefix . '_admin', $this->plugin_url . '/assets/js/admin.js', $required_scripts, $this->version, TRUE);
422 wp_localize_script($this->prefix . '_admin', 'reacg', array(
423 'insert' => __('Insert', 'regallery'),
424 'update' => __('Update', 'regallery'),
425 'update_thumbnail' => __('Update video cover', 'regallery'),
426 'edit' => __('Edit', 'regallery'),
427 'edit_thumbnail' => __('Edit video cover', 'regallery'),
428 'attachment_filename' => __('Filename', 'regallery'),
429 'attachment_dimensions' => __('Dimensions', 'regallery'),
430 'attachment_file_size' => __('File size', 'regallery'),
431 'attachment_title' => __('Title', 'regallery'),
432 'attachment_caption' => __('Caption', 'regallery'),
433 'attachment_alt_text' => __('Alt text', 'regallery'),
434 'attachment_description' => __('Description', 'regallery'),
435 'attachment_action_url' => __('Action URL', 'regallery'),
436 'attachment_metadata_exif' => __('Metadata (EXIF)', 'regallery'),
437 'choose_images' => __('Choose images', 'regallery'),
438 'generate' => __('Generate', 'regallery'),
439 'regenerate' => __('Regenerate', 'regallery'),
440 'proceed' => __('Proceed', 'regallery'),
441 'only_empty_fields' => __('Only empty fields', 'regallery'),
442 'replace_existing' => __('Replace existing content', 'regallery'),
443 'overwrite_existing' => __('Overwrite existing content?', 'regallery'),
444 'choose_what_to_generate' => __('Choose what to generate for the gallery items', 'regallery'),
445 'ai_generate_content' => __('AI Generate Content', 'regallery'),
446 'processing' => __('Processing', 'regallery'),
447 'content_generated_successfully' => __('Content generated successfully.', 'regallery'),
448 'no_fields_to_generate' => __('Nothing to generate for the items. All selected fields already contain content.', 'regallery'),
449 'content_generated_based_on_image' => __('The content will be generated based on the image and will be automatically saved.', 'regallery'),
450 'save_failed' => __('Unable to save image data.', 'regallery'),
451 'ai_popup_additional_notes_label' => __('Additional Notes', 'regallery'),
452 'ai_popup_additional_notes_placeholder' => __('You can add additional notes here to help generate a more accurate text.', 'regallery'),
453 'ai_popup_title_heading' => __('Generative AI Title', 'regallery'),
454 'ai_popup_title_field_label' => __('Generated Title', 'regallery'),
455 'ai_popup_title_notice' => __('The title will be generated based on the image.', 'regallery'),
456 'ai_popup_caption_heading' => __('Generative AI Caption', 'regallery'),
457 'ai_popup_caption_field_label' => __('Generated Caption', 'regallery'),
458 'ai_popup_caption_notice' => __('The caption will be generated based on the image.', 'regallery'),
459 'ai_popup_description_heading' => __('Generative AI Description', 'regallery'),
460 'ai_popup_description_field_label' => __('Generated Description', 'regallery'),
461 'ai_popup_description_notice' => __('The description will be generated based on the image.', 'regallery'),
462 'ai_popup_alt_heading' => __('Generative AI Alt text', 'regallery'),
463 'ai_popup_alt_field_label' => __('Generated Alt text', 'regallery'),
464 'ai_popup_alt_notice' => __('The alt text will be generated based on the image.', 'regallery'),
465 'ai_highlight' => __('Use our built-in AI tools to instantly generate a Title, Caption, Description, and Alt text. Ideal for better SEO and accessibility.', 'regallery'),
466 'enter_license_key' => __('Please enter license key.', 'regallery'),
467 'no_image' => $this->plugin_url . $this->no_image,
468 'website_language' => get_locale(),
469 'user_language' => get_user_locale(),
470 'rest_nonce' => $this->rest_nonce,
471 'nonce' => wp_create_nonce( $this->nonce ),
472 'allowed_post_types' => REACG_ALLOWED_POST_TYPES,
473 'ajax_url' => wp_nonce_url(admin_url('admin-ajax.php'), $this->nonce, $this->nonce),
474 'core_rest_url_v1' => $this->core_rest_url_v1,
475 'core_rest_url_v2' => $this->core_rest_url_v2,
476 'core_rest_url_v3' => $this->core_rest_url_v3,
477 ));
478
479 // Register general styles/scripts.
480 $this->register_general_scripts();
481
482 $this->enqueue_common_assets();
483 }
484
485 /**
486 * Enqueue common assets for admin.
487 */
488 private function enqueue_common_assets() {
489 wp_enqueue_style( $this->prefix . '_common_admin', $this->plugin_url . '/assets/css/common.css', [], $this->version );
490 }
491
492 /**
493 * Register frontend scripts and styles.
494 */
495 public function register_frontend_scripts() {
496 $this->register_general_scripts();
497 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce is not required.
498 if ( isset($_GET['bricks']) && $_GET['bricks'] === 'run' ) {
499 wp_enqueue_style($this->prefix . '_bricks', $this->plugin_url . '/builders/bricks/bricks.css', [], '1.0');
500 }
501 }
502
503 /**
504 * Enqueue scripts/styles for Gutenberg.
505 *
506 * @return void
507 */
508 public function enqueue_block_assets() {
509 // Always load inside editor iframe (Need to correctly enqueue frontend scripts/styles in iframe for changing between Tablet/Mobile views.)
510 // Frontend: load ONLY if block exists․
511 if ( is_admin() || ( function_exists( 'has_block' ) && has_block( 'reacg/gallery' ) ) ) {
512 $this->register_frontend_scripts();
513 REACGLibrary::enqueue_scripts();
514 }
515 // Canvas-only editor styles must also load inside the iframe (WP 7.1+).
516 // Sidebar styles stay on enqueue_block_editor_assets.
517 if ( is_admin() ) {
518 wp_enqueue_style(
519 $this->prefix . '_gutenberg_canvas',
520 $this->plugin_url . '/builders/gutenberg/styles/gutenberg.css',
521 array( $this->prefix . '_general' ),
522 $this->version
523 );
524 }
525 }
526
527 /**
528 * Enqueue scripts/styles for Gutenberg.
529 *
530 * @return void
531 */
532 public function enqueue_block_editor_assets() {
533 $required_scripts = [
534 $this->prefix . '_thumbnails',
535 'wp-blocks',
536 'wp-element',
537 'wp-block-editor',
538 'wp-components',
539 $this->prefix . '_admin'
540 ];
541 $required_styles = [
542 $this->prefix . '_general',
543 'wp-edit-blocks',
544 $this->prefix . '_admin'
545 ];
546
547 wp_enqueue_script($this->prefix . '_gutenberg', $this->plugin_url . '/builders/gutenberg/scripts/gutenberg.js', $required_scripts, $this->version, TRUE);
548 wp_localize_script($this->prefix . '_gutenberg', 'reacg_gutenberg', array(
549 'title' => $this->nicename,
550 'description' => __("Display images with various visual effects in responsive gallery.", "regallery"),
551 'setup_wizard_description' => __("Create new gallery or select the existing one.", "regallery"),
552 'gallery_images_section_title' => __("Media", "regallery"),
553 'create_button' => __("Create", "regallery"),
554 'gallery_title_placeholder' => __("Enter gallery title", "regallery"),
555 'plugin_url' => $this->plugin_url,
556 'plugin_version' => $this->version,
557 'icon' => $this->plugin_url . '/assets/images/icon.svg',
558 'data' => REACGLibrary::get_shortcodes($this, TRUE),
559 'ajax_url' => wp_nonce_url(admin_url('admin-ajax.php'), $this->nonce, $this->nonce),
560 ));
561 $gallery_ids = REACGLibrary::get_galleries();
562 $data = [];
563 foreach ( $gallery_ids as $galleryId ) {
564 $data[$galleryId] = REACGLibrary::get_data($galleryId);
565 }
566 wp_localize_script(REACG_PREFIX . '_gutenberg', 'reacg_data', $data);
567 wp_enqueue_style($this->prefix . '_gutenberg', $this->plugin_url . '/builders/gutenberg/styles/gutenberg.css', $required_styles, $this->version);
568 }
569
570 /**
571 * Global activate.
572 *
573 * @param $networkwide
574 */
575 public function global_activate($networkwide) {
576 if ( function_exists('is_multisite') && is_multisite() ) {
577 // Run the activation function for each blog, if it is a network activation.
578 if ( $networkwide ) {
579 $sites = get_sites( [
580 'fields' => 'ids',
581 ] );
582 if ( !empty( $sites ) ) {
583 foreach ( $sites as $blog_id ) {
584 switch_to_blog($blog_id);
585 $this->activate();
586 restore_current_blog();
587 }
588 }
589
590 return;
591 }
592 }
593 $this->activate();
594 }
595
596 public function new_blog_added( $blog_id, $user_id, $domain, $path, $site_id, $meta ) {
597 if ( is_plugin_active_for_network('gallery/gallery.php') ) {
598 switch_to_blog($blog_id);
599 $this->activate();
600 restore_current_blog();
601 }
602 }
603
604 /**
605 * Activate.
606 *
607 * @param $activate
608 *
609 * @return void
610 */
611 public function activate($activate = TRUE) {
612 // Register the custom post type on activate also to affect recreation of rewrite rules.
613 $this->post_type_gallery();
614 // Recreate rewrite rules after registering the new custom post type to ensure the new post permalinks work.
615 global $wp_rewrite;
616 $wp_rewrite->init();
617 $wp_rewrite->flush_rules();
618
619 if ( $activate ) {
620 add_option( 'reacg_do_activation_redirect', true );
621 // Set installation time.
622 REACGLibrary::installed_time();
623
624 // Add default options.
625 require_once REACG()->plugin_dir . "/includes/options.php";
626 new REACG_Options(TRUE);
627 }
628 else {
629 delete_option('reacg_optin_shown');
630 }
631 }
632
633 public function do_activation_redirect() {
634 if ( get_option( 'reacg_do_activation_redirect', FALSE ) ) {
635 delete_option( 'reacg_do_activation_redirect' );
636
637 // Avoid redirect on bulk activation
638 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce is not required.
639 if ( !isset( $_GET['activate-multi'] ) ) {
640 if ( REACG_PLAYGROUND ) {
641 $demo = $this->demo(TRUE);
642 $link = $demo->import_data(FALSE);
643 if ( !empty($link) ) {
644 wp_safe_redirect($link);
645 exit;
646 }
647 }
648 wp_safe_redirect( admin_url( 'edit.php?post_type=' . REACG_CUSTOM_POST_TYPE ) );
649 exit;
650 }
651 }
652 }
653
654 /**
655 * Global deactivate.
656 *
657 * @param $networkwide
658 */
659 public function global_deactivate($networkwide) {
660 if ( function_exists('is_multisite') && is_multisite() ) {
661 // Run the deactivation function for each blog, if it is a network deactivation.
662 if ( $networkwide ) {
663 $sites = get_sites( [
664 'fields' => 'ids',
665 ] );
666 if ( !empty( $sites ) ) {
667 foreach ( $sites as $blog_id ) {
668 switch_to_blog( $blog_id );
669 $this->activate( false );
670 restore_current_blog();
671 }
672 }
673
674 return;
675 }
676 }
677 $this->activate(false);
678 }
679 }
680
681 /**
682 * Main instance of REACG.
683 *
684 * @return REACG The main instance to prevent the need to use globals.
685 */
686 function REACG() {
687 return REACG::instance();
688 }
689
690 REACG();
691