PluginProbe
Code Engine – PHP Snippets, AI Functions & Automation for WordPress / 0.4.3
Code Engine – PHP Snippets, AI Functions & Automation for WordPress v0.4.3
0.5.7 0.5.6 0.5.5 0.5.4 0.5.3 0.5.2 0.5.1 0.5.0 0.4.9 0.4.8 0.4.7 0.4.6 trunk 0.0.1 0.0.2 0.2.8 0.2.9 0.3.0 0.3.1 0.3.2 0.3.3 0.3.4 0.3.5 0.3.6 0.3.7 All 33 releases
← All changes | common/admin.php +182 -8 0.4.20.4.3 View file →
@@ -5,8 +5,10 @@
5 5 class MeowKit_MWCODE_Admin {
6 6 public static $loaded = false;
7 7 public static $version = '4.0';
8 8 public static $admin_version = '4.0';
9 + public static $network_license_modal_added = false;
10 + public static $network_license_plugins = [];
9 11
10 12 /**
11 13 * Storage for instances that need deferred initialization.
12 14 *
@@ -196,19 +198,191 @@
196 198 return $links;
197 199 }
198 200 $isIssue = $this->isPro && !$this->is_registered();
199 201 if ( strpos( $pathName, $thisPathName ) !== false ) {
200 - $new_links = [
201 - 'settings' =>
202 - sprintf( __( '<a href="admin.php?page=%s_settings">Settings</a>', $this->domain ), $this->prefix ),
203 - 'license' =>
204 - $this->is_registered() ?
205 - ( '<span style="color: #a75bd6;">' . __( 'Pro Version', $this->domain ) . '</span>' ) :
206 - ( $isIssue ? ( sprintf( '<span style="color: #ff3434;">' . __( 'License Issue', $this->domain ), $this->prefix ) . '</span>' ) : ( sprintf( '<span>' . __( '<a target="_blank" href="https://meowapps.com">Get the <u>Pro Version</u></a>', $this->domain ), $this->prefix ) . '</span>' ) ),
207 - ];
202 + // In network admin, handle differently (no settings page available)
203 + if ( is_network_admin() ) {
204 + if ( $this->isPro && !$this->is_registered() ) {
205 + // Show "Register License" link for unregistered Pro plugins
206 + $new_links = [
207 + 'license' => sprintf(
208 + '<a href="#" class="meowapps-network-license-link" data-prefix="%s" data-plugin="%s" style="color: #d63638;">%s</a>',
209 + esc_attr( $this->prefix ),
210 + esc_attr( $this->nice_name_from_file( $this->mainfile ) ),
211 + __( 'Register License', $this->domain )
212 + ),
213 + ];
214 + // Track this plugin for the modal
215 + self::$network_license_plugins[ $this->prefix ] = $this->nice_name_from_file( $this->mainfile );
216 + // Add modal output hook (only once)
217 + if ( !self::$network_license_modal_added ) {
218 + add_action( 'admin_footer', [ __CLASS__, 'output_network_license_modal' ] );
219 + self::$network_license_modal_added = true;
220 + }
221 + }
222 + elseif ( $this->isPro && $this->is_registered() ) {
223 + // Pro plugin is registered
224 + $new_links = [
225 + 'license' => '<span style="color: #a75bd6;">' . __( 'Pro Version', $this->domain ) . '</span>',
226 + ];
227 + }
228 + else {
229 + // Free plugin
230 + $new_links = [
231 + 'license' => sprintf( '<span>' . __( '<a target="_blank" href="https://meowapps.com">Get the <u>Pro Version</u></a>', $this->domain ), $this->prefix ) . '</span>',
232 + ];
233 + }
234 + }
235 + else {
236 + // Regular admin - show settings and license status
237 + $new_links = [
238 + 'settings' =>
239 + sprintf( __( '<a href="admin.php?page=%s_settings">Settings</a>', $this->domain ), $this->prefix ),
240 + 'license' =>
241 + $this->is_registered() ?
242 + ( '<span style="color: #a75bd6;">' . __( 'Pro Version', $this->domain ) . '</span>' ) :
243 + ( $isIssue ? ( sprintf( '<span style="color: #ff3434;">' . __( 'License Issue', $this->domain ), $this->prefix ) . '</span>' ) : ( sprintf( '<span>' . __( '<a target="_blank" href="https://meowapps.com">Get the <u>Pro Version</u></a>', $this->domain ), $this->prefix ) . '</span>' ) ),
244 + ];
245 + }
208 246 $links = array_merge( $new_links, $links );
209 247 }
210 248 return $links;
249 + }
250 +
251 + /**
252 + * Output the network license registration modal.
253 + * Called via admin_footer hook in network admin.
254 + */
255 + public static function output_network_license_modal() {
256 + $rest_url = esc_url( rest_url() );
257 + $nonce = wp_create_nonce( 'wp_rest' );
258 + ?>
259 + <div id="meowapps-network-license-modal" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.6); z-index:100000; align-items:center; justify-content:center;">
260 + <div style="background:#fff; padding:24px; border-radius:8px; max-width:450px; width:90%; box-shadow:0 4px 20px rgba(0,0,0,0.3);">
261 + <h2 style="margin:0 0 8px 0; font-size:18px;">Register License</h2>
262 + <p id="meowapps-license-plugin-name" style="margin:0 0 16px 0; color:#666;"></p>
263 + <input type="text" id="meowapps-license-key-input" placeholder="Enter your license key" style="width:100%; padding:10px; font-size:14px; border:1px solid #8c8f94; border-radius:4px; box-sizing:border-box;" />
264 + <p id="meowapps-license-message" style="margin:12px 0 0 0; padding:10px; border-radius:4px; display:none;"></p>
265 + <div style="margin-top:16px; display:flex; gap:10px; justify-content:flex-end;">
266 + <button type="button" id="meowapps-license-cancel" class="button">Cancel</button>
267 + <button type="button" id="meowapps-license-submit" class="button button-primary">Validate & Register</button>
268 + </div>
269 + </div>
270 + </div>
271 + <script>
272 + (function() {
273 + var modal = document.getElementById('meowapps-network-license-modal');
274 + var input = document.getElementById('meowapps-license-key-input');
275 + var message = document.getElementById('meowapps-license-message');
276 + var pluginName = document.getElementById('meowapps-license-plugin-name');
277 + var submitBtn = document.getElementById('meowapps-license-submit');
278 + var cancelBtn = document.getElementById('meowapps-license-cancel');
279 + var currentPrefix = '';
280 +
281 + function showMessage(text, isError) {
282 + message.textContent = text;
283 + message.style.display = 'block';
284 + message.style.background = isError ? '#fcf0f1' : '#edfaef';
285 + message.style.color = isError ? '#d63638' : '#1e7e34';
286 + message.style.border = '1px solid ' + (isError ? '#d63638' : '#1e7e34');
287 + }
288 +
289 + function hideMessage() {
290 + message.style.display = 'none';
291 + }
292 +
293 + function openModal(prefix, plugin) {
294 + currentPrefix = prefix;
295 + pluginName.textContent = plugin;
296 + input.value = '';
297 + hideMessage();
298 + submitBtn.disabled = false;
299 + submitBtn.textContent = 'Validate & Register';
300 + modal.style.display = 'flex';
301 + input.focus();
302 + }
303 +
304 + function closeModal() {
305 + modal.style.display = 'none';
306 + currentPrefix = '';
307 + }
308 +
309 + // Handle click on "Register License" links
310 + document.addEventListener('click', function(e) {
311 + if (e.target.classList.contains('meowapps-network-license-link')) {
312 + e.preventDefault();
313 + var prefix = e.target.getAttribute('data-prefix');
314 + var plugin = e.target.getAttribute('data-plugin');
315 + openModal(prefix, plugin);
316 + }
317 + });
318 +
319 + // Close modal on cancel or clicking outside
320 + cancelBtn.addEventListener('click', closeModal);
321 + modal.addEventListener('click', function(e) {
322 + if (e.target === modal) closeModal();
323 + });
324 +
325 + // Handle escape key
326 + document.addEventListener('keydown', function(e) {
327 + if (e.key === 'Escape' && modal.style.display === 'flex') {
328 + closeModal();
329 + }
330 + });
331 +
332 + // Handle enter key in input
333 + input.addEventListener('keydown', function(e) {
334 + if (e.key === 'Enter') {
335 + submitBtn.click();
336 + }
337 + });
338 +
339 + // Submit license
340 + submitBtn.addEventListener('click', function() {
341 + var licenseKey = input.value.trim();
342 + if (!licenseKey) {
343 + showMessage('Please enter a license key.', true);
344 + return;
345 + }
346 +
347 + submitBtn.disabled = true;
348 + submitBtn.textContent = 'Validating...';
349 + hideMessage();
350 +
351 + var restUrl = '<?php echo $rest_url; ?>meow-licenser/' + currentPrefix + '/v1/set_license/';
352 +
353 + fetch(restUrl, {
354 + method: 'POST',
355 + headers: {
356 + 'Content-Type': 'application/json',
357 + 'X-WP-Nonce': '<?php echo $nonce; ?>'
358 + },
359 + body: JSON.stringify({ serialKey: licenseKey })
360 + })
361 + .then(function(response) { return response.json(); })
362 + .then(function(data) {
363 + if (data.success && data.data && !data.data.issue) {
364 + showMessage('License registered successfully! Reloading...', false);
365 + setTimeout(function() { location.reload(); }, 1500);
366 + } else {
367 + var errorMsg = 'License validation failed.';
368 + if (data.data && data.data.issue) {
369 + errorMsg = 'License issue: ' + data.data.issue;
370 + }
371 + showMessage(errorMsg, true);
372 + submitBtn.disabled = false;
373 + submitBtn.textContent = 'Validate & Register';
374 + }
375 + })
376 + .catch(function(error) {
377 + showMessage('Error: ' + error.message, true);
378 + submitBtn.disabled = false;
379 + submitBtn.textContent = 'Validate & Register';
380 + });
381 + });
382 + })();
383 + </script>
384 + <?php
211 385 }
212 386
213 387 public function request_verify_ssl() {
214 388 return get_option( 'force_sslverify', false );