PluginProbe
Countdown Timer – Widget Countdown / trunk
Countdown Timer – Widget Countdown vtrunk
2.2.6 2.2.7 2.2.8 2.2.9 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.3.5 2.3.6 2.3.7 2.3.8 2.3.9 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.5.0 All 182 releases
widget-countdown / includes / Core / Plugin.php

Plugin.php in Countdown Timer – Widget Countdown trunk, at includes/Core/Plugin.php

224 lines 7.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) exit;
3
4 /**
5 * Plugin — the main bootstrap class.
6 *
7 * Single responsibility: require files, create instances, wire hooks.
8 * No business logic. No database access. No HTML output.
9 */
10 class Wpda_Countdown_Plugin {
11
12 private $timer_repo;
13 private $theme_repo;
14 private $installer;
15
16 public function __construct() {
17 $this->load_dependencies();
18 $this->create_services();
19
20 // Make wpda_countdown() work BEFORE register_hooks runs — the frontend
21 // constructor can instantiate the popup whose own constructor calls
22 // PopupController::return_params_array() → wpda_countdown()->timer_repository().
23 global $wpdevart_countdown;
24 $wpdevart_countdown = $this;
25
26 $this->register_hooks();
27 }
28
29 /**
30 * Require all files in the correct order.
31 */
32 private function load_dependencies() {
33 $base = wpda_countdown_plugin_path . 'includes/';
34
35 // ── Repository ──
36 require_once $base . 'Repository/TimerRepository.php';
37 require_once $base . 'Repository/ThemeRepository.php';
38
39 // ── Core ──
40 require_once $base . 'Core/Installer.php';
41 require_once $base . 'Core/Assets.php';
42
43 // ── Legacy animation settings class (used by old widget-countdown shortcode) ──
44 if ( ! class_exists( 'wpdevart_countdown_setting' ) ) {
45 require_once $base . 'legacy/library.php';
46 }
47
48 // ── Admin ──
49 require_once $base . 'admin/Fields.php';
50 require_once $base . 'admin/AdminMenu.php';
51 require_once $base . 'admin/TimerController.php';
52 require_once $base . 'admin/ThemeController.php';
53 require_once $base . 'admin/PopupController.php';
54 require_once $base . 'admin/StickyBarController.php';
55
56 // ── Frontend ──
57 require_once $base . 'frontend/CountdownEngine.php';
58 require_once $base . 'frontend/Frontend.php';
59
60 // ── Widget ──
61 if ( WPDA_COUNTDOWN_IS_PRO ) {
62 require_once $base . 'Widget/ProWidget.php';
63 }
64
65 // ── Legacy (backward compat shortcode + widget) ──
66 require_once $base . 'legacy/front_end.php';
67 require_once $base . 'legacy/widget.php';
68 }
69
70 /**
71 * Create service instances (no hooks yet).
72 */
73 private function create_services() {
74 $this->timer_repo = new Wpda_Countdown_Timer_Repository();
75 $this->theme_repo = new Wpda_Countdown_Theme_Repository();
76 $this->installer = new Wpda_Countdown_Installer( $this->timer_repo, $this->theme_repo );
77 }
78
79 /**
80 * Wire everything to WordPress hooks.
81 */
82 private function register_hooks() {
83 $plugin_file = wpda_countdown_plugin_path . 'wpdevart-countdown.php';
84
85 // ── Activation ──
86 register_activation_hook( $plugin_file, array( $this->installer, 'install' ) );
87 register_activation_hook( $plugin_file, array( $this, 'on_activate' ) );
88
89 // ── Safety net: create tables on plugins_loaded (fires before init on
90 // every request, frontend included) and also on admin_init so a
91 // missing-table state self-heals on the next page load even if the
92 // activation hook never fired (reinstall over existing files, FTP
93 // upload, manual DROP TABLE, etc.). The installer uses an option
94 // sentinel so the check is a no-op once tables are verified.
95 add_action( 'plugins_loaded', array( $this->installer, 'ensure_tables' ) );
96 add_action( 'admin_init', array( $this->installer, 'ensure_tables' ) );
97
98 // ── Assets ──
99 $assets = new Wpda_Countdown_Assets();
100 add_action( 'init', array( $assets, 'register' ) );
101
102 // ── Text domain ──
103 add_action( 'init', array( $this, 'load_textdomain' ) );
104
105 // ── Admin ──
106 $admin_menu = new Wpda_Countdown_Admin_Menu(
107 $this->timer_repo,
108 $this->theme_repo,
109 $this->installer
110 );
111 $admin_menu->init();
112
113 // ── Legacy admin menu (backward compat — registers the legacy shortcode button popup) ──
114 require_once wpda_countdown_plugin_path . 'includes/legacy/admin_menu.php';
115 new wpdevart_countdown_admin_menu( array(
116 'menu_name' => 'Countdown',
117 'databese_parametrs' => null,
118 ) );
119
120 // ── Frontend ──
121 new wpdevart_countdown_frontend();
122
123 // ── Legacy frontend ──
124 new wpdevart_countdown_front_end( array(
125 'menu_name' => 'countdown',
126 'databese_parametrs' => null,
127 ) );
128
129 // ── Widgets ──
130 add_action( 'widgets_init', array( $this, 'register_widgets' ) );
131
132 // ── Elementor ──
133 add_action( 'elementor/init', array( $this, 'init_elementor' ) );
134
135 // ── Activation notice ──
136 add_action( 'admin_notices', array( $this, 'activation_notice' ) );
137
138 // ── Plugins-list row "Upgrade to Pro" link (free version only) ──
139 if ( ! WPDA_COUNTDOWN_IS_PRO ) {
140 add_filter(
141 'plugin_action_links_' . plugin_basename( $plugin_file ),
142 array( $this, 'add_upgrade_action_link' )
143 );
144 }
145 }
146
147 /**
148 * Prepend "Upgrade to Pro" link before "Deactivate" in the plugins list row.
149 */
150 public function add_upgrade_action_link( $links ) {
151 $upgrade = '<a target="_blank" style="color:#7052fb;font-weight:bold;font-size:13px;" href="https://wpdevart.com/wordpress-countdown-plugin/">Upgrade to Pro</a>';
152 array_unshift( $links, $upgrade );
153 return $links;
154 }
155
156 // ─── Hook callbacks ─────────────────────────────────────────
157
158 public function on_activate() {
159 set_transient( 'wpda_countdown_activated', true, 60 );
160 }
161
162 public function load_textdomain() {
163 $rel = basename( rtrim( wpda_countdown_plugin_path, '/\\' ) ) . '/languages';
164 load_plugin_textdomain( 'wpdevart_countdown', false, $rel );
165 load_plugin_textdomain( 'wpdevart_countdown_n', false, $rel );
166 }
167
168 public function register_widgets() {
169 register_widget( 'wpdevart_countdown' );
170 if ( WPDA_COUNTDOWN_IS_PRO ) {
171 register_widget( 'wpdevart_countdown_pro' );
172 }
173 }
174
175 public function init_elementor() {
176 require_once wpda_countdown_plugin_path . 'includes/Integration/Elementor.php';
177 new Wpda_Countdown_Elementor();
178 }
179
180 public function activation_notice() {
181 if ( ! get_transient( 'wpda_countdown_activated' ) ) return;
182 delete_transient( 'wpda_countdown_activated' );
183 $url = admin_url( 'admin.php?page=wpda_countdown_menu&task=add_wpda_countdown_timer' );
184 echo '<div class="notice notice-success is-dismissible"><p>';
185 echo '<strong>Countdown ' . ( WPDA_COUNTDOWN_IS_PRO ? 'Pro' : '' ) . ' activated!</strong> ';
186 echo '<a href="' . esc_url( $url ) . '">Create your first countdown timer &rarr;</a>';
187 echo '</p></div>';
188 }
189
190 // ─── Public accessors (for external code that needs repos) ──
191
192 public function timer_repository() {
193 return $this->timer_repo;
194 }
195
196 public function theme_repository() {
197 return $this->theme_repo;
198 }
199 }
200
201 /**
202 * Global accessor — use this from any file that needs the Plugin instance.
203 *
204 * wpda_countdown()->timer_repository()->all_names()
205 */
206 function wpda_countdown() {
207 global $wpdevart_countdown;
208 return $wpdevart_countdown;
209 }
210
211 /**
212 * Multisite-safe check for whether a plugin is active.
213 */
214 function wpda_countdown_is_plugin_active( $plugin ) {
215 if ( in_array( $plugin, (array) get_option( 'active_plugins', array() ), true ) ) {
216 return true;
217 }
218 if ( ! is_multisite() ) {
219 return false;
220 }
221 $sitewide = get_site_option( 'active_sitewide_plugins', array() );
222 return isset( $sitewide[ $plugin ] );
223 }
224