PluginProbe
MarqueeAll – Elementor Marquee for Image, Text, Post Grid, Testimonial, Cryptocurrency, Faqs & News Ticker 🌀 / 1.2.2
MarqueeAll – Elementor Marquee for Image, Text, Post Grid, Testimonial, Cryptocurrency, Faqs & News Ticker 🌀 v1.2.2
1.2.3 1.2.2 trunk 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1
marqueeall / includes / plugin.php

plugin.php in MarqueeAll – Elementor Marquee for Image, Text, Post Grid, Testimonial, Cryptocurrency, Faqs & News Ticker 🌀 1.2.2, at includes/plugin.php

370 lines 11.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Main Plugin Class
4 *
5 * @package MarqueeAll
6 * @since 1.0.0
7 */
8
9 namespace MASSCIE;
10
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit;
13 }
14
15 /**
16 * Class Plugin
17 */
18 final class Plugin {
19
20 /**
21 * @var Plugin|null
22 */
23 private static $instance = null;
24
25 /**
26 * @return Plugin
27 */
28 public static function instance() {
29 if ( null === self::$instance ) {
30 self::$instance = new self();
31 }
32 return self::$instance;
33 }
34
35 /**
36 * Constructor.
37 */
38 private function __construct() {
39 add_action( 'plugins_loaded', array( $this, 'on_plugins_loaded' ) );
40 add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_assets' ) );
41 add_action( 'elementor/editor/after_enqueue_styles', array( $this, 'enqueue_elementor_editor_assets' ) );
42
43 if ( is_admin() ) {
44 // Load admin + widget manager only in dashboard.
45 $this->load_admin();
46
47 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
48 add_action( 'admin_footer-plugins.php', array( $this, 'render_deactivation_modal' ) );
49 add_action( 'wp_ajax_masscie_deactivation_feedback', array( $this, 'handle_deactivation_feedback' ) );
50 }
51 }
52
53 /**
54 * Load admin-only files (Widget Manager page + AJAX).
55 * Wrapped in a try/catch so a missing file never breaks the front end.
56 *
57 * @return void
58 */
59 private function load_admin() {
60 $registry_file = MASSCIE_PATH . 'includes/class-widget-registry.php';
61 $manager_file = MASSCIE_PATH . 'includes/class-widget-manager.php';
62 $admin_file = MASSCIE_PATH . 'includes/admin/class-admin.php';
63
64 if ( file_exists( $registry_file ) ) {
65 require_once $registry_file;
66 }
67 if ( file_exists( $manager_file ) ) {
68 require_once $manager_file;
69 }
70 if ( file_exists( $admin_file ) && class_exists( 'MASSCIE\Widget_Registry' ) ) {
71 require_once $admin_file;
72 Admin\Admin::instance();
73 }
74 }
75
76 /**
77 * Fired on plugins_loaded.
78 *
79 * @return void
80 */
81 public function on_plugins_loaded() {
82 if ( ! did_action( 'elementor/loaded' ) ) {
83 add_action(
84 'admin_notices',
85 function () {
86 printf(
87 '<div class="notice notice-error"><p>%s</p></div>',
88 esc_html__( 'MarqueeAll requires Elementor to be installed and activated.', 'marqueeall' )
89 );
90 }
91 );
92 return;
93 }
94
95 // Register MarqueeAll widget category.
96 add_action(
97 'elementor/elements/categories_registered',
98 function ( $manager ) {
99 $manager->add_category(
100 'masscie-widgets',
101 array(
102 'title' => __( 'MarqueeAll Widgets', 'marqueeall' ),
103 'icon' => 'fa fa-arrows-h',
104 )
105 );
106 }
107 );
108
109 // Register widgets with Elementor.
110 add_action( 'elementor/widgets/register', array( $this, 'register_widgets' ) );
111 }
112
113 /**
114 * Widget map — mirrors the original plugin.php manual list.
115 * Each entry: file path relative to MASSCIE_PATH, fully-qualified class name.
116 *
117 * @return array[]
118 */
119 private function get_widget_map() {
120 return array(
121 'text-marquee' => array(
122 'file' => 'includes/widgets/class-text-marquee.php',
123 'class' => 'MASSCIE\Widgets\Text_Marquee',
124 ),
125 'image-marquee' => array(
126 'file' => 'includes/widgets/class-image-marquee.php',
127 'class' => 'MASSCIE\Widgets\Image_Marquee',
128 ),
129 'testimonial-marquee' => array(
130 'file' => 'includes/widgets/class-testimonial-marquee.php',
131 'class' => 'MASSCIE\Widgets\Testimonial_Marquee',
132 ),
133 'news-ticker' => array(
134 'file' => 'includes/widgets/class-news-ticker.php',
135 'class' => 'MASSCIE\Widgets\News_Ticker',
136 ),
137 'post-grid-marquee' => array(
138 'file' => 'includes/widgets/class-post-grid-marquee.php',
139 'class' => 'MASSCIE\Widgets\Post_Grid_Marquee',
140 ),
141 'team-members-marquee' => array(
142 'file' => 'includes/widgets/class-team-members-marquee.php',
143 'class' => 'MASSCIE\Widgets\Team_Members_Marquee',
144 ),
145 'text-scramble' => array(
146 'file' => 'includes/widgets/class-text-scramble.php',
147 'class' => 'MASSCIE\Widgets\Text_Scramble',
148 ),
149 'crypto-marquee' => array(
150 'file' => 'includes/widgets/class-crypto-marquee.php',
151 'class' => 'MASSCIE\Widgets\Crypto_Marquee',
152 ),
153 );
154 }
155
156 /**
157 * Register Elementor widgets.
158 *
159 * Reads the saved option directly — zero dependency on Widget_Registry
160 * or Widget_Manager — so widgets always load even if those files are
161 * missing, mis-uploaded, or cached.
162 *
163 * Logic:
164 * - Option missing / empty array → ALL widgets enabled (fresh install default)
165 * - Option present, slug = 0 → widget SKIPPED
166 * - Option present, slug = 1 → widget LOADED
167 * - Option present, slug missing → widget LOADED (new widget added later)
168 *
169 * @param \Elementor\Widgets_Manager $widgets_manager Elementor widget manager.
170 * @return void
171 */
172 public function register_widgets( $widgets_manager ) {
173 // Read saved statuses. Returns false if option doesn't exist yet.
174 $status = get_option( 'marqueeall_widget_status', false );
175
176 foreach ( $this->get_widget_map() as $slug => $widget ) {
177 // Only skip when we have a saved option AND it explicitly sets this slug to 0.
178 if ( false !== $status && is_array( $status ) && isset( $status[ $slug ] ) && 0 === (int) $status[ $slug ] ) {
179 continue;
180 }
181
182 $file = MASSCIE_PATH . $widget['file'];
183
184 if ( ! file_exists( $file ) ) {
185 continue;
186 }
187
188 require_once $file;
189
190 $class = $widget['class'];
191
192 if ( ! class_exists( $class ) ) {
193 continue;
194 }
195
196 $widgets_manager->register( new $class() );
197 }
198 }
199
200 /**
201 * Register front-end assets (scripts/styles registered; widgets enqueue on demand).
202 *
203 * @return void
204 */
205 public function enqueue_assets() {
206 wp_register_style(
207 'masscie-style',
208 MASSCIE_URL . 'assets/css/masscie.css',
209 array(),
210 MASSCIE_VERSION
211 );
212
213 wp_register_style(
214 'masscie-crypto-style',
215 MASSCIE_URL . 'assets/css/masscie-crypto.css',
216 array(),
217 MASSCIE_VERSION
218 );
219
220 wp_register_script(
221 'masscie-marquee',
222 MASSCIE_URL . 'assets/js/masscie-marquee.js',
223 array( 'jquery' ),
224 MASSCIE_VERSION,
225 true
226 );
227 }
228
229 /**
230 * Enqueue plugins.php admin assets (deactivation feedback).
231 *
232 * @param string $hook_suffix Current admin page hook.
233 * @return void
234 */
235 public function enqueue_admin_assets( $hook_suffix ) {
236 if ( 'plugins.php' !== $hook_suffix ) {
237 return;
238 }
239
240 wp_enqueue_style(
241 'masscie-admin-feedback',
242 MASSCIE_URL . 'assets/css/masscie-admin-feedback.css',
243 array(),
244 MASSCIE_VERSION
245 );
246
247 wp_enqueue_script(
248 'masscie-admin-feedback',
249 MASSCIE_URL . 'assets/js/masscie-admin-feedback.js',
250 array( 'jquery' ),
251 MASSCIE_VERSION,
252 true
253 );
254
255 wp_localize_script(
256 'masscie-admin-feedback',
257 'MASSCIE_FEEDBACK',
258 array(
259 'ajax_url' => admin_url( 'admin-ajax.php' ),
260 'nonce' => wp_create_nonce( 'masscie_deactivation_feedback' ),
261 'plugin_slug' => 'marqueeall',
262 'deactivateText' => __( 'Deactivate', 'marqueeall' ),
263 )
264 );
265 }
266
267 /**
268 * Enqueue Elementor editor assets.
269 *
270 * @return void
271 */
272 public function enqueue_elementor_editor_assets() {
273 wp_enqueue_style(
274 'marqueeall-elementor-editor',
275 MASSCIE_URL . 'assets/css/elementor-editor.css',
276 array(),
277 MASSCIE_VERSION
278 );
279
280 wp_enqueue_script(
281 'masscie-crypto-editor',
282 MASSCIE_URL . 'assets/js/crypto-editor.js',
283 array( 'jquery', 'select2' ),
284 MASSCIE_VERSION,
285 true
286 );
287
288 wp_localize_script(
289 'masscie-crypto-editor',
290 'masscieCryptoEditor',
291 array(
292 'ajax_url' => admin_url( 'admin-ajax.php' ),
293 'nonce' => wp_create_nonce( 'masscie_crypto_nonce' ),
294 'i18n' => array(
295 'fetching' => __( 'Fetching...', 'marqueeall' ),
296 'error' => __( 'Error fetching data. Please try again.', 'marqueeall' ),
297 'no_cryptos' => __( 'No cryptocurrencies found.', 'marqueeall' ),
298 ),
299 )
300 );
301
302 if ( ! wp_script_is( 'select2', 'enqueued' ) ) {
303 wp_enqueue_script( 'select2' );
304 wp_enqueue_style( 'select2' );
305 }
306 }
307
308 /**
309 * Render deactivation feedback modal on plugins.php.
310 *
311 * @return void
312 */
313 public function render_deactivation_modal() {
314 ?>
315 <div id="masscie-feedback-modal" style="display:none;">
316 <div class="masscie-feedback-backdrop"></div>
317 <div class="masscie-feedback-dialog">
318 <h2><?php esc_html_e( 'Quick Feedback', 'marqueeall' ); ?></h2>
319 <p><?php esc_html_e( 'If you have a moment, please let us know why you are deactivating:', 'marqueeall' ); ?></p>
320 <form id="masscie-feedback-form">
321 <label><input type="radio" name="reason" value="not_what_i_was_looking_for"> <?php esc_html_e( "It's not what I was looking for", 'marqueeall' ); ?></label>
322 <label><input type="radio" name="reason" value="not_working"> <?php esc_html_e( 'The plugin is not working', 'marqueeall' ); ?></label>
323 <label><input type="radio" name="reason" value="found_better"> <?php esc_html_e( 'I found a better plugin', 'marqueeall' ); ?></label>
324 <label><input type="radio" name="reason" value="didnt_work_as_expected"> <?php esc_html_e( "The plugin didn't work as expected", 'marqueeall' ); ?></label>
325 <label><input type="radio" name="reason" value="couldnt_understand"> <?php esc_html_e( "I couldn't understand how to make it work", 'marqueeall' ); ?></label>
326 <label><input type="radio" name="reason" value="missing_feature"> <?php esc_html_e( "The plugin is great, but I need a specific feature that you don't support", 'marqueeall' ); ?></label>
327 <label><input type="radio" name="reason" value="temporary"> <?php esc_html_e( "It's a temporary deactivation - I'm troubleshooting an issue", 'marqueeall' ); ?></label>
328 <label><input type="radio" name="reason" value="other"> <?php esc_html_e( 'Other', 'marqueeall' ); ?></label>
329 <textarea name="details" placeholder="<?php esc_attr_e( 'Please share more details (optional)', 'marqueeall' ); ?>"></textarea>
330 <div class="masscie-feedback-buttons">
331 <button type="button" class="button button-secondary" id="masscie-feedback-skip"><?php esc_html_e( 'Skip & Deactivate', 'marqueeall' ); ?></button>
332 <button type="submit" class="button button-primary" id="masscie-feedback-submit"><?php esc_html_e( 'Submit & Deactivate', 'marqueeall' ); ?></button>
333 <button type="button" class="button" id="masscie-feedback-cancel"><?php esc_html_e( 'Cancel', 'marqueeall' ); ?></button>
334 </div>
335 <input type="hidden" name="deactivate_url" id="masscie-deactivate-url" value="">
336 </form>
337 </div>
338 </div>
339 <?php
340 }
341
342 /**
343 * AJAX — handle deactivation feedback submission.
344 *
345 * @return void
346 */
347 public function handle_deactivation_feedback() {
348 check_ajax_referer( 'masscie_deactivation_feedback', 'nonce' );
349
350 if ( ! current_user_can( 'activate_plugins' ) ) {
351 wp_send_json_error( array( 'message' => __( 'Permission denied', 'marqueeall' ) ) );
352 }
353
354 $reason = isset( $_POST['reason'] ) ? sanitize_text_field( wp_unslash( $_POST['reason'] ) ) : '';
355 $details = isset( $_POST['details'] ) ? wp_kses_post( wp_unslash( $_POST['details'] ) ) : '';
356 $deactivate_url = isset( $_POST['deactivate_url'] ) ? esc_url_raw( wp_unslash( $_POST['deactivate_url'] ) ) : '';
357 $site_url = home_url();
358
359 wp_mail(
360 'amandeepsingh@webspero.com',
361 sprintf( 'MarqueeAll Deactivation Feedback from %s', $site_url ),
362 "Plugin: MarqueeAll\nSite: {$site_url}\nReason: {$reason}\n\nDetails:\n{$details}\n"
363 );
364
365 wp_send_json_success( array( 'deactivate_url' => $deactivate_url ) );
366 }
367 }
368
369 Plugin::instance();
370