PluginProbe
PatternsWP – Gutenberg Block Patterns & Page Templates Library / 1.0.6
PatternsWP – Gutenberg Block Patterns & Page Templates Library v1.0.6
trunk 1.0.0 1.0.1 1.0.10 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9
patternswp / includes / class-patternswp-admin.php

class-patternswp-admin.php in PatternsWP – Gutenberg Block Patterns & Page Templates Library 1.0.6, at includes/class-patternswp-admin.php

319 lines 16.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Admin Page
4 */
5
6 class PatternsWP_Admin {
7
8 /**
9 * Constructor
10 */
11 public function __construct() {
12 // Add menu and pages
13 add_action('admin_menu', array($this, 'add_admin_menu'));
14 add_action('admin_init', array($this, 'patternswp_clear_cache'));
15 add_action( 'admin_init', array( $this, 'patternswp_ensure_hourly_cron' ) );
16 add_action( 'wp_ajax_patternswp_background_transient_load_ajax', array( $this, 'patternswp_background_transient_load_ajaxcc' ) );
17 add_action( 'wp_ajax_nopriv_patternswp_background_transient_load_ajax', array( $this, 'patternswp_background_transient_load_ajaxcc' ) );
18 add_action( 'patternswp_load_patterns_by_ra', array( $this, 'patternswp_load_patterns_by_remote_ajax' ) );
19 }
20
21 /**
22 * Add admin menu
23 */
24 public function add_admin_menu() {
25 // Custom SVG icon (base64 encoded)
26 $custom_icon = 'data:image/svg+xml;base64,' . base64_encode('
27 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="currentColor">
28 <path d="M9.34 24L4.45 21.16L4.03 20.92V15.3L9.34 12V24Z"/>
29 <path fill-rule="evenodd" clip-rule="evenodd" d="M14.66 9.2L20.97 6L14.66 2.8V9.2Z"/>
30 <path d="M14.66 2.8L9.34 6L4.03 9.2V2.8L9.34 0L14.66 2.8Z"/>
31 <path fill-rule="evenodd" clip-rule="evenodd" d="M10.79 11.44V17.84L14.66 15.3L20.97 12V6L14.66 9.2L10.79 11.44Z"/>
32 </svg>
33 ');
34
35 // Add top-level menu with custom SVG icon
36 $menu_slug = 'patternswp-plugin-menu';
37 add_menu_page(
38 'PatternsWP',
39 'PatternsWP',
40 'manage_options',
41 $menu_slug,
42 array($this, 'render_main_page'),
43 $custom_icon,
44 60
45 );
46
47 // Add subpages
48 $this->add_subpage($menu_slug, 'Dashboard', 'Dashboard', 'patternswp-plugin-menu', array($this, 'render_main_page'));
49 $this->add_subpage($menu_slug, 'Support', 'Support', 'patternswp-plugin-page-1', array($this, 'patternswp_support'));
50 $this->add_subpage($menu_slug, 'Clear Cache', 'Clear Cache', 'patternswp-clear-cache', array($this, 'patternswp_clear_cache_form'));
51 }
52
53 /**
54 * Add subpage
55 */
56 private function add_subpage($parent_slug, $page_title, $menu_title, $menu_slug, $callback) {
57 // Add subpage
58 add_submenu_page($parent_slug, $page_title, $menu_title, 'manage_options', $menu_slug, $callback);
59 }
60
61 /**
62 * Render tabs
63 */
64 public function patterswp_tab( $tab ) {
65 $tabs = array(
66 'Dashboard' => 'patternswp-plugin-menu',
67 'Support' => 'patternswp-plugin-page-1',
68 'Clear Cache' => 'patternswp-clear-cache',
69 'License' => 'patternswp-license_section'
70 );
71
72 foreach ($tabs as $name => $slug) {
73 $class = ( $tab === $name ) ? 'nav-tab-active' : '';
74 echo '<a href="?page=' . esc_attr($slug) . '" class="nav-tab ' . esc_attr($class) . '">' . esc_html($name) . '</a>';
75 }
76 }
77
78 /**
79 * Render main page
80 */
81 public function render_main_page() { ?>
82 <div class="wrap">
83 <h1><?php esc_html_e('PatternsWP', 'patternswp'); ?></h1>
84 <h2 class="nav-tab-wrapper">
85 <?php $this->patterswp_tab( 'Dashboard' ); ?>
86 </h2>
87 <div class="patterns-wp-tabs-content">
88 <div id="tab-1" class="patterns-wp-tab-content patterns-wp-tab-active">
89 <div class="wrap">
90 <div class="pw-feature-box big-box" style="max-width: 1280px; padding: 40px; background-color: white; border-radius: 10px; overflow: hidden;">
91 <div class="about__section has-1-columns">
92 <div class="column" style="text-align:center;">
93 <h4><?php echo esc_html('Hello, ' . wp_get_current_user()->display_name . ' 👋'); ?></h4>
94 <h1 class="feature-title"><?php esc_html_e('Welcome to PatternsWP', 'patternswp'); ?></h1>
95 <p><?php esc_html_e('Thanks for choosing PatternsWP! Follow these three simple steps to get started!', 'patternswp'); ?></p>
96 </div>
97 </div>
98 <div class="about__section has-3-columns">
99 <div class="column" style="padding: 40px;">
100 <div class="about__image">
101 <?php
102 // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage
103 echo '<img src="' . esc_url(plugin_dir_url(__FILE__) . 'pwp-welcome-01.png') . '" alt="" height="auto" width="100%">';
104 ?>
105 </div>
106 <h4><?php esc_html_e('01. Open the PatternsWP Library', 'patternswp'); ?></h4>
107 <p><?php esc_html_e('When editing a page or post in the block editor, locate the PatternsWP Library button in the editor’s header. Click it to access a collection of pre-designed patterns and full-page templates.', 'patternswp'); ?></p>
108 </div>
109 <div class="column" style="padding: 40px;">
110 <div class="about__image">
111 <?php
112 // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage
113 echo '<img src="' . esc_url(plugin_dir_url(__FILE__) . 'pwp-welcome-02.png') . '" alt="" height="auto" width="100%">';
114 ?>
115 </div>
116 <h4><?php esc_html_e('02. Browse Patterns & Templates', 'patternswp'); ?></h4>
117 <p><?php esc_html_e('Explore a diverse range of block patterns and full-page layouts. Use the search box or filter by category to quickly find the perfect design for your website.', 'patternswp'); ?></p>
118 </div>
119 <div class="column" style="padding: 40px;">
120 <div class="about__image">
121 <?php
122 // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage
123 echo '<img src="' . esc_url(plugin_dir_url(__FILE__) . 'pwp-welcome-03.png') . '" alt="" height="auto" width="100%">';
124 ?>
125 </div>
126 <h4><?php esc_html_e('03. Add Patterns & Customize', 'patternswp'); ?></h4>
127 <p><?php esc_html_e('Once you’ve found the right pattern, add it to your page with a single click. Every pattern is fully customizable, allowing you to tweak colors, typography, and content effortlessly.', 'patternswp'); ?></p>
128 </div>
129 </div>
130 </div>
131 </div>
132 </div>
133 </div>
134 </div>
135 <?php }
136
137 /**
138 * Support page
139 */
140 public function patternswp_support() { ?>
141 <div class="wrap">
142 <h1><?php esc_html_e('Support', 'patternswp'); ?></h1>
143 <h2 class="nav-tab-wrapper">
144 <?php $this->patterswp_tab( 'Support' ); ?>
145 </h2>
146 <div class="patterns-wp-tabs-content">
147 <div id="tab-1" class="patterns-wp-tab-content patterns-wp-tab-active">
148 </div>
149 <div id="tab-2" class="patterns-wp-tab-content">
150 <div class="wrap">
151 <div class="pw-feature-box big-box" style="max-width: 1280px; padding: 40px; background-color: white; border-radius: 10px; overflow: hidden;">
152 <div class="about__section has-1-columns">
153 <div class="column" style="">
154 <h1 class="feature-title"><?php esc_html_e('Support', 'patternswp'); ?></h1>
155 <p><?php esc_html_e('Need help with PatternsWP? Whether you have a question, need technical assistance, or just want to reach out, we’re here for you. Contact us, and we’ll be happy to assist!', 'patternswp'); ?></p>
156 </div>
157 <div style="height: 1px; background-color: #ccc; width: 100%; margin: 20px 0;"></div>
158 </div>
159 <div class="about__section has-2-columns">
160 <div class="column" style="padding-right: 100px;">
161
162 <h4><?php esc_html_e('Frequently asked questions', 'patternswp'); ?></h4>
163 <p>
164 <?php
165 printf(
166 esc_attr('Here, you will find answers to commonly asked questions about using PatternsWP. If you need further assistance, feel free to %s.', 'patternswp'),
167 '<a href="https://thepatternswp.com/contact/" target="_blank">'.esc_attr('contact us via the support form →', 'patternswp').'</a>'
168 );
169 ?>
170 </p>
171 </div>
172 <div class="column" style="padding: 0px;">
173 <h5>
174 <a href="https://thepatternswp.com/docs/getting-started-with-patternswp/" target="_blank" style="color: #3858e9; text-decoration: none;">
175 <?php esc_html_e('Getting Started with PatternsWP →', 'patternswp'); ?>
176 </a>
177 </h5>
178 <div style="height: 1px; background-color: #ccc; width: 100%; margin: 10px 0;"></div>
179 <h5>
180 <a href="https://thepatternswp.com/docs/how-to-install-patternswp/" target="_blank" style="color: #3858e9; text-decoration: none;">
181 <?php esc_html_e('How to install PatternsWP →', 'patternswp'); ?>
182 </a>
183 </h5> <div style="height: 1px; background-color: #ccc; width: 100%; margin: 10px 0;"></div>
184 <h5>
185 <a href="https://thepatternswp.com/docs/how-to-upgrade-patternswp-to-pro/" target="_blank" style="color: #3858e9; text-decoration: none;">
186 <?php esc_html_e('How to Upgrade PatternsWP to Pro →', 'patternswp'); ?>
187 </a>
188 </h5> <div style="height: 1px; background-color: #ccc; width: 100%; margin: 10px 0;"></div>
189 <h5>
190 <a href="https://thepatternswp.com/docs/patternswp-support/" target="_blank" style="color: #3858e9; text-decoration: none;">
191 <?php esc_html_e('PatternsWP Support →', 'patternswp'); ?>
192 </a>
193 </h5> <div style="height: 1px; background-color: #ccc; width: 100%; margin: 10px 0;"></div>
194 </div>
195
196 </div>
197 </div>
198 </div>
199 </div>
200 </div>
201 </div>
202 <?php }
203
204 /**
205 * Clear Cache page
206 */
207 public function patternswp_clear_cache_form() { ?>
208 <div class="wrap">
209 <h1><?php esc_html_e('Clear Cache', 'patternswp'); ?></h1>
210 <h2 class="nav-tab-wrapper">
211 <?php $this->patterswp_tab( 'Clear Cache' ); ?>
212 </h2>
213 <div class="patterns-wp-tabs-content">
214 <div id="tab-1" class="patterns-wp-tab-content patterns-wp-tab-active">
215 <div class="wrap">
216 <div class="container" style="padding: 20px; background-color: white; border-radius: 5px; overflow: hidden; width: 70%;">
217 <div class="">
218 <form id="patternswp_clearcache_form" method="post">
219 <?php wp_nonce_field('patternswp_clear_cache_action', 'patternswp_clear_cache_nonce'); ?>
220 <input name="patternswp_clear_cache" type="submit" class="button button-primary" value="Clear Cache">
221 <div>
222 </div>
223 </form>
224 </div>
225 </div>
226 </div>
227 </div>
228 </div>
229 </div>
230 <?php }
231
232 /**
233 * Clear Cache
234 */
235 public function patternswp_clear_cache() {
236 global $wpdb;
237
238 if (isset($_POST['patternswp_clear_cache'])) {
239 if (!isset($_POST['patternswp_clear_cache_nonce'])) {
240 wp_die(esc_attr__('Security check failed. Please try again.', 'patternswp'));
241 }
242
243 $nonce = sanitize_text_field(wp_unslash($_POST['patternswp_clear_cache_nonce']));
244
245 if (!wp_verify_nonce($nonce, 'patternswp_clear_cache_action')) {
246 wp_die(esc_attr__('Security check failed. Please try again.', 'patternswp'));
247 }
248
249 if (!current_user_can('manage_options')) {
250 wp_die(esc_attr('You do not have sufficient permissions to perform this action.', 'patternswp'));
251 }
252
253 // Delete category type transient
254 delete_transient('patternswp_category_type');
255
256 // Delete all API-related transients
257 $pattern = '_transient_patternswp_';
258 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
259 $results = $wpdb->get_col($wpdb->prepare("SELECT option_name FROM $wpdb->options WHERE option_name LIKE %s", $wpdb->esc_like($pattern) . '%'));
260
261 // Delete all patterns cache
262 $patterns = 'patterns_cache_';
263 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
264 $wpdb->query(
265 $wpdb->prepare(
266 "DELETE FROM $wpdb->options WHERE option_name LIKE %s",
267 $wpdb->esc_like($patterns) . '%'
268 )
269 );
270
271 foreach ($results as $transient) {
272 delete_option($transient);
273 delete_option(str_replace('_transient_', '_transient_timeout_', $transient));
274 }
275
276 //load patterns in background
277 $this->patternswp_load_patterns_by_remote_ajax();
278
279 wp_redirect(add_query_arg(array(
280 'page' => 'patternswp-clear-cache',
281 'pt_msg' => urlencode('Clear Cache Successfully'),
282 'status' => 'success'
283 ), admin_url('admin.php')));
284 exit;
285 }
286 }
287
288 /**
289 * Ensure hourly cron job is scheduled
290 */
291 public function patternswp_ensure_hourly_cron() {
292 if ( ! wp_next_scheduled( 'patternswp_hourly_transient_load' ) ) {
293 wp_schedule_event( time(), 'hourly', 'patternswp_hourly_transient_load' );
294 }
295 }
296
297 /**
298 * AJAX handler to load transient data
299 */
300 public function patternswp_background_transient_load_ajaxcc() {
301 do_action( 'patternswp_hourly_transient_load' );
302 wp_die();
303 }
304
305 /**
306 * Load patterns via AJAX
307 */
308 public function patternswp_load_patterns_by_remote_ajax() {
309 $ajax_url = admin_url('admin-ajax.php');
310 wp_remote_post( $ajax_url , array(
311 'body' => array( 'action' => 'patternswp_background_transient_load_ajax' ),
312 'timeout' => 1,
313 'blocking' => false,
314 'sslverify' => false,
315 ));
316 }
317 }
318
319 new PatternsWP_Admin();