PluginProbe
MarqueeAll – Elementor Marquee for Image, Text, Post Grid, Testimonial, Cryptocurrency, Faqs & News Ticker 🌀 / trunk
MarqueeAll – Elementor Marquee for Image, Text, Post Grid, Testimonial, Cryptocurrency, Faqs & News Ticker 🌀 vtrunk
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 🌀 trunk, at includes/plugin.php

374 lines 11.3 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 'faq-marquee' => array(
154 'file' => 'includes/widgets/class-faq-marquee.php',
155 'class' => 'MASSCIE\Widgets\Faq_Marquee',
156 ),
157 );
158 }
159
160 /**
161 * Register Elementor widgets.
162 *
163 * Reads the saved option directly — zero dependency on Widget_Registry
164 * or Widget_Manager — so widgets always load even if those files are
165 * missing, mis-uploaded, or cached.
166 *
167 * Logic:
168 * - Option missing / empty array → ALL widgets enabled (fresh install default)
169 * - Option present, slug = 0 → widget SKIPPED
170 * - Option present, slug = 1 → widget LOADED
171 * - Option present, slug missing → widget LOADED (new widget added later)
172 *
173 * @param \Elementor\Widgets_Manager $widgets_manager Elementor widget manager.
174 * @return void
175 */
176 public function register_widgets( $widgets_manager ) {
177 // Read saved statuses. Returns false if option doesn't exist yet.
178 $status = get_option( 'marqueeall_widget_status', false );
179
180 foreach ( $this->get_widget_map() as $slug => $widget ) {
181 // Only skip when we have a saved option AND it explicitly sets this slug to 0.
182 if ( false !== $status && is_array( $status ) && isset( $status[ $slug ] ) && 0 === (int) $status[ $slug ] ) {
183 continue;
184 }
185
186 $file = MASSCIE_PATH . $widget['file'];
187
188 if ( ! file_exists( $file ) ) {
189 continue;
190 }
191
192 require_once $file;
193
194 $class = $widget['class'];
195
196 if ( ! class_exists( $class ) ) {
197 continue;
198 }
199
200 $widgets_manager->register( new $class() );
201 }
202 }
203
204 /**
205 * Register front-end assets (scripts/styles registered; widgets enqueue on demand).
206 *
207 * @return void
208 */
209 public function enqueue_assets() {
210 wp_register_style(
211 'masscie-style',
212 MASSCIE_URL . 'assets/css/masscie.css',
213 array(),
214 MASSCIE_VERSION
215 );
216
217 wp_register_style(
218 'masscie-crypto-style',
219 MASSCIE_URL . 'assets/css/masscie-crypto.css',
220 array(),
221 MASSCIE_VERSION
222 );
223
224 wp_register_script(
225 'masscie-marquee',
226 MASSCIE_URL . 'assets/js/masscie-marquee.js',
227 array( 'jquery' ),
228 MASSCIE_VERSION,
229 true
230 );
231 }
232
233 /**
234 * Enqueue plugins.php admin assets (deactivation feedback).
235 *
236 * @param string $hook_suffix Current admin page hook.
237 * @return void
238 */
239 public function enqueue_admin_assets( $hook_suffix ) {
240 if ( 'plugins.php' !== $hook_suffix ) {
241 return;
242 }
243
244 wp_enqueue_style(
245 'masscie-admin-feedback',
246 MASSCIE_URL . 'assets/css/masscie-admin-feedback.css',
247 array(),
248 MASSCIE_VERSION
249 );
250
251 wp_enqueue_script(
252 'masscie-admin-feedback',
253 MASSCIE_URL . 'assets/js/masscie-admin-feedback.js',
254 array( 'jquery' ),
255 MASSCIE_VERSION,
256 true
257 );
258
259 wp_localize_script(
260 'masscie-admin-feedback',
261 'MASSCIE_FEEDBACK',
262 array(
263 'ajax_url' => admin_url( 'admin-ajax.php' ),
264 'nonce' => wp_create_nonce( 'masscie_deactivation_feedback' ),
265 'plugin_slug' => 'marqueeall',
266 'deactivateText' => __( 'Deactivate', 'marqueeall' ),
267 )
268 );
269 }
270
271 /**
272 * Enqueue Elementor editor assets.
273 *
274 * @return void
275 */
276 public function enqueue_elementor_editor_assets() {
277 wp_enqueue_style(
278 'marqueeall-elementor-editor',
279 MASSCIE_URL . 'assets/css/elementor-editor.css',
280 array(),
281 MASSCIE_VERSION
282 );
283
284 wp_enqueue_script(
285 'masscie-crypto-editor',
286 MASSCIE_URL . 'assets/js/crypto-editor.js',
287 array( 'jquery', 'select2' ),
288 MASSCIE_VERSION,
289 true
290 );
291
292 wp_localize_script(
293 'masscie-crypto-editor',
294 'masscieCryptoEditor',
295 array(
296 'ajax_url' => admin_url( 'admin-ajax.php' ),
297 'nonce' => wp_create_nonce( 'masscie_crypto_nonce' ),
298 'i18n' => array(
299 'fetching' => __( 'Fetching...', 'marqueeall' ),
300 'error' => __( 'Error fetching data. Please try again.', 'marqueeall' ),
301 'no_cryptos' => __( 'No cryptocurrencies found.', 'marqueeall' ),
302 ),
303 )
304 );
305
306 if ( ! wp_script_is( 'select2', 'enqueued' ) ) {
307 wp_enqueue_script( 'select2' );
308 wp_enqueue_style( 'select2' );
309 }
310 }
311
312 /**
313 * Render deactivation feedback modal on plugins.php.
314 *
315 * @return void
316 */
317 public function render_deactivation_modal() {
318 ?>
319 <div id="masscie-feedback-modal" style="display:none;">
320 <div class="masscie-feedback-backdrop"></div>
321 <div class="masscie-feedback-dialog">
322 <h2><?php esc_html_e( 'Quick Feedback', 'marqueeall' ); ?></h2>
323 <p><?php esc_html_e( 'If you have a moment, please let us know why you are deactivating:', 'marqueeall' ); ?></p>
324 <form id="masscie-feedback-form">
325 <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>
326 <label><input type="radio" name="reason" value="not_working"> <?php esc_html_e( 'The plugin is not working', 'marqueeall' ); ?></label>
327 <label><input type="radio" name="reason" value="found_better"> <?php esc_html_e( 'I found a better plugin', 'marqueeall' ); ?></label>
328 <label><input type="radio" name="reason" value="didnt_work_as_expected"> <?php esc_html_e( "The plugin didn't work as expected", 'marqueeall' ); ?></label>
329 <label><input type="radio" name="reason" value="couldnt_understand"> <?php esc_html_e( "I couldn't understand how to make it work", 'marqueeall' ); ?></label>
330 <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>
331 <label><input type="radio" name="reason" value="temporary"> <?php esc_html_e( "It's a temporary deactivation - I'm troubleshooting an issue", 'marqueeall' ); ?></label>
332 <label><input type="radio" name="reason" value="other"> <?php esc_html_e( 'Other', 'marqueeall' ); ?></label>
333 <textarea name="details" placeholder="<?php esc_attr_e( 'Please share more details (optional)', 'marqueeall' ); ?>"></textarea>
334 <div class="masscie-feedback-buttons">
335 <button type="button" class="button button-secondary" id="masscie-feedback-skip"><?php esc_html_e( 'Skip & Deactivate', 'marqueeall' ); ?></button>
336 <button type="submit" class="button button-primary" id="masscie-feedback-submit"><?php esc_html_e( 'Submit & Deactivate', 'marqueeall' ); ?></button>
337 <button type="button" class="button" id="masscie-feedback-cancel"><?php esc_html_e( 'Cancel', 'marqueeall' ); ?></button>
338 </div>
339 <input type="hidden" name="deactivate_url" id="masscie-deactivate-url" value="">
340 </form>
341 </div>
342 </div>
343 <?php
344 }
345
346 /**
347 * AJAX — handle deactivation feedback submission.
348 *
349 * @return void
350 */
351 public function handle_deactivation_feedback() {
352 check_ajax_referer( 'masscie_deactivation_feedback', 'nonce' );
353
354 if ( ! current_user_can( 'activate_plugins' ) ) {
355 wp_send_json_error( array( 'message' => __( 'Permission denied', 'marqueeall' ) ) );
356 }
357
358 $reason = isset( $_POST['reason'] ) ? sanitize_text_field( wp_unslash( $_POST['reason'] ) ) : '';
359 $details = isset( $_POST['details'] ) ? wp_kses_post( wp_unslash( $_POST['details'] ) ) : '';
360 $deactivate_url = isset( $_POST['deactivate_url'] ) ? esc_url_raw( wp_unslash( $_POST['deactivate_url'] ) ) : '';
361 $site_url = home_url();
362
363 wp_mail(
364 'amandeepsingh@webspero.com',
365 sprintf( 'MarqueeAll Deactivation Feedback from %s', $site_url ),
366 "Plugin: MarqueeAll\nSite: {$site_url}\nReason: {$reason}\n\nDetails:\n{$details}\n"
367 );
368
369 wp_send_json_success( array( 'deactivate_url' => $deactivate_url ) );
370 }
371 }
372
373 Plugin::instance();
374