post_content, 'net360qr_dashboard') || has_shortcode($post->post_content, 'net360qr_dashboard'))) { wp_enqueue_style('360-qr-frontend', NET360QR_URL.'assets/frontend.css', array(), NET360QR_VERSION); wp_enqueue_script('360-qr-download', NET360QR_URL.'assets/qr-download.js', array(), NET360QR_VERSION, true); wp_enqueue_script('360-qr-shapes', NET360QR_URL.'assets/qr-shapes.js', array(), NET360QR_VERSION, true); } } private function back($args=array()) { $u = wp_get_referer() ?: home_url('/'); wp_safe_redirect(add_query_arg($args, $u)); exit; } private function generated_code() { $chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; do { $code = ''; for ($i=0; $i<8; $i++) $code .= $chars[wp_rand(0, strlen($chars)-1)]; } while (NET360QR_DB::code_exists($code)); return $code; } public function actions() { if (!is_user_logged_in() || !isset($_POST['net360qr_action'])) return; $action = sanitize_key(wp_unslash($_POST['net360qr_action'])); if (!in_array($action, array('save','toggle','delete'), true)) return; $nonce = isset($_POST['_wpnonce']) ? sanitize_text_field(wp_unslash($_POST['_wpnonce'])) : ''; if (!$nonce || !wp_verify_nonce($nonce, 'net360qr_front')) $this->back(array('net360qr_error'=>'Invalid request.')); $uid = get_current_user_id(); $id = isset($_POST['id']) ? absint(wp_unslash($_POST['id'])) : 0; if ($action === 'save') { $name = isset($_POST['name']) ? sanitize_text_field(wp_unslash($_POST['name'])) : ''; $dest = isset($_POST['destination_url']) ? esc_url_raw(wp_unslash($_POST['destination_url'])) : ''; $code = isset($_POST['code']) ? strtoupper(sanitize_key(wp_unslash($_POST['code']))) : ''; if (!$name || !$dest || !preg_match('#^https?://#i', $dest)) $this->back(array('net360qr_error'=>'Enter a name and a valid URL (http/https).')); $public = home_url('/q/'.($code ?: 'XXXXXXXX')); $qrCheck = NET360QR_LOCAL::validate_text($public); if (is_wp_error($qrCheck)) $this->back(array('net360qr_error'=>$qrCheck->get_error_message())); if (!$code) $code = $this->generated_code(); if (NET360QR_DB::code_exists($code, $id)) $this->back(array('net360qr_error'=>'Duplicate code. Please choose another.')); $existing = $id ? NET360QR_DB::get_for_user($id, $uid) : null; if ($id && !$existing) $this->back(array('net360qr_error'=>'QR code not found.')); $logo_id = $existing ? absint($existing->logo_attachment_id ?? 0) : 0; if (!empty($_POST['remove_logo'])) $logo_id = 0; if (!empty($_FILES['net360qr_logo']['name'])) { if (!current_user_can('upload_files')) $this->back(array('net360qr_error'=>'Your account does not have permission to upload logos.')); require_once ABSPATH . 'wp-admin/includes/file.php'; require_once ABSPATH . 'wp-admin/includes/media.php'; require_once ABSPATH . 'wp-admin/includes/image.php'; $new_logo = media_handle_upload('net360qr_logo', 0); if (is_wp_error($new_logo)) $this->back(array('net360qr_error'=>'Could not upload the logo.')); $mime = get_post_mime_type($new_logo); if (!in_array($mime, array('image/png','image/jpeg','image/webp'), true)) { wp_delete_attachment($new_logo, true); $this->back(array('net360qr_error'=>'The logo must be a PNG, JPG, or WebP image.')); } $logo_id = (int) $new_logo; } $shape_input = isset($_POST['qr_shape']) ? sanitize_key(wp_unslash($_POST['qr_shape'])) : ($existing->qr_shape ?? 'classic'); $shape = NET360QR_LOCAL::shape($shape_input); $data = array('name'=>$name,'code'=>$code,'destination_url'=>$dest,'logo_attachment_id'=>$logo_id,'qr_shape'=>$shape); if ($id) NET360QR_DB::update($id, $data); else NET360QR_DB::insert(array_merge($data,array('user_id'=>$uid,'status'=>'active'))); $this->back(array('net360qr_ok'=>'1')); } $qr = NET360QR_DB::get_for_user($id, $uid); if (!$qr) $this->back(array('net360qr_error'=>'QR code not found.')); if ($action === 'delete') NET360QR_DB::delete($id); else NET360QR_DB::update($id, array('status'=>$qr->status === 'active' ? 'inactive' : 'active')); $this->back(array('net360qr_ok'=>'1')); } private function svg_data($public, $size=300) { return NET360QR_LOCAL::data_uri($public, $size); } public function dashboard() { if (!is_user_logged_in()) { return '
Please log in to manage your QR codes.
'; } $uid = get_current_user_id(); $qrs = NET360QR_DB::all($uid); $edit_id = absint(get_query_var('net360qr_edit', 0)); $edit = $edit_id ? NET360QR_DB::get_for_user($edit_id, $uid) : null; $total_scans = 0; $active = 0; foreach ($qrs as $q) { $total_scans += (int)$q->scans; if ($q->status === 'active') $active++; } ob_start(); ?>
360 QR MANAGER

My QR Codes

Create dynamic QR codes and change their destination without reprinting them.

QR Codes Created
✓ Changes saved successfully.
Active QR Codes
Total Scans
System Status● Operational
01

The QR URL stays the same even when you change its destination.

QR styleqr_shape ?? 'classic'); ?>
Center Logo (Optional)
360
QR Logo ExampleAdded only if you upload an image. You can leave this blank.
PNG, JPG, or WebP. A small logo with a transparent background is recommended.logo_attachment_id) && wp_get_attachment_url($edit->logo_attachment_id)): ?>
Current logo
02 · MANAGEMENT

Your QR Codes

registered
▦

You don’t have any QR codes yet

Create your first dynamic QR code above. You can edit its destination whenever you need.

code)); $image = home_url('/q-image/'.rawurlencode($qr->code)); ?>

name); ?>

code); ?>
status==='active'?'Active':'Inactive'; ?>
QR URL

Destinationdestination_url); ?>

scans)); ?> scanslast_scan_at ? esc_html(mysql2date('d/m/Y H:i', $qr->last_scan_at)) : '—'; ?> last scan
✎ Edit
↓ Download
Download PNG 'Standard · 512 px',1024=>'High Quality · 1024 px',2048=>'Maximum Quality · 2048 px') as $download_size=>$download_label): ?> Vector SVG · Scalable