event-tickets-with-ticket-scanner
Last commit date
3rd
5 months ago
css
5 months ago
img
5 months ago
includes
5 months ago
js
5 months ago
languages
5 months ago
ticket
5 months ago
vendors
5 months ago
.gitignore
5 months ago
SASO_EVENTTICKETS.php
5 months ago
backend.js
5 months ago
changelog.txt
5 months ago
db.php
5 months ago
index.php
5 months ago
init_file.php
5 months ago
order_details.js
5 months ago
readme.txt
5 months ago
saso-eventtickets-validator.js
5 months ago
sasoEventtickets_AdminSettings.php
5 months ago
sasoEventtickets_Authtoken.php
5 months ago
sasoEventtickets_Base.php
5 months ago
sasoEventtickets_Core.php
5 months ago
sasoEventtickets_Frontend.php
5 months ago
sasoEventtickets_Messenger.php
5 months ago
sasoEventtickets_Options.php
5 months ago
sasoEventtickets_PDF.php
5 months ago
sasoEventtickets_Seating.php
5 months ago
sasoEventtickets_Ticket.php
5 months ago
sasoEventtickets_TicketBadge.php
5 months ago
sasoEventtickets_TicketDesigner.php
5 months ago
sasoEventtickets_TicketQR.php
5 months ago
ticket_events.js
5 months ago
ticket_scanner.js
5 months ago
validator.js
5 months ago
wc_backend.js
5 months ago
wc_frontend.js
5 months ago
woocommerce-hooks.php
5 months ago
index.php
1665 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Plugin Name: Event Tickets with Ticket Scanner |
| 4 | * Plugin URI: https://vollstart.com/event-tickets-with-ticket-scanner/docs/ |
| 5 | * Description: You can create and generate tickets and codes. You can redeem the tickets at entrance using the built-in ticket scanner. You customer can download a PDF with the ticket information. The Premium allows you also to activate user registration and more. This allows your user to register them self to a ticket. |
| 6 | * Version: 2.8.5 |
| 7 | * Author: Vollstart |
| 8 | * Author URI: https://vollstart.com |
| 9 | * Text Domain: event-tickets-with-ticket-scanner |
| 10 | * |
| 11 | * Event Tickets with Ticket Scanner is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU General Public License for more details. |
| 15 | */ |
| 16 | // https://semver.org/ |
| 17 | // https://developer.wordpress.org/plugins/security/securing-output/ |
| 18 | // https://developer.wordpress.org/plugins/security/securing-input/ |
| 19 | |
| 20 | include_once(plugin_dir_path(__FILE__)."init_file.php"); |
| 21 | |
| 22 | if (!defined('SASO_EVENTTICKETS_PLUGIN_VERSION')) |
| 23 | define('SASO_EVENTTICKETS_PLUGIN_VERSION', '2.8.5'); |
| 24 | if (!defined('SASO_EVENTTICKETS_PLUGIN_DIR_PATH')) |
| 25 | define('SASO_EVENTTICKETS_PLUGIN_DIR_PATH', plugin_dir_path(__FILE__)); |
| 26 | |
| 27 | include_once plugin_dir_path(__FILE__)."SASO_EVENTTICKETS.php"; |
| 28 | |
| 29 | class sasoEventtickets_fakeprem{} |
| 30 | class sasoEventtickets { |
| 31 | private $_js_version; |
| 32 | private $_js_file = 'saso-eventtickets-validator.js'; |
| 33 | public $_js_nonce = 'sasoEventtickets'; |
| 34 | public $_do_action_prefix = 'saso_eventtickets_'; |
| 35 | public $_add_filter_prefix = 'saso_eventtickets_'; |
| 36 | protected $_prefix = 'sasoEventtickets'; |
| 37 | public $_prefix_session = 'sasoEventtickets_'; |
| 38 | protected $_shortcode = 'sasoEventTicketsValidator'; |
| 39 | protected $_shortcode_mycode = 'sasoEventTicketsValidator_code'; |
| 40 | protected $_shortcode_eventviews = 'sasoEventTicketsValidator_eventsview'; |
| 41 | protected $_shortcode_ticket_scanner = 'sasoEventTicketsValidator_ticket_scanner'; |
| 42 | protected $_shortcode_feature_list = 'sasoEventTicketsValidator_feature_list'; |
| 43 | protected $_shortcode_ticket_detail = 'sasoEventTicketsValidator_ticket_detail'; |
| 44 | protected $_divId = 'sasoEventtickets'; |
| 45 | |
| 46 | private $_isPrem = null; |
| 47 | private $_premium_plugin_name = 'event-tickets-with-ticket-scanner-premium'; |
| 48 | private $_premium_function_file = 'sasoEventtickets_PremiumFunctions.php'; |
| 49 | private $PREMFUNCTIONS = null; |
| 50 | private $BASE = null; |
| 51 | private $CORE = null; |
| 52 | private $ADMIN = null; |
| 53 | private $FRONTEND = null; |
| 54 | private $OPTIONS = null; |
| 55 | |
| 56 | private $isAllowedAccess = null; |
| 57 | |
| 58 | public static function Instance() { |
| 59 | static $inst = null; |
| 60 | if ($inst === null) { |
| 61 | $inst = new self(); |
| 62 | } |
| 63 | return $inst; |
| 64 | } |
| 65 | |
| 66 | public function __construct() { |
| 67 | $this->_js_version = $this->getPluginVersion(); |
| 68 | $this->initHandlers(); |
| 69 | } |
| 70 | |
| 71 | public function initHandlers() { |
| 72 | add_action( 'init', [$this, 'load_plugin_textdomain'] ); |
| 73 | add_action( 'upgrader_process_complete', [$this, 'listener_upgrader_process_complete'], 10, 2 ); |
| 74 | //add_action('admin_init', [$this, 'initialize_plugin']); |
| 75 | if (is_admin()) { // called in backend admin, admin-ajax! |
| 76 | $this->init_backend(); |
| 77 | } else { // called in front end |
| 78 | $this->init_frontend(); |
| 79 | } |
| 80 | add_action( 'sasoEventtickets_cronjob_daily', [$this, 'relay_sasoEventtickets_cronjob_daily'], 10, 0 ); // set in tickets.php |
| 81 | add_action( 'plugins_loaded', [$this, 'WooCommercePluginLoaded'], 20, 0 ); |
| 82 | if (basename($_SERVER['SCRIPT_NAME']) == "admin-ajax.php") { |
| 83 | add_action('wp_ajax_nopriv_'.$this->_prefix.'_executeFrontend', [$this,'executeFrontend_a'], 10, 0); // nicht angemeldete user, sollen eine antwort erhalten |
| 84 | add_action('wp_ajax_'.$this->_prefix.'_executeFrontend', [$this,'executeFrontend_a'], 10, 0); // falls eingeloggt ist |
| 85 | add_action('wp_ajax_'.$this->_prefix.'_executeWCBackend', [$this,'executeWCBackend'], 10, 0); // falls eingeloggt ist |
| 86 | add_action('wp_ajax_'.$this->_prefix.'_downloadMyCodesAsPDF', [$this,'downloadMyCodesAsPDF'], 10, 0); // logged in users only |
| 87 | } |
| 88 | if (method_exists($this->getPremiumFunctions(), "initHandlers")) { |
| 89 | $this->getPremiumFunctions()->initHandlers(); |
| 90 | } |
| 91 | $this->cronjob_daily_activate(); |
| 92 | } |
| 93 | public function cronjob_daily_activate() { |
| 94 | $args = []; |
| 95 | if (! wp_next_scheduled ( 'sasoEventtickets_cronjob_daily', $args )) { |
| 96 | wp_schedule_event( strtotime("00:05"), 'daily', 'sasoEventtickets_cronjob_daily', $args ); |
| 97 | } |
| 98 | } |
| 99 | public function cronjob_daily_deactivate() { |
| 100 | wp_clear_scheduled_hook( 'sasoEventtickets_cronjob_daily' ); |
| 101 | } |
| 102 | public function load_plugin_textdomain() { |
| 103 | load_plugin_textdomain( 'event-tickets-with-ticket-scanner', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); |
| 104 | } |
| 105 | public function getPluginPath() { |
| 106 | return SASO_EVENTTICKETS_PLUGIN_DIR_PATH; |
| 107 | } |
| 108 | public function getPluginVersion() { |
| 109 | return SASO_EVENTTICKETS_PLUGIN_VERSION; |
| 110 | } |
| 111 | public function getPluginVersions() { |
| 112 | $ret = ['basic'=>SASO_EVENTTICKETS_PLUGIN_VERSION, 'premium'=>'', 'debug'=>'']; |
| 113 | if (defined('SASO_EVENTTICKETS_PREMIUM_PLUGIN_VERSION')) { |
| 114 | $ret['premium'] = SASO_EVENTTICKETS_PREMIUM_PLUGIN_VERSION; |
| 115 | } |
| 116 | if (defined('WP_DEBUG') && WP_DEBUG) { |
| 117 | $ret['debug'] = esc_html__('is active', 'event-tickets-with-ticket-scanner'); |
| 118 | } |
| 119 | return $ret; |
| 120 | } |
| 121 | public function getDB() { |
| 122 | return SASO_EVENTTICKETS::getDB(plugin_dir_path(__FILE__), "sasoEventticketsDB", $this); |
| 123 | } |
| 124 | public function getBase() { |
| 125 | if ($this->BASE == null) { |
| 126 | if (!class_exists('sasoEventtickets_Base')) { |
| 127 | include_once plugin_dir_path(__FILE__)."sasoEventtickets_Base.php"; |
| 128 | } |
| 129 | $this->BASE = new sasoEventtickets_Base($this); |
| 130 | } |
| 131 | return $this->BASE; |
| 132 | } |
| 133 | public function getCore() { |
| 134 | if ($this->CORE == null) { |
| 135 | if (!class_exists('sasoEventtickets_Core')) { |
| 136 | include_once plugin_dir_path(__FILE__)."sasoEventtickets_Core.php"; |
| 137 | } |
| 138 | $this->CORE = new sasoEventtickets_Core($this); |
| 139 | } |
| 140 | return $this->CORE; |
| 141 | } |
| 142 | public function getAdmin() { |
| 143 | if ($this->ADMIN == null) { |
| 144 | if (!class_exists('sasoEventtickets_AdminSettings')) { |
| 145 | include_once plugin_dir_path(__FILE__)."sasoEventtickets_AdminSettings.php"; |
| 146 | } |
| 147 | $this->ADMIN = new sasoEventtickets_AdminSettings($this); |
| 148 | } |
| 149 | return $this->ADMIN; |
| 150 | } |
| 151 | public function getFrontend() { |
| 152 | if ($this->FRONTEND == null) { |
| 153 | if (!class_exists('sasoEventtickets_Frontend')) { |
| 154 | include_once plugin_dir_path(__FILE__)."sasoEventtickets_Frontend.php"; |
| 155 | } |
| 156 | $this->FRONTEND = new sasoEventtickets_Frontend($this); |
| 157 | } |
| 158 | return $this->FRONTEND; |
| 159 | } |
| 160 | public function getOptions() { |
| 161 | if ($this->OPTIONS == null) { |
| 162 | if (!class_exists('sasoEventtickets_Options')) { |
| 163 | include_once plugin_dir_path(__FILE__)."sasoEventtickets_Options.php"; |
| 164 | } |
| 165 | $this->OPTIONS = new sasoEventtickets_Options($this, $this->_prefix); |
| 166 | $this->OPTIONS->initOptions(); |
| 167 | } |
| 168 | return $this->OPTIONS; |
| 169 | } |
| 170 | public function getNewPDFObject() { |
| 171 | if (!class_exists('sasoEventtickets_PDF')) { |
| 172 | require_once("sasoEventtickets_PDF.php"); |
| 173 | } |
| 174 | $pdf = new sasoEventtickets_PDF(); |
| 175 | $pdf->setFontSize($this->getOptions()->getOptionValue('wcTicketPDFFontSize')); |
| 176 | $pdf->setFontFamily($this->getOptions()->getOptionValue('wcTicketPDFFontFamily')); |
| 177 | $pdf = apply_filters( $this->_add_filter_prefix.'main_getNewPDFObject', $pdf ); |
| 178 | return $pdf; |
| 179 | } |
| 180 | public function loadOnce($className, $filename="") { |
| 181 | if (!class_exists($className)) { |
| 182 | if ($filename == "") $filename = $className; |
| 183 | include_once __DIR__.'/'.$filename.'.php'; |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | /** |
| 188 | * Load class from /includes/ folder structure |
| 189 | * |
| 190 | * @param string $className The class name to load |
| 191 | * @param string $relativePath Path relative to plugin root (e.g., 'includes/woocommerce/class-base.php') |
| 192 | * @return void |
| 193 | */ |
| 194 | private function loadClass(string $className, string $relativePath): void { |
| 195 | if (class_exists($className)) { |
| 196 | return; // Already loaded |
| 197 | } |
| 198 | |
| 199 | $path = __DIR__ . '/' . $relativePath; |
| 200 | |
| 201 | if (file_exists($path)) { |
| 202 | require_once $path; |
| 203 | } |
| 204 | } |
| 205 | public function getWC() { |
| 206 | $this->loadOnce('sasoEventtickets_WC', "woocommerce-hooks"); |
| 207 | return sasoEventtickets_WC::Instance(); |
| 208 | } |
| 209 | public function getTicketHandler() { |
| 210 | $this->loadOnce('sasoEventtickets_Ticket'); |
| 211 | return sasoEventtickets_Ticket::Instance($_SERVER["REQUEST_URI"]); |
| 212 | } |
| 213 | public function getTicketDesignerHandler($template="") { |
| 214 | $this->loadOnce('sasoEventtickets_TicketDesigner'); |
| 215 | return sasoEventtickets_TicketDesigner::Instance($this, $template); |
| 216 | } |
| 217 | public function getTicketBadgeHandler() { |
| 218 | $this->loadOnce('sasoEventtickets_TicketBadge'); |
| 219 | return sasoEventtickets_TicketBadge::Instance(); |
| 220 | } |
| 221 | public function getTicketQRHandler() { |
| 222 | $this->loadOnce('sasoEventtickets_TicketQR'); |
| 223 | return sasoEventtickets_TicketQR::Instance(); |
| 224 | } |
| 225 | public function getAuthtokenHandler() { |
| 226 | $this->loadOnce('sasoEventtickets_Authtoken'); |
| 227 | return sasoEventtickets_Authtoken::Instance(); |
| 228 | } |
| 229 | public function getSeating() { |
| 230 | $this->loadOnce('sasoEventtickets_Seating'); |
| 231 | return sasoEventtickets_Seating::Instance($this); |
| 232 | } |
| 233 | public function getPremiumFunctions() { |
| 234 | if ($this->_isPrem == null && $this->PREMFUNCTIONS == null) { |
| 235 | $this->_isPrem = false; |
| 236 | $this->PREMFUNCTIONS = new sasoEventtickets_fakeprem(); |
| 237 | if (class_exists('sasoEventtickets_PremiumFunctions')) { |
| 238 | $this->PREMFUNCTIONS = new sasoEventtickets_PremiumFunctions($this, plugin_dir_path(__FILE__), $this->_prefix, $this->getDB()); |
| 239 | $this->_isPrem = $this->PREMFUNCTIONS->isPremium(); |
| 240 | } else { // old approach before v 2.5.7 |
| 241 | // this is causing issues with base_dir set |
| 242 | $premPluginFolder = $this->getPremiumPluginFolder(); |
| 243 | if (!empty($premPluginFolder)) { |
| 244 | $file = $premPluginFolder.$this->_premium_function_file; |
| 245 | $premiumFile = plugin_dir_path(__FILE__)."../".$file; |
| 246 | if (file_exists($premiumFile)) { // check ob active ist nicht nötig, das das getPremiumPluginFolder schon macht |
| 247 | if (!class_exists('sasoEventtickets_PremiumFunctions')) { |
| 248 | include_once $premiumFile; |
| 249 | } |
| 250 | $this->PREMFUNCTIONS = new sasoEventtickets_PremiumFunctions($this, plugin_dir_path(__FILE__), $this->_prefix, $this->getDB()); |
| 251 | $this->_isPrem = $this->PREMFUNCTIONS->isPremium(); |
| 252 | } |
| 253 | } |
| 254 | } |
| 255 | } |
| 256 | return $this->PREMFUNCTIONS; |
| 257 | } |
| 258 | private function getPremiumPluginFolder() { |
| 259 | $plugins = get_option('active_plugins', []); |
| 260 | $premiumFile = ""; |
| 261 | foreach($plugins as $plugin) { |
| 262 | if (strpos(" ".$plugin, $this->_premium_plugin_name) > 0) { |
| 263 | $premiumFile = plugin_dir_path($plugin); |
| 264 | break; |
| 265 | } |
| 266 | } |
| 267 | return $premiumFile; |
| 268 | } |
| 269 | public function isPremium() { |
| 270 | if ($this->_isPrem == null) $this->getPremiumFunctions(); |
| 271 | return $this->_isPrem; |
| 272 | } |
| 273 | public function getPrefix() { |
| 274 | return $this->_prefix; |
| 275 | } |
| 276 | public function getMV() { |
| 277 | $v = ['storeip'=>false,'allowuserreg'=>false,'codes_total'=>0x13,'codes'=>0x12,'lists'=>5,'authtokens_total'=>3]; |
| 278 | $v["codes"] = (int) hexdec(0x80 / 0x002) / 2; |
| 279 | $v["codes_total"] = (int) hexdec(0x80 / 0x002) / 2; |
| 280 | $v["seatingplans"] = (int) (0x04 >> 0x02); |
| 281 | $v["seats_per_plan"] = (int) (0x50 >> 0x02); |
| 282 | return $v; |
| 283 | } |
| 284 | public function listener_upgrader_process_complete( $upgrader_object, $options ) { |
| 285 | $current_plugin_path_name = plugin_basename( __FILE__ ); |
| 286 | if ($options['action'] == 'update' && $options['type'] == 'plugin' ) { |
| 287 | if (isset($options['plugins'])) { |
| 288 | foreach($options['plugins'] as $each_plugin) { |
| 289 | if ($each_plugin==$current_plugin_path_name) { |
| 290 | // .......................... YOUR CODES ............. |
| 291 | } |
| 292 | } |
| 293 | } |
| 294 | } |
| 295 | do_action( $this->_do_action_prefix.'main_listener_upgrader_process_complete' ); |
| 296 | } |
| 297 | /** |
| 298 | * check for ticket detail page request |
| 299 | */ |
| 300 | public function wc_checkTicketDetailPage() { |
| 301 | if( is_404() ){ |
| 302 | include_once("SASO_EVENTTICKETS.php"); |
| 303 | // /wp-content/plugins/event-tickets-with-ticket-scanner/ticket/ |
| 304 | $p = $this->getCore()->getTicketURLPath(true); |
| 305 | $t = explode("/", $_SERVER["REQUEST_URI"]); |
| 306 | if (count($t) > 1) { |
| 307 | if ($t[count($t)-2] != "scanner") { |
| 308 | if(substr($_SERVER["REQUEST_URI"], 0, strlen($p)) == $p) { |
| 309 | $this->getTicketHandler()->initFilterAndActions(); |
| 310 | } else { |
| 311 | $wcTicketCompatibilityModeURLPath = trim($this->getOptions()->getOptionValue('wcTicketCompatibilityModeURLPath')); |
| 312 | $wcTicketCompatibilityModeURLPath = trim(trim($wcTicketCompatibilityModeURLPath, "/")); |
| 313 | if (!empty($wcTicketCompatibilityModeURLPath)) { |
| 314 | $uri = trim($_SERVER["REQUEST_URI"]); |
| 315 | if (!empty($uri)) { |
| 316 | $pos = strpos($uri, $wcTicketCompatibilityModeURLPath); |
| 317 | if ($pos > 0) { |
| 318 | $this->getTicketHandler()->initFilterAndActions(); |
| 319 | } |
| 320 | } |
| 321 | } |
| 322 | } |
| 323 | } |
| 324 | |
| 325 | if ($t[count($t)-2] == "scanner") { |
| 326 | if(substr($_SERVER["REQUEST_URI"], 0, strlen($p)) == $p) { |
| 327 | //$this->replacingShortcodeTicketScanner(); |
| 328 | $this->getTicketHandler()->initFilterAndActionsTicketScanner(); |
| 329 | } else { |
| 330 | $wcTicketCompatibilityModeURLPath = trim($this->getOptions()->getOptionValue('wcTicketCompatibilityModeURLPath')); |
| 331 | $wcTicketCompatibilityModeURLPath = trim(trim($wcTicketCompatibilityModeURLPath, "/")); |
| 332 | if (!empty($wcTicketCompatibilityModeURLPath)) { |
| 333 | $uri = trim($_SERVER["REQUEST_URI"]); |
| 334 | if (!empty($uri)) { |
| 335 | $pos = strpos($_SERVER["REQUEST_URI"], $wcTicketCompatibilityModeURLPath."/scanner/"); |
| 336 | if ($pos > 0) { |
| 337 | $this->getTicketHandler()->initFilterAndActionsTicketScanner(); |
| 338 | } |
| 339 | } |
| 340 | } |
| 341 | } |
| 342 | } |
| 343 | } |
| 344 | } // endif 404 |
| 345 | } |
| 346 | private function init_frontend() { |
| 347 | add_shortcode($this->_shortcode, [$this, 'replacingShortcode']); |
| 348 | add_shortcode($this->_shortcode_mycode, [$this, 'replacingShortcodeMyCode']); |
| 349 | add_shortcode($this->_shortcode_ticket_scanner, [$this, 'replacingShortcodeTicketScanner']); |
| 350 | add_shortcode($this->_shortcode_eventviews, [$this, 'replacingShortcodeEventViews']); |
| 351 | add_shortcode($this->_shortcode_feature_list, [$this, 'replacingShortcodeFeatureList']); |
| 352 | add_shortcode($this->_shortcode_ticket_detail, [$this, 'replacingShortcodeTicketDetail']); |
| 353 | do_action( $this->_do_action_prefix.'main_init_frontend' ); |
| 354 | } |
| 355 | private function init_backend() { |
| 356 | add_action('admin_menu', [$this, 'register_options_page']); |
| 357 | register_activation_hook(__FILE__, [$this, 'plugin_activated']); |
| 358 | register_deactivation_hook( __FILE__, [$this, 'plugin_deactivated'] ); |
| 359 | //register_uninstall_hook( __FILE__, 'sasoEventticketsDB::plugin_uninstall' ); // MUSS NOCH GETESTE WERDEN |
| 360 | add_action( 'plugins_loaded', [$this, 'plugins_loaded'] ); |
| 361 | add_action( 'show_user_profile', [$this, 'show_user_profile'] ); |
| 362 | add_action( 'admin_notices', [$this, 'showSubscriptionWarning'] ); |
| 363 | add_action( 'admin_notices', [$this, 'showOutdatedPremiumWarning'] ); |
| 364 | |
| 365 | if (basename($_SERVER['SCRIPT_NAME']) == "admin-ajax.php") { |
| 366 | add_action('wp_ajax_'.$this->_prefix.'_executeAdminSettings', [$this,'executeAdminSettings_a'], 10, 0); |
| 367 | add_action('wp_ajax_'.$this->_prefix.'_executeSeatingAdmin', [$this,'executeSeatingAdmin_a'], 10, 0); |
| 368 | } |
| 369 | |
| 370 | do_action( $this->_do_action_prefix.'main_init_backend' ); |
| 371 | } |
| 372 | public function WooCommercePluginLoaded() { |
| 373 | // DON'T load WC here - let relay functions do lazy loading |
| 374 | //$this->getWC(); // um die wc handler zu laden |
| 375 | add_action('woocommerce_review_order_after_cart_contents', [$this, 'relay_woocommerce_review_order_after_cart_contents']); |
| 376 | add_action('woocommerce_checkout_process', [$this, 'relay_woocommerce_checkout_process']); |
| 377 | add_action('woocommerce_before_cart_table', [$this, 'relay_woocommerce_before_cart_table']); |
| 378 | add_action('woocommerce_cart_updated', [$this, 'relay_woocommerce_cart_updated']); |
| 379 | add_filter('woocommerce_email_attachments', [$this, 'relay_woocommerce_email_attachments'], 10, 3); |
| 380 | add_action('woocommerce_checkout_create_order_line_item', [$this, 'relay_woocommerce_checkout_create_order_line_item'], 20, 4 ); |
| 381 | add_action('woocommerce_check_cart_items', [$this, 'relay_woocommerce_check_cart_items'] ); |
| 382 | add_action('woocommerce_new_order', [$this, 'relay_woocommerce_new_order'], 10, 1); |
| 383 | add_action('woocommerce_checkout_update_order_meta', [$this, 'relay_woocommerce_checkout_update_order_meta'], 20, 2); |
| 384 | add_action('woocommerce_order_status_changed', [$this, 'relay_woocommerce_order_status_changed'], 10, 3); |
| 385 | add_filter('woocommerce_order_item_display_meta_key', [$this, 'relay_woocommerce_order_item_display_meta_key'], 20, 3 ); |
| 386 | add_filter('woocommerce_order_item_display_meta_value', [$this, 'relay_woocommerce_order_item_display_meta_value'], 20, 3); |
| 387 | add_action('wpo_wcpdf_after_item_meta', [$this, 'relay_wpo_wcpdf_after_item_meta'], 20, 3 ); |
| 388 | add_action('woocommerce_order_item_meta_start', [$this, 'relay_woocommerce_order_item_meta_start'], 201, 4); |
| 389 | add_action('woocommerce_product_after_variable_attributes', [$this, 'relay_woocommerce_product_after_variable_attributes'], 10, 3); |
| 390 | add_action('woocommerce_save_product_variation',[$this, 'relay_woocommerce_save_product_variation'], 10 ,2 ); |
| 391 | add_action('woocommerce_email_order_meta', [$this, 'relay_woocommerce_email_order_meta'], 10, 4 ); |
| 392 | add_action('woocommerce_thankyou', [$this, 'relay_woocommerce_thankyou'], 5); |
| 393 | if (wp_doing_ajax()) { |
| 394 | // erlaube ajax nonpriv und registriere handler |
| 395 | add_action('wp_ajax_nopriv_'.$this->getPrefix().'_executeWCFrontend', [$this,'relay_executeWCFrontend']); // nicht angemeldete user, sollen eine antwort erhalten |
| 396 | add_action('wp_ajax_'.$this->getPrefix().'_executeWCFrontend', [$this,'relay_executeWCFrontend']); // nicht angemeldete user, sollen eine antwort erhalten |
| 397 | // Seating Frontend AJAX (seat selection in shop) |
| 398 | add_action('wp_ajax_nopriv_'.$this->getPrefix().'_executeSeatingFrontend', [$this,'relay_executeSeatingFrontend']); |
| 399 | add_action('wp_ajax_'.$this->getPrefix().'_executeSeatingFrontend', [$this,'relay_executeSeatingFrontend']); |
| 400 | } |
| 401 | if (is_admin()) { |
| 402 | add_action('woocommerce_delete_order', [$this, 'relay_woocommerce_delete_order'], 10, 1 ); |
| 403 | add_action('woocommerce_delete_order_item', [$this, 'relay_woocommerce_delete_order_item'], 20, 1); |
| 404 | add_action('woocommerce_pre_delete_order_refund', [$this, 'relay_woocommerce_pre_delete_order_refund'], 10, 3); |
| 405 | add_action('woocommerce_delete_order_refund', [$this, 'relay_woocommerce_delete_order_refund'], 10, 1 ); |
| 406 | add_action('woocommerce_order_partially_refunded', [$this, 'relay_woocommerce_order_partially_refunded'], 10, 2); |
| 407 | add_filter('woocommerce_product_data_tabs', [$this, 'relay_woocommerce_product_data_tabs'], 98 ); |
| 408 | add_action('woocommerce_product_data_panels', [$this, 'relay_woocommerce_product_data_panels'] ); |
| 409 | add_action('woocommerce_process_product_meta', [$this, 'relay_woocommerce_process_product_meta'], 10, 2 ); |
| 410 | add_action('add_meta_boxes', [$this, 'relay_add_meta_boxes'], 10, 2); |
| 411 | add_filter('manage_edit-product_columns', [$this, 'relay_manage_edit_product_columns']); |
| 412 | add_action('manage_product_posts_custom_column', [$this, 'relay_manage_product_posts_custom_column'], 2); |
| 413 | add_filter("manage_edit-product_sortable_columns", [$this, 'relay_manage_edit_product_sortable_columns']); |
| 414 | } else { |
| 415 | add_action('woocommerce_single_product_summary', [$this, 'relay_woocommerce_single_product_summary']); |
| 416 | } |
| 417 | |
| 418 | // set routing -- NEEDS to be replaced by add_rewrite_rule later |
| 419 | add_action( 'template_redirect', [$this, 'wc_checkTicketDetailPage'], 1 ); |
| 420 | //$this->wc_checkTicketDetailPage(); |
| 421 | add_action('rest_api_init', function () { |
| 422 | SASO_EVENTTICKETS::setRestRoutesTicket(); |
| 423 | }); |
| 424 | |
| 425 | add_action('woocommerce_after_shop_loop_item', [$this, 'relay_woocommerce_after_shop_loop_item'], 9); // with 9 we are just before the add to cart button |
| 426 | add_filter('woocommerce_add_to_cart_validation', [$this, 'relay_woocommerce_add_to_cart_validation'], 10, 3); |
| 427 | add_filter('woocommerce_add_cart_item_data', [$this, 'relay_woocommerce_add_cart_item_data'], 10, 3); |
| 428 | add_action('woocommerce_add_to_cart', [$this, 'relay_woocommerce_add_to_cart'], 10, 6); |
| 429 | add_action('woocommerce_cart_item_removed', [$this, 'relay_woocommerce_cart_item_removed'], 10, 2); |
| 430 | add_action('woocommerce_after_cart_item_quantity_update', [$this, 'relay_woocommerce_after_cart_item_quantity_update'], 10, 4); |
| 431 | add_filter('woocommerce_update_cart_validation', [$this, 'relay_woocommerce_update_cart_validation'], 10, 4); |
| 432 | add_action('woocommerce_before_add_to_cart_button', [$this, 'relay_woocommerce_before_add_to_cart_button'], 15); |
| 433 | |
| 434 | do_action( $this->_do_action_prefix.'main_WooCommercePluginLoaded' ); |
| 435 | } |
| 436 | public function relay_woocommerce_after_shop_loop_item() { |
| 437 | $this->getWC()->getFrontendManager()->woocommerce_after_shop_loop_item_handler(); |
| 438 | } |
| 439 | public function relay_woocommerce_add_to_cart_validation() { |
| 440 | $args = func_get_args(); |
| 441 | return $this->getWC()->getFrontendManager()->woocommerce_add_to_cart_validation_handler(...$args); |
| 442 | } |
| 443 | public function relay_woocommerce_add_cart_item_data() { |
| 444 | $args = func_get_args(); |
| 445 | return $this->getWC()->getFrontendManager()->woocommerce_add_cart_item_data_handler(...$args); |
| 446 | } |
| 447 | public function relay_woocommerce_add_to_cart() { |
| 448 | $args = func_get_args(); |
| 449 | return $this->getWC()->getFrontendManager()->woocommerce_add_to_cart_handler(...$args); |
| 450 | } |
| 451 | public function relay_woocommerce_cart_item_removed() { |
| 452 | $args = func_get_args(); |
| 453 | $this->getWC()->getFrontendManager()->woocommerce_cart_item_removed_handler(...$args); |
| 454 | } |
| 455 | public function relay_woocommerce_after_cart_item_quantity_update() { |
| 456 | $args = func_get_args(); |
| 457 | $this->getWC()->getFrontendManager()->woocommerce_after_cart_item_quantity_update_handler(...$args); |
| 458 | } |
| 459 | public function relay_woocommerce_update_cart_validation() { |
| 460 | $args = func_get_args(); |
| 461 | return $this->getWC()->getFrontendManager()->woocommerce_update_cart_validation_handler(...$args); |
| 462 | } |
| 463 | public function relay_woocommerce_before_add_to_cart_button() { |
| 464 | $this->getWC()->getFrontendManager()->woocommerce_before_add_to_cart_button_handler(); |
| 465 | } |
| 466 | public function relay_woocommerce_review_order_after_cart_contents() { |
| 467 | $this->getWC()->getFrontendManager()->woocommerce_review_order_after_cart_contents(); |
| 468 | } |
| 469 | public function relay_woocommerce_checkout_process() { |
| 470 | $this->getWC()->getFrontendManager()->woocommerce_checkout_process(); |
| 471 | } |
| 472 | public function relay_woocommerce_before_cart_table() { |
| 473 | $this->getWC()->getFrontendManager()->woocommerce_before_cart_table(); |
| 474 | } |
| 475 | public function relay_woocommerce_cart_updated() { |
| 476 | $this->getWC()->getFrontendManager()->woocommerce_cart_updated_handler(); |
| 477 | } |
| 478 | public function relay_woocommerce_email_attachments() { |
| 479 | $args = func_get_args(); |
| 480 | return $this->getWC()->getEmailHandler()->woocommerce_email_attachments(...$args); |
| 481 | } |
| 482 | public function relay_woocommerce_checkout_create_order_line_item() { |
| 483 | $args = func_get_args(); |
| 484 | return $this->getWC()->getOrderManager()->woocommerce_checkout_create_order_line_item(...$args); |
| 485 | } |
| 486 | public function relay_woocommerce_check_cart_items() { |
| 487 | $this->getWC()->getFrontendManager()->woocommerce_check_cart_items(); |
| 488 | } |
| 489 | public function relay_woocommerce_new_order() { |
| 490 | $args = func_get_args(); |
| 491 | return $this->getWC()->getOrderManager()->woocommerce_new_order(...$args); |
| 492 | } |
| 493 | public function relay_woocommerce_checkout_update_order_meta() { |
| 494 | $args = func_get_args(); |
| 495 | return $this->getWC()->getOrderManager()->woocommerce_checkout_update_order_meta(...$args); |
| 496 | } |
| 497 | public function relay_executeWCFrontend() { |
| 498 | return $this->getWC()->getFrontendManager()->executeWCFrontend(); |
| 499 | } |
| 500 | public function relay_executeSeatingFrontend() { |
| 501 | return $this->getSeating()->getFrontendManager()->executeSeatingFrontend(); |
| 502 | } |
| 503 | public function relay_woocommerce_delete_order() { |
| 504 | $args = func_get_args(); |
| 505 | $this->getWC()->getOrderManager()->woocommerce_delete_order(...$args); |
| 506 | } |
| 507 | public function relay_woocommerce_delete_order_item() { |
| 508 | $args = func_get_args(); |
| 509 | $this->getWC()->getOrderManager()->woocommerce_delete_order_item(...$args); |
| 510 | } |
| 511 | public function relay_woocommerce_pre_delete_order_refund() { |
| 512 | $args = func_get_args(); |
| 513 | $this->getWC()->getOrderManager()->woocommerce_pre_delete_order_refund(...$args); |
| 514 | } |
| 515 | public function relay_woocommerce_delete_order_refund() { |
| 516 | $args = func_get_args(); |
| 517 | $this->getWC()->getOrderManager()->woocommerce_delete_order_refund(...$args); |
| 518 | } |
| 519 | public function relay_woocommerce_product_data_tabs() { |
| 520 | $args = func_get_args(); |
| 521 | return $this->getWC()->getProductManager()->woocommerce_product_data_tabs(...$args); |
| 522 | } |
| 523 | public function relay_woocommerce_product_data_panels() { |
| 524 | $this->getWC()->getProductManager()->woocommerce_product_data_panels(); |
| 525 | } |
| 526 | public function relay_woocommerce_process_product_meta() { |
| 527 | $args = func_get_args(); |
| 528 | $this->getWC()->getProductManager()->woocommerce_process_product_meta(...$args); |
| 529 | } |
| 530 | public function relay_add_meta_boxes(...$args) { |
| 531 | $this->getWC()->add_meta_boxes(...$args); |
| 532 | } |
| 533 | public function relay_manage_edit_product_columns() { |
| 534 | $args = func_get_args(); |
| 535 | return $this->getWC()->getProductManager()->manage_edit_product_columns(...$args); |
| 536 | } |
| 537 | public function relay_manage_product_posts_custom_column() { |
| 538 | $args = func_get_args(); |
| 539 | $this->getWC()->getProductManager()->manage_product_posts_custom_column(...$args); |
| 540 | } |
| 541 | public function relay_manage_edit_product_sortable_columns() { |
| 542 | $args = func_get_args(); |
| 543 | return $this->getWC()->getProductManager()->manage_edit_product_sortable_columns(...$args); |
| 544 | } |
| 545 | public function relay_woocommerce_single_product_summary() { |
| 546 | $this->getWC()->getFrontendManager()->woocommerce_single_product_summary(); |
| 547 | } |
| 548 | public function relay_woocommerce_order_status_changed() { |
| 549 | $args = func_get_args(); |
| 550 | $this->getWC()->getOrderManager()->woocommerce_order_status_changed(...$args); |
| 551 | } |
| 552 | public function relay_woocommerce_order_partially_refunded() { |
| 553 | $args = func_get_args(); |
| 554 | $this->getWC()->getOrderManager()->woocommerce_order_partially_refunded(...$args); |
| 555 | } |
| 556 | public function relay_woocommerce_order_item_display_meta_key() { |
| 557 | $args = func_get_args(); |
| 558 | return $this->getWC()->getOrderManager()->woocommerce_order_item_display_meta_key(...$args); |
| 559 | } |
| 560 | public function relay_woocommerce_order_item_display_meta_value() { |
| 561 | $args = func_get_args(); |
| 562 | return $this->getWC()->getOrderManager()->woocommerce_order_item_display_meta_value(...$args); |
| 563 | } |
| 564 | public function relay_wpo_wcpdf_after_item_meta() { |
| 565 | $args = func_get_args(); |
| 566 | $this->getWC()->getOrderManager()->wpo_wcpdf_after_item_meta(...$args); |
| 567 | } |
| 568 | public function relay_woocommerce_order_item_meta_start() { |
| 569 | $args = func_get_args(); |
| 570 | $this->getWC()->getOrderManager()->woocommerce_order_item_meta_start(...$args); |
| 571 | } |
| 572 | public function relay_woocommerce_product_after_variable_attributes() { |
| 573 | $args = func_get_args(); |
| 574 | $this->getWC()->getProductManager()->woocommerce_product_after_variable_attributes(...$args); |
| 575 | } |
| 576 | public function relay_woocommerce_save_product_variation() { |
| 577 | $args = func_get_args(); |
| 578 | $this->getWC()->getProductManager()->woocommerce_save_product_variation(...$args); |
| 579 | } |
| 580 | public function relay_woocommerce_email_order_meta() { |
| 581 | $args = func_get_args(); |
| 582 | $this->getWC()->getEmailHandler()->woocommerce_email_order_meta(...$args); |
| 583 | } |
| 584 | public function relay_woocommerce_thankyou() { |
| 585 | $args = func_get_args(); |
| 586 | $this->getWC()->getFrontendManager()->woocommerce_thankyou(...$args); |
| 587 | } |
| 588 | public function relay_sasoEventtickets_cronjob_daily() { |
| 589 | $this->getTicketHandler()->cronJobDaily(); |
| 590 | } |
| 591 | |
| 592 | public function plugin_deactivated() { |
| 593 | $this->cronjob_daily_deactivate(); |
| 594 | $this->getDB(); |
| 595 | sasoEventticketsDB::plugin_deactivated(); |
| 596 | do_action( $this->_do_action_prefix.'main_plugin_deactivated' ); |
| 597 | } |
| 598 | public function plugin_uninstall() { |
| 599 | $this->getDB(); |
| 600 | sasoEventticketsDB::plugin_uninstall(); |
| 601 | $this->getAdmin(); |
| 602 | sasoEventtickets_AdminSettings::plugin_uninstall(); |
| 603 | do_action( $this->_do_action_prefix.'main_WooCommercePluginLoaded' ); |
| 604 | } |
| 605 | public function plugin_activated($is_network_wide=false) { // und auch für updates, macht es einfacher |
| 606 | $this->getDB(); // um installiere Tabellen auszuführen |
| 607 | update_option('SASO_EVENTTICKETS_PLUGIN_VERSION', SASO_EVENTTICKETS_PLUGIN_VERSION); |
| 608 | $this->getAdmin()->generateFirstCodeList(); |
| 609 | $this->cronjob_daily_activate(); |
| 610 | do_action( $this->_do_action_prefix.'activated' ); |
| 611 | do_action( $this->_do_action_prefix.'main_plugin_activated' ); |
| 612 | } |
| 613 | public function plugins_loaded() { |
| 614 | if (SASO_EVENTTICKETS_PLUGIN_VERSION !== get_option('SASO_EVENTTICKETS_PLUGIN_VERSION', '')) $this->plugin_activated(); // vermutlich wurde die aktivierung übersprungen, bei änderungen direkt an den files |
| 615 | } |
| 616 | public function initialize_plugin() { |
| 617 | $this->getDB(); // um installiere Tabellen auszuführen |
| 618 | do_action( $this->_do_action_prefix.'initialized' ); |
| 619 | do_action( $this->_do_action_prefix.'main_initialize_plugin' ); |
| 620 | } |
| 621 | function show_user_profile($profileuser) { |
| 622 | $this->getAdmin()->show_user_profile($profileuser); |
| 623 | do_action( $this->_do_action_prefix.'main_show_user_profile' ); |
| 624 | } |
| 625 | function register_options_page() { |
| 626 | $allowed = $this->isUserAllowedToAccessAdminArea(); |
| 627 | $allowed = apply_filters( $this->_add_filter_prefix.'main_options_page', $allowed ); |
| 628 | if ($allowed) { |
| 629 | add_options_page(__('Event Tickets', 'event-tickets-with-ticket-scanner'), 'Event Tickets', 'manage_options', 'event-tickets-with-ticket-scanner', [$this,'options_page']); |
| 630 | add_menu_page( __('Event Tickets', 'event-tickets-with-ticket-scanner'), 'Event Tickets', 'read', 'event-tickets-with-ticket-scanner', [$this,'options_page'], plugins_url( "",__FILE__ )."/img/icon_event-tickets-with-ticket-scanner_18px.gif", null ); |
| 631 | } |
| 632 | do_action( $this->_do_action_prefix.'main_register_options_page' ); |
| 633 | } |
| 634 | |
| 635 | function options_page() { |
| 636 | $allowed = $this->isUserAllowedToAccessAdminArea(); |
| 637 | $allowed = apply_filters( $this->_add_filter_prefix.'main_options_page', $allowed ); |
| 638 | if ( !$allowed ) { |
| 639 | wp_die( __( 'You do not have sufficient permissions to access this page.', 'event-tickets-with-ticket-scanner' ) ); |
| 640 | } |
| 641 | |
| 642 | wp_enqueue_style("wp-jquery-ui-dialog"); |
| 643 | |
| 644 | $js_url = "jquery.qrcode.min.js?_v=".$this->_js_version; |
| 645 | wp_register_script('ajax_script2', plugins_url( "3rd/".$js_url,__FILE__ ), array('jquery', 'jquery-ui-dialog')); |
| 646 | wp_enqueue_script('ajax_script2'); |
| 647 | |
| 648 | wp_enqueue_media(); // um die js wp.media lib zu laden |
| 649 | |
| 650 | // einbinden das js starter skript |
| 651 | $js_url = $this->_js_file."?_v=".$this->_js_version; |
| 652 | if (defined( 'WP_DEBUG')) $js_url .= '&debug=1'; |
| 653 | wp_register_script('ajax_script_backend', plugins_url( $js_url,__FILE__ ), array('jquery', 'jquery-ui-dialog', 'wp-i18n')); |
| 654 | wp_enqueue_script('ajax_script_backend'); |
| 655 | wp_set_script_translations('ajax_script_backend', 'event-tickets-with-ticket-scanner', __DIR__.'/languages'); |
| 656 | |
| 657 | // per script eine variable einbinden, die url hat den wp-admin prefix |
| 658 | // damit im backend.js dann die richtige callback url genutzt werden kann |
| 659 | $vars = array( |
| 660 | '_plugin_home_url' =>plugins_url( "",__FILE__ ), |
| 661 | '_plugin_version' => $this->getPluginVersion(), |
| 662 | '_action' => $this->_prefix.'_executeAdminSettings', |
| 663 | '_max'=>$this->getBase()->getMaxValues(), |
| 664 | '_isPremium'=>$this->isPremium(), |
| 665 | '_isUserLoggedin'=>is_user_logged_in(), |
| 666 | '_premJS'=>$this->isPremium() && method_exists($this->getPremiumFunctions(), "getJSBackendFile") ? $this->getPremiumFunctions()->getJSBackendFile() : '', |
| 667 | 'url' => admin_url( 'admin-ajax.php' ), |
| 668 | 'ticket_url' => $this->getCore()->getTicketURLPath(), |
| 669 | 'nonce' => wp_create_nonce( $this->_js_nonce ), |
| 670 | 'ajaxActionPrefix' => $this->_prefix, |
| 671 | 'divPrefix' => $this->_prefix, |
| 672 | 'divId' => $this->_divId, |
| 673 | 'jsFiles' => plugins_url( 'backend.js?_v='.$this->_js_version,__FILE__ ) |
| 674 | ); |
| 675 | $vars = apply_filters( $this->_add_filter_prefix.'main_options_page', $vars ); |
| 676 | wp_localize_script( |
| 677 | 'ajax_script_backend', |
| 678 | 'Ajax_'.$this->_prefix, // name der injected variable |
| 679 | $vars |
| 680 | ); |
| 681 | |
| 682 | do_action( $this->_do_action_prefix.'main_options_page' ); |
| 683 | |
| 684 | $versions = $this->getPluginVersions(); |
| 685 | $versions_tail = $versions['basic'].($versions['premium'] != "" ? ', Premium: '.$versions['premium'] : ''); |
| 686 | $version_tail_add = ""; |
| 687 | if ($versions['debug'] != "") $version_tail_add .= 'DEBUG: '.$versions['debug'].', LANG: '.determine_locale(); |
| 688 | ?> |
| 689 | <div class="event-tickets-with-ticket-scanner-admin-page"> |
| 690 | <div class="event-tickets-with-ticket-scanner-header"> |
| 691 | <div class="event-tickets-with-ticket-scanner-header-left"> |
| 692 | <img src="<?php echo plugins_url( "",__FILE__ ); ?>/img/logo_event-tickets-with-ticket-scanner.gif" |
| 693 | alt="Event Tickets" |
| 694 | class="event-tickets-with-ticket-scanner-header-logo"> |
| 695 | |
| 696 | <div class="event-tickets-with-ticket-scanner-header-title"> |
| 697 | <div class="event-tickets-with-ticket-scanner-header-name"> |
| 698 | Event Tickets with Ticket Scanner |
| 699 | </div> |
| 700 | <div class="event-tickets-with-ticket-scanner-header-meta"> |
| 701 | <?php esc_html_e('Version', 'event-tickets-with-ticket-scanner'); ?>: <?php echo $versions_tail; ?> <?php echo $version_tail_add; ?> |
| 702 | </div> |
| 703 | </div> |
| 704 | </div> |
| 705 | |
| 706 | <div class="event-tickets-with-ticket-scanner-header-right" id="event-tickets-with-ticket-scanner-header-actions"> |
| 707 | <!-- Button kommt via JS --> |
| 708 | </div> |
| 709 | </div> |
| 710 | |
| 711 | <div style="clear:both;" data-id="plugin_addons"></div> |
| 712 | <div style="clear:both;" data-id="plugin_info_area"></div> |
| 713 | <div style="clear:both;" id="<?php echo esc_attr($this->_divId); ?>">...loading...</div> |
| 714 | <div style="margin-top:100px;"> |
| 715 | <hr> |
| 716 | <a name="shortcodedetails"></a> |
| 717 | <h3>Documentation</h3> |
| 718 | <p><span class="dashicons dashicons-external"></span><a href="https://vollstart.com/event-tickets-with-ticket-scanner/docs/" target="_blank">Click here, to visit the documentation of this plugin.</a></p> |
| 719 | <h3><?php esc_html_e('Plugin Rating', 'event-tickets-with-ticket-scanner'); ?></h3> |
| 720 | <p><?php esc_html_e('If you like our plugin, then please give us a', 'event-tickets-with-ticket-scanner'); ?> <a target="_blank" href="https://wordpress.org/support/plugin/event-tickets-with-ticket-scanner/reviews?rate=5#new-post">� |
| 721 | � |
| 722 | � |
| 723 | � |
| 724 | � |
| 725 | 5-Star Rating</a>.</p> |
| 726 | <h3><?php esc_html_e('Ticket Sale option', 'event-tickets-with-ticket-scanner'); ?></h3> |
| 727 | <p><?php esc_html_e('You can use this plugin to sell tickets and even redeem them. Check out the documentation for', 'event-tickets-with-ticket-scanner'); ?> <a target="_blank" href="https://vollstart.com/event-tickets-with-ticket-scanner/docs/#ticket"><?php esc_html_e('more details here', 'event-tickets-with-ticket-scanner'); ?></a>.</p> |
| 728 | <h3><?php esc_html_e('Premium Homepage', 'event-tickets-with-ticket-scanner'); ?></h3> |
| 729 | <p><?php esc_html_e('You can find more details about the', 'event-tickets-with-ticket-scanner'); ?> <a target="_blank" href="https://vollstart.com/event-tickets-with-ticket-scanner/"><?php esc_html_e('premium version here', 'event-tickets-with-ticket-scanner'); ?></a>.</p> |
| 730 | <!-- |
| 731 | <h3>Shortcode parameter In- & Output</h3> |
| 732 | <a href="https://vollstart.com/event-tickets-with-ticket-scanner/docs/" target="_blank">Click here for more help about the options</a> |
| 733 | <p>You can use your own HTML input, output and trigger component. If you add the parameters (all 3 mandatory to use this feature), then the default input area will not be rendered.</p> |
| 734 | <ul> |
| 735 | <li><b>inputid</b><br>inputid="html-element-id". The value of this component will be taken. It need to be an HTML input element. We will access the value-parameter of it.</li> |
| 736 | <li><b>triggerid</b><br>triggerid="html-element-id". The onclick event of this component will be replaced by our function to call the server validation with the code.</li> |
| 737 | <li><b>outputid</b><br>outputid="html-element-id". The content of this component will be replaced by the server result after the check . We will use the innerHTML property of it, so use a DIV, SPAN, TD or similar for best results.</li> |
| 738 | </ul> |
| 739 | <h3>Shortcode parameter Javascript</h3> |
| 740 | <p>You can add your Javascript function name. Both parameters are optional and not required. If functions will be called before the code is sent to the server or displaying the result.</p> |
| 741 | <ul> |
| 742 | <li><b>jspre</b><br>jspre="function-name". The function will be called. The input parameter will be the code. If your function returns a value, than this returned value will be used otherwise the entered code will be used.</li> |
| 743 | <li><b>jsafter</b><br>jsafter="function-name". The function will be called. The input parameter will be the result JSON object from the server.</li> |
| 744 | </ul> |
| 745 | --> |
| 746 | <h3><?php esc_html_e('Shortcode to display the event calendar form within a page', 'event-tickets-with-ticket-scanner'); ?></h3> |
| 747 | <b>[<?php echo esc_html($this->_shortcode_eventviews); ?>]</b> |
| 748 | <p><?php esc_html_e('The event calendar form will be displayed. You can add the following parameters to change the output:', 'event-tickets-with-ticket-scanner'); ?></p> |
| 749 | <ul> |
| 750 | <!--<li>view<br>Values: calendar, list or calendar|list<br>Default: list</li>--> |
| 751 | <li>months_to_show<br>Values can be a number higher than 0. Default: 3</li> |
| 752 | </ul> |
| 753 | <p>CSS file: <a href="<?php echo plugins_url( "",__FILE__ ); ?>/css/calendar.css" target="_blank">calendar.css</a></p> |
| 754 | <h3><?php esc_html_e('Shortcode to display the assigned tickets and codes of an user within a page', 'event-tickets-with-ticket-scanner'); ?></h3> |
| 755 | <b>[<?php echo esc_html($this->_shortcode_mycode); ?>]</b> |
| 756 | <p><?php esc_html_e('Displays tickets assigned to the current logged-in user (default) or tickets from a specific order.', 'event-tickets-with-ticket-scanner'); ?></p> |
| 757 | <ul> |
| 758 | <li><b>order_id</b> - <?php esc_html_e('Show tickets from a specific order instead of user tickets. Security: User must own the order or have valid order key in URL.', 'event-tickets-with-ticket-scanner'); ?><br> |
| 759 | <?php esc_html_e('Example:', 'event-tickets-with-ticket-scanner'); ?> [<?php echo esc_html($this->_shortcode_mycode); ?> order_id="123"]</li> |
| 760 | <li><b>format</b> - <?php esc_html_e('Output format. Values: json', 'event-tickets-with-ticket-scanner'); ?></li> |
| 761 | <li><b>display</b> - <?php esc_html_e('Fields to show (comma-separated). Values: codes, validation, user, used, confirmedCount, woocommerce, wc_rp, wc_ticket', 'event-tickets-with-ticket-scanner'); ?></li> |
| 762 | <li><b>download_all_pdf</b> - <?php esc_html_e('Show download button for all tickets as one PDF. Values: true/false', 'event-tickets-with-ticket-scanner'); ?></li> |
| 763 | </ul> |
| 764 | <p> |
| 765 | <?php esc_html_e('Example with JSON output:', 'event-tickets-with-ticket-scanner'); ?> [<?php echo esc_html($this->_shortcode_mycode); ?> format="json" display="code,wc_ticket"] |
| 766 | </p> |
| 767 | <h3><?php esc_html_e('Shortcode to display the ticket scanner within a page', 'event-tickets-with-ticket-scanner'); ?></h3> |
| 768 | <?php esc_html_e('Useful if you cannot open the ticket scanner due to security issues.', 'event-tickets-with-ticket-scanner'); ?><br> |
| 769 | <b>[<?php echo esc_html($this->_shortcode_ticket_scanner); ?>]</b> |
| 770 | <h3><?php esc_html_e('Shortcode to display ticket detail view within a page', 'event-tickets-with-ticket-scanner'); ?></h3> |
| 771 | <?php esc_html_e('Useful if the /ticket/ URL path does not work on your server.', 'event-tickets-with-ticket-scanner'); ?><br> |
| 772 | <b>[<?php echo esc_html($this->_shortcode_ticket_detail); ?>]</b> |
| 773 | <p> |
| 774 | <?php esc_html_e('Usage: Add the shortcode to a page and access it with ?ticket=YOUR-TICKET-CODE in the URL.', 'event-tickets-with-ticket-scanner'); ?><br> |
| 775 | <?php esc_html_e('Example:', 'event-tickets-with-ticket-scanner'); ?> yoursite.com/ticket-page/?ticket=ABC-123-XYZ<br> |
| 776 | <?php esc_html_e('Or use the code attribute:', 'event-tickets-with-ticket-scanner'); ?> [<?php echo esc_html($this->_shortcode_ticket_detail); ?> code="ABC-123-XYZ"] |
| 777 | </p> |
| 778 | <h3><?php esc_html_e('PHP Filters', 'event-tickets-with-ticket-scanner'); ?></h3> |
| 779 | <p><?php esc_html_e('You can use PHP code to register your filter functions for the validation check.', 'event-tickets-with-ticket-scanner'); ?> |
| 780 | <a href="https://vollstart.com/event-tickets-with-ticket-scanner/docs/#filters" target="_blank"><?php esc_html_e('Click here for more help about the functions', 'event-tickets-with-ticket-scanner'); ?></a> |
| 781 | </p> |
| 782 | <ul> |
| 783 | <li>add_filter('<?php echo $this->_add_filter_prefix.'beforeCheckCodePre'; ?>', 'myfunc', 20, 1)</li> |
| 784 | <li>add_filter('<?php echo $this->_add_filter_prefix.'beforeCheckCode'; ?>', 'myfunc', 20, 1)</li> |
| 785 | <li>add_filter('<?php echo $this->_add_filter_prefix.'afterCheckCodePre'; ?>', 'myfunc', 20, 1)</li> |
| 786 | <li>add_filter('<?php echo $this->_add_filter_prefix.'afterCheckCode'; ?>', 'myfunc', 20, 1)</li> |
| 787 | </ul> |
| 788 | <p>More BETA filters and actions hooks can be found <a href="https://vollstart.com/event-tickets-with-ticket-scanner/docs/ticket-plugin-api/" target="_blank">here (NOT STABLE, be aware that they might be changed in the future)</a>. |
| 789 | <p style="text-align:center;"><a target="_blank" href="https://vollstart.com">VOLLSTART</a> - More plugins: <a target="_blank" href="https://wordpress.org/plugins/serial-codes-generator-and-validator/">Serial Code Validator</a></p> |
| 790 | </div> |
| 791 | </div> |
| 792 | <?php |
| 793 | do_action( $this->_do_action_prefix.'options_page' ); |
| 794 | } |
| 795 | |
| 796 | public function isUserAllowedToAccessAdminArea() { |
| 797 | if ($this->isAllowedAccess != null) return $this->isAllowedAccess; |
| 798 | if ($this->getOptions()->isOptionCheckboxActive('allowOnlySepcificRoleAccessToAdmin')) { |
| 799 | // check welche rollen |
| 800 | $user = wp_get_current_user(); |
| 801 | $user_roles = (array) $user->roles; |
| 802 | if (in_array("administrator", $user_roles)) { |
| 803 | $this->isAllowedAccess = true; |
| 804 | } else { |
| 805 | $adminAreaAllowedRoles = $this->getOptions()->getOptionValue('adminAreaAllowedRoles'); |
| 806 | if (!is_array($adminAreaAllowedRoles)) { |
| 807 | if (empty($adminAreaAllowedRoles)) { |
| 808 | $adminAreaAllowedRoles = []; |
| 809 | } else { |
| 810 | $adminAreaAllowedRoles = [$adminAreaAllowedRoles]; |
| 811 | } |
| 812 | } |
| 813 | foreach($adminAreaAllowedRoles as $role_name) { |
| 814 | if (in_array($role_name, $user_roles)) { |
| 815 | $this->isAllowedAccess = true; |
| 816 | break; |
| 817 | }; |
| 818 | } |
| 819 | } |
| 820 | } else { |
| 821 | // Standard: Only administrators have access |
| 822 | $this->isAllowedAccess = current_user_can('manage_options'); |
| 823 | } |
| 824 | $this->isAllowedAccess = apply_filters( $this->_add_filter_prefix.'main_isUserAllowedToAccessAdminArea', $this->isAllowedAccess ); |
| 825 | return $this->isAllowedAccess; |
| 826 | } |
| 827 | |
| 828 | public function executeAdminSettings_a() { |
| 829 | if (!SASO_EVENTTICKETS::issetRPara('a_sngmbh')) return wp_send_json_success("a_sngmbh not provided"); |
| 830 | return $this->executeAdminSettings(SASO_EVENTTICKETS::getRequestPara('a_sngmbh')); // to prevent WP adds parameters |
| 831 | } |
| 832 | |
| 833 | public function executeAdminSettings($a=0, $data=null) { |
| 834 | if (!$this->isUserAllowedToAccessAdminArea()) { |
| 835 | return wp_send_json_error("Access denied", 403); |
| 836 | } |
| 837 | if ($a === 0 && !SASO_EVENTTICKETS::issetRPara('a_sngmbh')) return wp_send_json_success("a not provided"); |
| 838 | |
| 839 | if ($data == null) { |
| 840 | $data = SASO_EVENTTICKETS::issetRPara('data') ? SASO_EVENTTICKETS::getRequestPara('data') : []; |
| 841 | } |
| 842 | if ($a === 0 || empty($a) || trim($a) == "") { |
| 843 | $a = SASO_EVENTTICKETS::getRequestPara('a_sngmbh'); |
| 844 | } |
| 845 | do_action( $this->_do_action_prefix.'executeAdminSettings', $a, $data ); |
| 846 | return $this->getAdmin()->executeJSON($a, $data, false, false); // with nonce check |
| 847 | } |
| 848 | |
| 849 | public function executeSeatingAdmin_a() { |
| 850 | return $this->executeSeatingAdmin(SASO_EVENTTICKETS::getRequestPara('a')); |
| 851 | } |
| 852 | |
| 853 | public function executeSeatingAdmin($a = '', $data = null) { |
| 854 | if (!$this->isUserAllowedToAccessAdminArea()) { |
| 855 | return wp_send_json_error('Access denied', 403); |
| 856 | } |
| 857 | if (empty($a) && !SASO_EVENTTICKETS::issetRPara('a')) { |
| 858 | return wp_send_json_error('a not provided'); |
| 859 | } |
| 860 | if ($data === null) { |
| 861 | $data = SASO_EVENTTICKETS::getRequest(); |
| 862 | } |
| 863 | if (empty($a)) { |
| 864 | $a = SASO_EVENTTICKETS::getRequestPara('a'); |
| 865 | } |
| 866 | return $this->getSeating()->getAdminHandler()->executeSeatingJSON($a, $data); |
| 867 | } |
| 868 | |
| 869 | public function executeFrontend_a() { |
| 870 | return $this->executeFrontend(); // to prevent WP adds parameters |
| 871 | } |
| 872 | |
| 873 | public function executeWCBackend() { |
| 874 | if (!$this->isUserAllowedToAccessAdminArea()) { |
| 875 | return wp_send_json_error("Access denied", 403); |
| 876 | } |
| 877 | if (!SASO_EVENTTICKETS::issetRPara('a_sngmbh')) return wp_send_json_success("a_sngmbh not provided"); |
| 878 | $data = SASO_EVENTTICKETS::issetRPara('data') ? SASO_EVENTTICKETS::getRequestPara('data') : []; |
| 879 | return $this->getWC()->executeJSON(SASO_EVENTTICKETS::getRequestPara('a_sngmbh'), $data); |
| 880 | } |
| 881 | |
| 882 | public function executeFrontend($a=0, $data=null) { |
| 883 | $sasoEventtickets_Frontend = $this->getFrontend(); |
| 884 | if ($a === 0 && !SASO_EVENTTICKETS::issetRPara('a_sngmbh')) return wp_send_json_success("a not provided"); |
| 885 | |
| 886 | if ($data == null) { |
| 887 | $data = SASO_EVENTTICKETS::issetRPara('data') ? SASO_EVENTTICKETS::getRequestPara('data') : []; |
| 888 | } |
| 889 | if ($a === 0 || empty($a) || trim($a) == "") { |
| 890 | $a = SASO_EVENTTICKETS::getRequestPara('a_sngmbh'); |
| 891 | } |
| 892 | do_action( $this->_do_action_prefix.'executeFrontend', $a, $data ); |
| 893 | return $sasoEventtickets_Frontend->executeJSON($a, $data); |
| 894 | } |
| 895 | |
| 896 | public function replacingShortcode($attr=[], $content = null, $tag = '') { |
| 897 | add_filter( $this->_add_filter_prefix.'replaceShortcode', [$this, 'replaceShortcode'], 10, 3 ); |
| 898 | $ret = apply_filters( $this->_add_filter_prefix.'replaceShortcode', $attr, $content, $tag ); |
| 899 | return $ret; |
| 900 | } |
| 901 | |
| 902 | public function setTicketScannerJS() { |
| 903 | wp_enqueue_style("wp-jquery-ui-dialog"); |
| 904 | |
| 905 | $js_url = "jquery.qrcode.min.js?_v=".$this->getPluginVersion(); |
| 906 | wp_enqueue_script( |
| 907 | 'ajax_script2', |
| 908 | plugins_url( "3rd/".$js_url,__FILE__ ), |
| 909 | array('jquery', 'jquery-ui-dialog') |
| 910 | ); |
| 911 | |
| 912 | $js_url = plugin_dir_url(__FILE__)."3rd/html5-qrcode.min.js?_v=".$this->getPluginVersion(); |
| 913 | wp_register_script('html5-qrcode', $js_url, array('jquery', 'jquery-ui-dialog')); |
| 914 | wp_enqueue_script('html5-qrcode'); |
| 915 | |
| 916 | // https://github.com/nimiq/qr-scanner - NEW scanner lib |
| 917 | $js_url = plugin_dir_url(__FILE__)."3rd/qr-scanner-1.4.2/qr-scanner.umd.min.js?_v=".$this->getPluginVersion(); |
| 918 | wp_register_script('qr-scanner', $js_url, array('jquery', 'jquery-ui-dialog')); |
| 919 | wp_enqueue_script('qr-scanner'); |
| 920 | |
| 921 | $js_url = "ticket_scanner.js?_v=".$this->getPluginVersion(); |
| 922 | if (defined('WP_DEBUG')) $js_url .= '&t='.time(); |
| 923 | $js_url = plugins_url( $js_url,__FILE__ ); |
| 924 | wp_register_script('ajax_script_ticket_scanner', $js_url, array('jquery', 'jquery-ui-dialog', 'wp-i18n')); |
| 925 | wp_enqueue_script('ajax_script_ticket_scanner'); |
| 926 | wp_set_script_translations('ajax_script_ticket_scanner', 'event-tickets-with-ticket-scanner', __DIR__.'/languages'); |
| 927 | |
| 928 | $ticketScannerDontRememberCamChoice = $this->getOptions()->isOptionCheckboxActive("ticketScannerDontRememberCamChoice") ? true : false; |
| 929 | |
| 930 | $vars = [ |
| 931 | 'root' => esc_url_raw( rest_url() ), |
| 932 | '_plugin_home_url' =>plugins_url( "",__FILE__ ), |
| 933 | '_action' => $this->_prefix.'_executeAdminSettings', |
| 934 | '_isPremium'=>$this->isPremium(), |
| 935 | '_isUserLoggedin'=>is_user_logged_in(), |
| 936 | '_userId'=>get_current_user_id(), |
| 937 | '_restPrefixUrl'=>SASO_EVENTTICKETS::getRESTPrefixURL(), |
| 938 | '_siteUrl'=>get_site_url(), |
| 939 | '_params'=>["auth"=>$this->getAuthtokenHandler()::$authtoken_param], |
| 940 | //'url' => admin_url( 'admin-ajax.php' ), // not used for now in ticketscanner.js |
| 941 | 'url' => rest_get_server(), // not used for now in ticketscanner.js |
| 942 | 'nonce' => wp_create_nonce( 'wp_rest' ), |
| 943 | //'nonce' => wp_create_nonce( $this->_js_nonce ), |
| 944 | 'ajaxActionPrefix' => $this->_prefix, |
| 945 | 'wcTicketCompatibilityModeRestURL' => $this->getOptions()->getOptionValue('wcTicketCompatibilityModeRestURL', ''), |
| 946 | 'IS_PRETTY_PERMALINK_ACTIVATED' => get_option('permalink_structure') ? true :false, |
| 947 | 'ticketScannerDontRememberCamChoice' => $ticketScannerDontRememberCamChoice, |
| 948 | 'ticketScannerStartCamWithoutButtonClicked' => $this->getOptions()->isOptionCheckboxActive('ticketScannerStartCamWithoutButtonClicked'), |
| 949 | 'ticketScannerDontShowOptionControls' => $this->getOptions()->isOptionCheckboxActive('ticketScannerDontShowOptionControls'), |
| 950 | 'ticketScannerScanAndRedeemImmediately' => $this->getOptions()->isOptionCheckboxActive('ticketScannerScanAndRedeemImmediately'), |
| 951 | 'ticketScannerHideTicketInformation' => $this->getOptions()->isOptionCheckboxActive('ticketScannerHideTicketInformation'), |
| 952 | 'ticketScannerHideTicketInformationShowShortDesc' => $this->getOptions()->isOptionCheckboxActive('ticketScannerHideTicketInformationShowShortDesc'), |
| 953 | 'ticketScannerDontShowBtnPDF' => $this->getOptions()->isOptionCheckboxActive('ticketScannerDontShowBtnPDF'), |
| 954 | 'ticketScannerDontShowBtnBadge' => $this->getOptions()->isOptionCheckboxActive('ticketScannerDontShowBtnBadge'), |
| 955 | 'ticketScannerDisplayTimes' => $this->getOptions()->isOptionCheckboxActive('ticketScannerDisplayTimes') |
| 956 | ]; |
| 957 | $vars = apply_filters( $this->_add_filter_prefix.'main_setTicketScannerJS', $vars ); |
| 958 | wp_localize_script( |
| 959 | 'ajax_script_ticket_scanner', |
| 960 | 'Ajax_'.$this->_prefix, // name der injected variable |
| 961 | $vars |
| 962 | ); |
| 963 | |
| 964 | do_action( $this->_do_action_prefix.'main_setTicketScannerJS', $js_url ); |
| 965 | } |
| 966 | |
| 967 | public function replacingShortcodeTicketScanner($attr=[], $content = null, $tag = '') { |
| 968 | $this->setTicketScannerJS(); |
| 969 | return ' |
| 970 | <center> |
| 971 | <div style="width:90%;max-width:1024px;">'.$this->getTicketHandler()->getTicketScannerHTMLBoilerplate().' |
| 972 | </div> |
| 973 | </center> |
| 974 | '; |
| 975 | } |
| 976 | |
| 977 | /** |
| 978 | * Shortcode to display ticket detail view on any page |
| 979 | * Usage: [sasoEventTicketsValidator_ticket_detail] with ?ticket=CODE in URL |
| 980 | * Or: [sasoEventTicketsValidator_ticket_detail code="TICKET-CODE"] |
| 981 | */ |
| 982 | public function replacingShortcodeTicketDetail($attr = [], $content = null, $tag = ''): string { |
| 983 | $code = ''; |
| 984 | if (!empty($attr['code'])) { |
| 985 | $code = sanitize_text_field($attr['code']); |
| 986 | } elseif (isset($_GET['ticket'])) { |
| 987 | $code = sanitize_text_field($_GET['ticket']); |
| 988 | } |
| 989 | |
| 990 | if (empty($code)) { |
| 991 | return '<p>' . esc_html__('No ticket code provided. Use ?ticket=YOUR-CODE in the URL.', 'event-tickets-with-ticket-scanner') . '</p>'; |
| 992 | } |
| 993 | |
| 994 | // Build a fake request URI for the ticket |
| 995 | $ticketPath = $this->getCore()->getTicketURLPath(true); |
| 996 | $fakeUri = $ticketPath . $code; |
| 997 | |
| 998 | include_once plugin_dir_path(__FILE__) . "sasoEventtickets_Ticket.php"; |
| 999 | $ticketInstance = sasoEventtickets_Ticket::Instance($fakeUri); |
| 1000 | |
| 1001 | return $ticketInstance->renderTicketDetailForShortcode(); |
| 1002 | } |
| 1003 | |
| 1004 | public function getCodesTextAsShortList($codes) { |
| 1005 | $ret = ""; |
| 1006 | if (count($codes) > 0) { |
| 1007 | $ret = '<table>'; |
| 1008 | $wcTicketUserProfileDisplayTicketDetailURL = $this->getOptions()->isOptionCheckboxActive("wcTicketUserProfileDisplayTicketDetailURL"); |
| 1009 | $wcTicketUserProfileDisplayRedeemAmount = $this->getOptions()->isOptionCheckboxActive("wcTicketUserProfileDisplayRedeemAmount"); |
| 1010 | |
| 1011 | $label_expired = $this->getOptions()->getOptionValue('wcTicketTransTicketExpired', 'EXPIRED'); |
| 1012 | $label_stolen = $this->getOptions()->getOptionValue('wcTicketTransTicketIsStolen', 'REPORTED AS STOLEN'); |
| 1013 | $label_notvalid = $this->getOptions()->getOptionValue('wcTicketTransTicketNotValid', 'DISABLED'); |
| 1014 | |
| 1015 | $myCodes = []; |
| 1016 | foreach($codes as $idx => $codeObj) { |
| 1017 | $metaObj = $this->getCore()->encodeMetaValuesAndFillObject($codeObj['meta'], $codeObj); |
| 1018 | |
| 1019 | $_c = '<tr><td style="text-align:right;">'.($idx + 1).'.</td><td>'.$codeObj['code_display'].'</td><td>'; |
| 1020 | if ($codeObj['aktiv'] == 1) { |
| 1021 | if ($this->getCore()->checkCodeExpired($codeObj)) { |
| 1022 | $_c .= $label_expired; |
| 1023 | } |
| 1024 | } else if ($codeObj['aktiv'] == 0) { |
| 1025 | $_c .= $label_notvalid; |
| 1026 | } else if ($codeObj['aktiv'] == 2) { |
| 1027 | $_c .= $label_stolen; |
| 1028 | } |
| 1029 | $_c .= '</td>'; |
| 1030 | |
| 1031 | if ($wcTicketUserProfileDisplayTicketDetailURL) { |
| 1032 | $_c .= "<td>"; |
| 1033 | $url = $this->getCore()->getTicketURL($codeObj, $metaObj); |
| 1034 | if (!empty($url)) { |
| 1035 | $_c .= '<a href="'.$url.'" target="_blank">Ticket Details</a>'; |
| 1036 | } |
| 1037 | $_c .= "</td>"; |
| 1038 | } |
| 1039 | if ($wcTicketUserProfileDisplayRedeemAmount && function_exists("wc_get_product")) { |
| 1040 | $_c .= "<td>"; |
| 1041 | $text_redeem_amount = $this->getTicketHandler()->getRedeemAmountText($codeObj, $metaObj, false); |
| 1042 | if (!empty($text_redeem_amount)) { |
| 1043 | $_c .= $text_redeem_amount; |
| 1044 | } |
| 1045 | $_c .= "<td>"; |
| 1046 | } |
| 1047 | $_c .= "</tr>"; |
| 1048 | $myCodes[] = $_c; |
| 1049 | } |
| 1050 | $ret .= implode("", $myCodes); |
| 1051 | $ret .= "</table>"; |
| 1052 | } |
| 1053 | $ret = apply_filters( $this->_add_filter_prefix.'main_getCodesTextAsShortList', $ret, $codes ); |
| 1054 | return $ret; |
| 1055 | } |
| 1056 | |
| 1057 | public function getMyCodeText($user_id, $attr=[], $content = null, $tag = '', $codes = null) { |
| 1058 | $ret = ''; |
| 1059 | // check ob eingeloggt |
| 1060 | $pre_text = $this->getOptions()->getOptionValue('userDisplayCodePrefix', ''); |
| 1061 | if (!empty($pre_text)) $pre_text .= " "; |
| 1062 | |
| 1063 | // If codes are provided (e.g., from order_id), use them; otherwise fetch by user_id |
| 1064 | if ($codes === null && $user_id > 0) { |
| 1065 | $codes = $this->getCore()->getCodesByRegUserId($user_id); |
| 1066 | } |
| 1067 | |
| 1068 | if ($codes !== null && count($codes) > 0) { |
| 1069 | $ret .= "<b>".$pre_text."</b><br>"; |
| 1070 | $ret .= $this->getCodesTextAsShortList($codes); |
| 1071 | |
| 1072 | // Download All as PDF button |
| 1073 | $show_download_btn = isset($attr['download_all_pdf']) && |
| 1074 | in_array(strtolower($attr['download_all_pdf']), ['true', '1', 'yes'], true); |
| 1075 | |
| 1076 | if ($show_download_btn && count($codes) > 0) { |
| 1077 | $max_tickets = isset($attr['download_all_pdf_max']) ? intval($attr['download_all_pdf_max']) : 100; |
| 1078 | $btn_label = isset($attr['download_all_pdf_label']) ? |
| 1079 | sanitize_text_field($attr['download_all_pdf_label']) : |
| 1080 | __('Download All Tickets as PDF', 'event-tickets-with-ticket-scanner'); |
| 1081 | |
| 1082 | $ticket_count = count($codes); |
| 1083 | if ($ticket_count > $max_tickets) { |
| 1084 | $ret .= '<p><em>' . sprintf( |
| 1085 | /* translators: %d: maximum number of tickets */ |
| 1086 | esc_html__('Too many tickets (%1$d). Maximum %2$d tickets can be downloaded at once.', 'event-tickets-with-ticket-scanner'), |
| 1087 | $ticket_count, |
| 1088 | $max_tickets |
| 1089 | ) . '</em></p>'; |
| 1090 | } else { |
| 1091 | // Generate secure download URL |
| 1092 | $nonce = wp_create_nonce('download_my_codes_pdf_' . $user_id); |
| 1093 | $download_url = admin_url('admin-ajax.php') . '?' . http_build_query([ |
| 1094 | 'action' => $this->_prefix . '_downloadMyCodesAsPDF', |
| 1095 | 'nonce' => $nonce |
| 1096 | ]); |
| 1097 | $ret .= '<p style="margin-top:10px;"><a href="' . esc_url($download_url) . '" class="button" target="_blank">' . |
| 1098 | esc_html($btn_label) . ' (' . $ticket_count . ')</a></p>'; |
| 1099 | } |
| 1100 | } |
| 1101 | } |
| 1102 | if (empty($ret) && $this->getOptions()->isOptionCheckboxActive('userDisplayCodePrefixAlways')) { |
| 1103 | $ret .= $pre_text; |
| 1104 | } |
| 1105 | $ret = apply_filters( $this->_add_filter_prefix.'main_getMyCodeText', $ret, $user_id, $attr, $content, $tag); |
| 1106 | return $ret; |
| 1107 | } |
| 1108 | |
| 1109 | /** |
| 1110 | * AJAX handler: Download all user's tickets as one PDF |
| 1111 | * Used by shortcode [sasoEventTicketsValidator_code download_all_pdf="true"] |
| 1112 | */ |
| 1113 | public function downloadMyCodesAsPDF(): void { |
| 1114 | $user_id = get_current_user_id(); |
| 1115 | |
| 1116 | // Must be logged in |
| 1117 | if ($user_id <= 0) { |
| 1118 | wp_die(esc_html__('You must be logged in to download tickets.', 'event-tickets-with-ticket-scanner'), 403); |
| 1119 | } |
| 1120 | |
| 1121 | // Verify nonce |
| 1122 | $nonce = isset($_GET['nonce']) ? sanitize_text_field($_GET['nonce']) : ''; |
| 1123 | if (!wp_verify_nonce($nonce, 'download_my_codes_pdf_' . $user_id)) { |
| 1124 | wp_die(esc_html__('Security check failed. Please refresh the page and try again.', 'event-tickets-with-ticket-scanner'), 403); |
| 1125 | } |
| 1126 | |
| 1127 | // Get user's codes |
| 1128 | $codes = $this->getCore()->getCodesByRegUserId($user_id); |
| 1129 | |
| 1130 | if (empty($codes)) { |
| 1131 | wp_die(esc_html__('No tickets found.', 'event-tickets-with-ticket-scanner'), 404); |
| 1132 | } |
| 1133 | |
| 1134 | // Limit to 100 tickets |
| 1135 | $max_tickets = 100; |
| 1136 | if (count($codes) > $max_tickets) { |
| 1137 | wp_die( |
| 1138 | sprintf( |
| 1139 | /* translators: %d: maximum number of tickets */ |
| 1140 | esc_html__('Too many tickets. Maximum %d tickets can be downloaded at once.', 'event-tickets-with-ticket-scanner'), |
| 1141 | $max_tickets |
| 1142 | ), |
| 1143 | 400 |
| 1144 | ); |
| 1145 | } |
| 1146 | |
| 1147 | // Extract code strings |
| 1148 | $code_strings = array_map(function($codeObj) { |
| 1149 | return $codeObj['code']; |
| 1150 | }, $codes); |
| 1151 | |
| 1152 | // Generate merged PDF |
| 1153 | $filename = 'my_tickets_' . wp_date('Ymd_Hi') . '.pdf'; |
| 1154 | |
| 1155 | try { |
| 1156 | $this->getTicketHandler()->generateOnePDFForCodes($code_strings, $filename, 'I'); |
| 1157 | } catch (Exception $e) { |
| 1158 | $this->getAdmin()->logErrorToDB($e, null, 'downloadMyCodesAsPDF'); |
| 1159 | wp_die(esc_html__('Error generating PDF. Please try again later.', 'event-tickets-with-ticket-scanner'), 500); |
| 1160 | } |
| 1161 | |
| 1162 | exit; |
| 1163 | } |
| 1164 | |
| 1165 | public function getMyCodeFormatted($user_id, $attr=[], $content = null, $tag = '', $codes = null) { |
| 1166 | $format = "json"; |
| 1167 | if (isset($attr["format"])) { |
| 1168 | $format = strtolower(trim(sanitize_key($attr["format"]))); |
| 1169 | } |
| 1170 | $display = ["codes"]; |
| 1171 | if (isset($attr["display"])) { |
| 1172 | |
| 1173 | $_d = trim(sanitize_text_field($attr["display"])); |
| 1174 | $_da = explode(",", $_d); |
| 1175 | if (count($_da) > 0) { |
| 1176 | $display = []; |
| 1177 | } |
| 1178 | foreach ($_da as $item) { |
| 1179 | $item = trim($item); |
| 1180 | $display[] = $item; |
| 1181 | } |
| 1182 | } |
| 1183 | |
| 1184 | $output = []; |
| 1185 | //codes,validation,user,used,confirmedCount,woocommerce,wc_rp,wc_ticket |
| 1186 | // If codes are provided (e.g., from order_id), use them; otherwise fetch by user_id |
| 1187 | if ($codes === null) { |
| 1188 | $codes = $this->getCore()->getCodesByRegUserId($user_id); |
| 1189 | } |
| 1190 | $metas = []; |
| 1191 | foreach($codes as $codeObj) { |
| 1192 | $metas[$codeObj["code"]] = $this->getCore()->encodeMetaValuesAndFillObject($codeObj['meta'], $codeObj); |
| 1193 | } |
| 1194 | foreach ($display as $item) { |
| 1195 | $output[$item] = []; |
| 1196 | if ($item == "codes") { |
| 1197 | foreach($codes as $codeObj) { |
| 1198 | if (isset($codeObj["meta"])) { |
| 1199 | unset($codeObj["meta"]); |
| 1200 | } |
| 1201 | $output[$item][] = $codeObj; |
| 1202 | } |
| 1203 | } elseif($item == "confirmedCount") { |
| 1204 | foreach($metas as $key => $meta) { |
| 1205 | $output[$item][] = array_merge(["value"=>$meta[$item]], ["code"=>$key]); |
| 1206 | } |
| 1207 | } else { |
| 1208 | foreach($metas as $key => $m) { |
| 1209 | if (is_array($m) && isset($m[$item])) { |
| 1210 | $meta = $m[$item]; |
| 1211 | if (isset($meta["stats_redeemed"])) { |
| 1212 | unset($meta["stats_redeemed"]); |
| 1213 | } |
| 1214 | if (isset($meta["set_by_admin"])) { |
| 1215 | unset($meta["set_by_admin"]); |
| 1216 | } |
| 1217 | if (isset($meta["redeemed_by_admin"])) { |
| 1218 | unset($meta["redeemed_by_admin"]); |
| 1219 | } |
| 1220 | $output[$item][] = array_merge($meta, ["code"=>$key]); |
| 1221 | } |
| 1222 | } |
| 1223 | } |
| 1224 | } |
| 1225 | |
| 1226 | switch($format) { |
| 1227 | case "json": |
| 1228 | default: |
| 1229 | $ret = $this->getCore()->json_encode_with_error_handling($output); |
| 1230 | } |
| 1231 | $ret = apply_filters( $this->_add_filter_prefix.'main_getMyCodeFormatted', $ret, $user_id, $attr, $content, $tag, $output); |
| 1232 | return $ret; |
| 1233 | } |
| 1234 | |
| 1235 | public function replacingShortcodeMyCode($attr=[], $content = null, $tag = '') { |
| 1236 | $user_id = get_current_user_id(); |
| 1237 | $codes = null; // Will be set if order_id is used |
| 1238 | |
| 1239 | // Check if order_id parameter is provided |
| 1240 | if (isset($attr['order_id']) && !empty($attr['order_id'])) { |
| 1241 | $order_id = intval($attr['order_id']); |
| 1242 | if ($order_id > 0) { |
| 1243 | // Security check: can current user access this order? |
| 1244 | if (!$this->canUserAccessOrder($order_id)) { |
| 1245 | return '<p>' . esc_html__('You do not have permission to view tickets for this order.', 'event-tickets-with-ticket-scanner') . '</p>'; |
| 1246 | } |
| 1247 | // Get codes by order_id |
| 1248 | $codes = $this->getCore()->getCodesByOrderId($order_id); |
| 1249 | } |
| 1250 | } |
| 1251 | |
| 1252 | if (count($attr) > 0 && isset($attr["format"])) { |
| 1253 | return $this->getMyCodeFormatted($user_id, $attr, $content, $tag, $codes); |
| 1254 | } else { |
| 1255 | return $this->getMyCodeText($user_id, $attr, $content, $tag, $codes); |
| 1256 | } |
| 1257 | } |
| 1258 | |
| 1259 | /** |
| 1260 | * Check if current user can access a specific order's tickets |
| 1261 | * |
| 1262 | * @param int $order_id WooCommerce order ID |
| 1263 | * @return bool True if user can access, false otherwise |
| 1264 | */ |
| 1265 | private function canUserAccessOrder(int $order_id): bool { |
| 1266 | $order = wc_get_order($order_id); |
| 1267 | if (!$order) { |
| 1268 | return false; |
| 1269 | } |
| 1270 | |
| 1271 | // 1. Admin/Shop-Manager can access all orders |
| 1272 | if (current_user_can('manage_woocommerce')) { |
| 1273 | return true; |
| 1274 | } |
| 1275 | |
| 1276 | $current_user_id = get_current_user_id(); |
| 1277 | |
| 1278 | // 2. Logged-in user owns this order |
| 1279 | if ($current_user_id > 0 && $order->get_user_id() == $current_user_id) { |
| 1280 | return true; |
| 1281 | } |
| 1282 | |
| 1283 | // 3. Valid order key in URL (WooCommerce thank-you page pattern) |
| 1284 | $order_key_from_url = isset($_GET['key']) ? sanitize_text_field($_GET['key']) : ''; |
| 1285 | if (!empty($order_key_from_url) && $order->get_order_key() === $order_key_from_url) { |
| 1286 | return true; |
| 1287 | } |
| 1288 | |
| 1289 | return false; |
| 1290 | } |
| 1291 | |
| 1292 | public function replacingShortcodeFeatureList($attr=[], $content = null, $tag = '') { |
| 1293 | //$features = $this->getAdmin()->getOptions(); |
| 1294 | //$options = $features["options"]; |
| 1295 | $options = $this->getOptions()->getOptions(); |
| 1296 | $features = []; |
| 1297 | $act_heading = ""; |
| 1298 | foreach ($options as $option) { |
| 1299 | if ($option["key"] == "serial") continue; |
| 1300 | if ($option["type"] == "heading") { |
| 1301 | $act_heading = $option["key"]; |
| 1302 | $features[$act_heading] = ["heading"=>$option, "options"=>[]]; |
| 1303 | } else { |
| 1304 | if ($act_heading != "") { |
| 1305 | $features[$act_heading]["options"][] = $option; |
| 1306 | } |
| 1307 | } |
| 1308 | } |
| 1309 | |
| 1310 | $ret = ""; |
| 1311 | uasort($features, function($a, $b) { |
| 1312 | return strnatcasecmp($a["heading"]["label"], $b["heading"]["label"]); |
| 1313 | }); |
| 1314 | foreach ($features as $key => $feature) { |
| 1315 | $ret .= '<h3>'.$feature["heading"]["label"].'</h3>'; |
| 1316 | $video = $feature["heading"]["_doc_video"] != "" ? ' <a href="'.$feature["heading"]["_doc_video"].'" target="_blank"><span class="dashicons dashicons-video-alt3"></span> Introduction video</a>' : ""; |
| 1317 | $ret .= '<p>'.trim($feature["heading"]["desc"].$video).'</p>'; |
| 1318 | if (count($feature["options"]) > 0) { |
| 1319 | $ret .= '<ul>'; |
| 1320 | foreach ($feature["options"] as $option) { |
| 1321 | $label = $option["label"]; |
| 1322 | $desc = $option["desc"]; |
| 1323 | $desc .= $option["_doc_video"] != "" ? ' <a href="'.$option["_doc_video"].'" target="_blank"><span class="dashicons dashicons-video-alt3"></span> Introduction video</a>' : ""; |
| 1324 | $desc = trim($desc); |
| 1325 | if ($desc != "") { |
| 1326 | $desc = '<p>'.$desc.'</p>'; |
| 1327 | } |
| 1328 | $label = '<span class="dashicons dashicons-yes"></span> '.$label; |
| 1329 | $ret .= '<li>'.$label.$desc.'</li>'; |
| 1330 | } |
| 1331 | $ret .= '</ul>'; |
| 1332 | } |
| 1333 | $ret .= '<hr>'; |
| 1334 | } |
| 1335 | |
| 1336 | return $ret; |
| 1337 | } |
| 1338 | |
| 1339 | public function replacingShortcodeEventViews($attr=[], $content = null, $tag = '') { |
| 1340 | // iterate over all woocommerce products and check if they are an event |
| 1341 | $view = "calendar|list"; |
| 1342 | if (isset($attr["view"])) { |
| 1343 | $view = strtolower(trim(sanitize_key($attr["view"]))); |
| 1344 | } |
| 1345 | $months_to_show = 3; |
| 1346 | if (isset($attr["months_to_show"])) { |
| 1347 | $m = intval($attr["months_to_show"]); |
| 1348 | if ($m > 0) $months_to_show = $m; |
| 1349 | } |
| 1350 | |
| 1351 | $month_start = strtotime(wp_date("Y-m-1 00:00:00")); |
| 1352 | //$month_end = strtotime(wp_date("Y-m-t 23:59:59")); |
| 1353 | $month_end = strtotime(wp_date("Y-m-1 23:59:59", strtotime("+".$months_to_show." month", $month_start))); |
| 1354 | |
| 1355 | $products_args = array( |
| 1356 | 'post_type' => 'product', |
| 1357 | 'post_status' => 'publish', |
| 1358 | 'posts_per_page' => -1, // -1 zeigt alle Produkte an |
| 1359 | 'meta_query' => array( |
| 1360 | [ |
| 1361 | 'key' => 'saso_eventtickets_is_ticket', |
| 1362 | 'value' => 'yes', |
| 1363 | 'compare' => '=' |
| 1364 | ] |
| 1365 | ) |
| 1366 | ); |
| 1367 | $posts = get_posts($products_args); // get only ticket products |
| 1368 | |
| 1369 | $list_infos = [ |
| 1370 | 'months_to_show'=>$months_to_show, |
| 1371 | 'month_start'=>$month_start, |
| 1372 | 'month_end'=>$month_end, |
| 1373 | 'view'=>$view |
| 1374 | ]; |
| 1375 | $products_to_show = []; |
| 1376 | // Ergebnisse überprüfen |
| 1377 | foreach ($posts as $post) { |
| 1378 | $product_ids = []; |
| 1379 | $product = wc_get_product( $post->ID ); |
| 1380 | |
| 1381 | // check if event is variant product |
| 1382 | $is_variable = $product->get_type() == "variable"; |
| 1383 | if ($is_variable) { |
| 1384 | // check if event dates are the same for all variants |
| 1385 | $date_is_for_all_variants = get_post_meta( $product_id, 'saso_eventtickets_is_date_for_all_variants', true ) == "yes" ? true : false; |
| 1386 | if ($date_is_for_all_variants == false) { |
| 1387 | // if not add also the variants |
| 1388 | $childs = $product->get_children(); |
| 1389 | foreach ($childs as $child_id) { |
| 1390 | if (get_post_meta($child_id, '_saso_eventtickets_is_not_ticket', true) == "yes") { |
| 1391 | continue; |
| 1392 | } |
| 1393 | $product_ids[] = $child_id; |
| 1394 | } |
| 1395 | } |
| 1396 | } else { |
| 1397 | $product_ids[] = $product->get_id(); |
| 1398 | } |
| 1399 | |
| 1400 | foreach ($product_ids as $product_id) { |
| 1401 | $product = wc_get_product( $product_id ); |
| 1402 | $dates = $this->getTicketHandler()->calcDateStringAllowedRedeemFrom($product_id); |
| 1403 | //if ($dates['ticket_end_date_timestamp'] > $month_start && $dates['ticket_start_date_timestamp'] < $month_end) { |
| 1404 | if ($dates['ticket_end_date_timestamp'] >= $month_start || ($dates['ticket_start_date_timestamp'] >= $month_start && $dates['ticket_start_date_timestamp'] <= $month_end)) { |
| 1405 | // set product to hidden |
| 1406 | $product_data = array( |
| 1407 | 'ID' => $product_id, |
| 1408 | 'dates' => $dates, |
| 1409 | 'event'=> [ |
| 1410 | 'location' => trim(get_post_meta( $product_id, 'saso_eventtickets_event_location', true )), |
| 1411 | 'location_label' => wp_kses_post(trim($this->getAdmin()->getOptionValue("wcTicketTransLocation"))) |
| 1412 | ], |
| 1413 | 'product' => [ |
| 1414 | 'title' => $product->get_name(), |
| 1415 | 'url' => get_permalink($product_id), |
| 1416 | 'price' =>$product->get_price(), |
| 1417 | 'price_html' => $product->get_price_html(), |
| 1418 | 'type' => $product->get_type(), |
| 1419 | ] |
| 1420 | ); |
| 1421 | $products_to_show[] = $product_data; |
| 1422 | } |
| 1423 | } |
| 1424 | } |
| 1425 | |
| 1426 | $divId = "sasoEventTicketsValidator_eventsview"; |
| 1427 | |
| 1428 | // add js for the events |
| 1429 | wp_enqueue_style("wp-jquery-ui-dialog"); |
| 1430 | |
| 1431 | $js_url = "ticket_events.js?_v=".$this->getPluginVersion(); |
| 1432 | if (defined('WP_DEBUG')) $js_url .= '&t='.time(); |
| 1433 | $js_url = plugins_url( $js_url,__FILE__ ); |
| 1434 | wp_register_script('ajax_script_ticket_events', $js_url, array('jquery', 'jquery-ui-dialog', 'wp-i18n')); |
| 1435 | wp_enqueue_script('ajax_script_ticket_events'); |
| 1436 | wp_set_script_translations('ajax_script_ticket_events', 'event-tickets-with-ticket-scanner', __DIR__.'/languages'); |
| 1437 | wp_enqueue_style("ticket_events_css", plugins_url( "",__FILE__ ).'/css/calendar.css', [], true); |
| 1438 | |
| 1439 | // add all events as an array for max 3 months??? or config parameter |
| 1440 | $vars = [ |
| 1441 | 'root' => esc_url_raw( rest_url() ), |
| 1442 | '_plugin_home_url' =>plugins_url( "",__FILE__ ), |
| 1443 | '_action' => $this->_prefix.'_executeFrontendEvents', |
| 1444 | '_isPremium'=>$this->isPremium(), |
| 1445 | '_isUserLoggedin'=>is_user_logged_in(), |
| 1446 | '_userId'=>get_current_user_id(), |
| 1447 | '_premJS'=>$this->isPremium() && method_exists($this->getPremiumFunctions(), "getJSFrontEventFile") ? $this->getPremiumFunctions()->getJSFrontEventFile() : '', |
| 1448 | '_siteUrl'=>get_site_url(), |
| 1449 | 'events' => $products_to_show, |
| 1450 | 'list_infos' => $list_infos, |
| 1451 | 'format_date' => $this->getOptions()->getOptionDateFormat(), |
| 1452 | 'format_time' => $this->getOptions()->getOptionTimeFormat(), |
| 1453 | 'format_datetime' => $this->getOptions()->getOptionDateTimeFormat(), |
| 1454 | 'url' => admin_url( 'admin-ajax.php' ), |
| 1455 | 'nonce' => wp_create_nonce( $this->_js_nonce ), |
| 1456 | 'ajaxActionPrefix' => $this->_prefix, |
| 1457 | 'divId' => $divId |
| 1458 | ]; |
| 1459 | $vars = apply_filters( $this->_add_filter_prefix.'main_setTicketEventJS', $vars ); |
| 1460 | wp_localize_script( |
| 1461 | 'ajax_script_ticket_events', |
| 1462 | 'Ajax_ticket_events_'.$this->_prefix, // name der injected variable |
| 1463 | $vars |
| 1464 | ); |
| 1465 | |
| 1466 | do_action( $this->_do_action_prefix.'main_setTicketEventJS', $js_url ); |
| 1467 | |
| 1468 | $ret = ''; |
| 1469 | if (!isset($attr['divid']) || trim($attr['divid']) == "") { |
| 1470 | $ret .= '<div id="'.$divId.'">'.__('...loading...', 'event-tickets-with-ticket-scanner').'</div>'; |
| 1471 | } |
| 1472 | |
| 1473 | $ret = apply_filters( $this->_add_filter_prefix.'main_replacingShortcodeEventViews', $ret ); |
| 1474 | do_action( $this->_do_action_prefix.'main_replacingShortcodeEventViews', $vars, $ret ); |
| 1475 | |
| 1476 | return $ret; |
| 1477 | } |
| 1478 | |
| 1479 | public function replaceShortcode($attr=[], $content = null, $tag = '') { |
| 1480 | // einbinden das js starter skript |
| 1481 | $js_url = $this->_js_file."?_v=".$this->_js_version; |
| 1482 | if (defined( 'WP_DEBUG')) $js_url .= '&debug=1'; |
| 1483 | $userDivId = !isset($attr['divid']) || trim($attr['divid']) == "" ? '' : trim($attr['divid']); |
| 1484 | |
| 1485 | $attr = array_change_key_case( (array) $attr, CASE_LOWER ); |
| 1486 | |
| 1487 | wp_enqueue_script( |
| 1488 | 'ajax_script_validator', |
| 1489 | plugins_url( $js_url,__FILE__ ), |
| 1490 | array('jquery', 'wp-i18n') |
| 1491 | ); |
| 1492 | wp_set_script_translations('ajax_script_validator', 'event-tickets-with-ticket-scanner', __DIR__.'/languages'); |
| 1493 | |
| 1494 | $vars = array( |
| 1495 | 'shortcode_attr'=>json_encode($attr), |
| 1496 | '_plugin_home_url' =>plugins_url( "",__FILE__ ), |
| 1497 | '_action' => $this->_prefix.'_executeFrontend', |
| 1498 | '_isPremium'=>$this->isPremium(), |
| 1499 | '_isUserLoggedin'=>is_user_logged_in(), |
| 1500 | '_premJS'=>$this->isPremium() && method_exists($this->getPremiumFunctions(), "getJSFrontFile") ? $this->getPremiumFunctions()->getJSFrontFile() : '', |
| 1501 | 'url' => admin_url( 'admin-ajax.php' ), |
| 1502 | 'nonce' => wp_create_nonce( $this->_js_nonce ), |
| 1503 | 'ajaxActionPrefix' => $this->_prefix, |
| 1504 | 'divPrefix' => $userDivId == "" ? $this->_prefix : $userDivId, |
| 1505 | 'divId' => $this->_divId, |
| 1506 | 'jsFiles' => plugins_url( 'validator.js?_v='.$this->_js_version, __FILE__ ) |
| 1507 | ); |
| 1508 | $vars['_messages'] = [ |
| 1509 | 'msgCheck0'=>$this->getOptions()->getOptionValue('textValidationMessage0'), |
| 1510 | 'msgCheck1'=>$this->getOptions()->getOptionValue('textValidationMessage1'), |
| 1511 | 'msgCheck2'=>$this->getOptions()->getOptionValue('textValidationMessage2'), |
| 1512 | 'msgCheck3'=>$this->getOptions()->getOptionValue('textValidationMessage3'), |
| 1513 | 'msgCheck4'=>$this->getOptions()->getOptionValue('textValidationMessage4'), |
| 1514 | 'msgCheck5'=>$this->getOptions()->getOptionValue('textValidationMessage5'), |
| 1515 | 'msgCheck6'=>$this->getOptions()->getOptionValue('textValidationMessage6') |
| 1516 | ]; |
| 1517 | $vars = apply_filters( $this->_add_filter_prefix.'main_replaceShortcode', $vars ); |
| 1518 | |
| 1519 | if ($this->isPremium() && method_exists($this->getPremiumFunctions(), "addJSFrontFile")) $this->getPremiumFunctions()->addJSFrontFile(); |
| 1520 | |
| 1521 | wp_localize_script( |
| 1522 | 'ajax_script_validator', |
| 1523 | 'Ajax_'.$this->_prefix, // name of the injected variable |
| 1524 | $vars |
| 1525 | ); |
| 1526 | $ret = ''; |
| 1527 | if (!isset($attr['divid']) || trim($attr['divid']) == "") { |
| 1528 | $ret .= '<div id="'.$this->_divId.'">'.__('...loading...', 'event-tickets-with-ticket-scanner').'</div>'; |
| 1529 | } |
| 1530 | |
| 1531 | $ret = apply_filters( $this->_add_filter_prefix.'main_replaceShortcode_2', $ret ); |
| 1532 | do_action( $this->_do_action_prefix.'main_replaceShortcode', $vars, $ret ); |
| 1533 | |
| 1534 | return $ret; |
| 1535 | } |
| 1536 | |
| 1537 | /** |
| 1538 | * Show admin notice when premium subscription is about to expire or has expired |
| 1539 | * |
| 1540 | * - Warning: 14 days before expiration |
| 1541 | * - Error: After expiration (during grace period or after) |
| 1542 | * |
| 1543 | * @return void |
| 1544 | */ |
| 1545 | public function showSubscriptionWarning(): void { |
| 1546 | // Only show for premium users |
| 1547 | if (!$this->isPremium()) { |
| 1548 | return; |
| 1549 | } |
| 1550 | |
| 1551 | // Only show in admin |
| 1552 | if (!is_admin()) { |
| 1553 | return; |
| 1554 | } |
| 1555 | |
| 1556 | // Only show to users who can manage options |
| 1557 | if (!current_user_can('manage_options')) { |
| 1558 | return; |
| 1559 | } |
| 1560 | |
| 1561 | $info = $this->getTicketHandler()->get_expiration(); |
| 1562 | |
| 1563 | // No expiration date or lifetime license - no warning needed |
| 1564 | if (empty($info['timestamp']) || $info['timestamp'] <= 0 || $info['timestamp'] == -1) { |
| 1565 | return; |
| 1566 | } |
| 1567 | |
| 1568 | // Lifetime subscription type - no warning needed |
| 1569 | if (isset($info['subscription_type']) && $info['subscription_type'] === 'lifetime') { |
| 1570 | return; |
| 1571 | } |
| 1572 | |
| 1573 | $days_left = ($info['timestamp'] - time()) / 86400; |
| 1574 | $renewal_url = 'https://vollstart.com/product/event-tickets-with-ticket-scanner/'; |
| 1575 | |
| 1576 | // Warning 14 days before expiration |
| 1577 | if ($days_left <= 14 && $days_left > 0) { |
| 1578 | $date = date_i18n(get_option('date_format'), $info['timestamp']); |
| 1579 | echo '<div class="notice notice-warning is-dismissible"><p>'; |
| 1580 | printf( |
| 1581 | /* translators: %1$s: expiration date, %2$s: renewal URL */ |
| 1582 | esc_html__('Your Event-Tickets Premium subscription expires on %1$s. %2$sRenew now%3$s to keep all features.', 'event-tickets-with-ticket-scanner'), |
| 1583 | '<strong>' . esc_html($date) . '</strong>', |
| 1584 | '<a href="' . esc_url($renewal_url) . '" target="_blank">', |
| 1585 | '</a>' |
| 1586 | ); |
| 1587 | echo '</p></div>'; |
| 1588 | } |
| 1589 | |
| 1590 | // Error after expiration |
| 1591 | if ($days_left <= 0) { |
| 1592 | $grace_days = isset($info['grace_period_days']) ? intval($info['grace_period_days']) : 7; |
| 1593 | $grace_left = $grace_days + $days_left; // days_left is negative |
| 1594 | |
| 1595 | echo '<div class="notice notice-error"><p>'; |
| 1596 | if ($grace_left > 0) { |
| 1597 | printf( |
| 1598 | /* translators: %1$d: days remaining in grace period, %2$s: renewal URL */ |
| 1599 | esc_html__('Your Premium subscription has expired. You have %1$d days remaining before features are disabled. %2$sReactivate now%3$s', 'event-tickets-with-ticket-scanner'), |
| 1600 | ceil($grace_left), |
| 1601 | '<a href="' . esc_url($renewal_url) . '" target="_blank">', |
| 1602 | '</a>' |
| 1603 | ); |
| 1604 | } else { |
| 1605 | printf( |
| 1606 | /* translators: %1$s: renewal URL */ |
| 1607 | esc_html__('Your Premium subscription has expired. Premium features are now limited. %1$sReactivate now%2$s', 'event-tickets-with-ticket-scanner'), |
| 1608 | '<a href="' . esc_url($renewal_url) . '" target="_blank">', |
| 1609 | '</a>' |
| 1610 | ); |
| 1611 | } |
| 1612 | echo '</p></div>'; |
| 1613 | } |
| 1614 | } |
| 1615 | |
| 1616 | /** |
| 1617 | * Show admin notice when premium plugin version is outdated |
| 1618 | * |
| 1619 | * Encourages users with old premium versions to upgrade |
| 1620 | * |
| 1621 | * @return void |
| 1622 | */ |
| 1623 | public function showOutdatedPremiumWarning(): void { |
| 1624 | // Only show if premium plugin is active |
| 1625 | if (!defined('SASO_EVENTTICKETS_PREMIUM_PLUGIN_VERSION')) { |
| 1626 | return; |
| 1627 | } |
| 1628 | |
| 1629 | // Only show in admin |
| 1630 | if (!is_admin()) { |
| 1631 | return; |
| 1632 | } |
| 1633 | |
| 1634 | // Only show to users who can manage options |
| 1635 | if (!current_user_can('manage_options')) { |
| 1636 | return; |
| 1637 | } |
| 1638 | |
| 1639 | // Only show on our plugin pages |
| 1640 | $screen = get_current_screen(); |
| 1641 | if ($screen === null || strpos($screen->id, 'saso-event-tickets') === false) { |
| 1642 | return; |
| 1643 | } |
| 1644 | |
| 1645 | // Minimum recommended premium version |
| 1646 | $min_premium_version = '1.6.0'; |
| 1647 | |
| 1648 | if (version_compare(SASO_EVENTTICKETS_PREMIUM_PLUGIN_VERSION, $min_premium_version, '<')) { |
| 1649 | $upgrade_url = 'https://vollstart.com/product/event-tickets-with-ticket-scanner/'; |
| 1650 | echo '<div class="notice notice-warning is-dismissible"><p>'; |
| 1651 | printf( |
| 1652 | /* translators: %1$s: current version, %2$s: recommended version, %3$s: upgrade URL */ |
| 1653 | esc_html__('Your Event-Tickets Premium plugin (v%1$s) is outdated. Version %2$s+ includes new features and improvements. %3$sUpgrade now%4$s', 'event-tickets-with-ticket-scanner'), |
| 1654 | esc_html(SASO_EVENTTICKETS_PREMIUM_PLUGIN_VERSION), |
| 1655 | esc_html($min_premium_version), |
| 1656 | '<a href="' . esc_url($upgrade_url) . '" target="_blank">', |
| 1657 | '</a>' |
| 1658 | ); |
| 1659 | echo '</p></div>'; |
| 1660 | } |
| 1661 | } |
| 1662 | } |
| 1663 | $sasoEventtickets = sasoEventtickets::Instance(); |
| 1664 | ?> |
| 1665 |