/** * Academic Pass AJAX flow */ define('VP_ACADEMIC_SUCCESS_PAGE_ID', 155351); add_action('wp_enqueue_scripts', function () { wp_enqueue_script('jquery'); wp_register_script( 'vp-academic-pass', get_template_directory_uri() . '/frontend/js/vp-academic-pass.js', array('jquery'), '1.0.0', true ); wp_localize_script('vp-academic-pass', 'vpAcademicPass', array( 'ajaxUrl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('vp_academic_pass_nonce'), 'pageId' => get_queried_object_id(), )); wp_enqueue_script('vp-academic-pass'); }); function vp_academic_email_content_type() { return 'text/html'; } function vp_academic_get_email_domain($email) { $email = strtolower(trim($email)); $parts = explode('@', $email); return count($parts) === 2 ? $parts[1] : ''; } function vp_academic_ends_with($haystack, $needle) { $haystack = strtolower($haystack); $needle = strtolower($needle); if ($needle === '') { return true; } return substr($haystack, -strlen($needle)) === $needle; } function vp_academic_domain_allowed($email_domain, $allowed_domains_raw) { $email_domain = strtolower(trim($email_domain)); $allowed_domains = preg_split('/\r\n|\r|\n/', (string) $allowed_domains_raw); foreach ($allowed_domains as $allowed_domain) { $allowed_domain = strtolower(trim($allowed_domain)); if (!$allowed_domain) { continue; } // Exact match: fzs.edu.rs if ($email_domain === $allowed_domain) { return true; } // Wildcard match: *.edu.rs if (strpos($allowed_domain, '*.') === 0) { $base_domain = substr($allowed_domain, 2); if ($email_domain === $base_domain || vp_academic_ends_with($email_domain, '.' . $base_domain)) { return true; } } } return false; } function vp_user_has_subscription_product($user_id, $product_id) { if (!function_exists('wcs_get_users_subscriptions')) { return false; } $subscriptions = wcs_get_users_subscriptions($user_id); foreach ($subscriptions as $subscription) { if (!$subscription) { continue; } if (!in_array($subscription->get_status(), array('active', 'on-hold', 'pending'), true)) { continue; } foreach ($subscription->get_items() as $item) { if ((int) $item->get_product_id() === (int) $product_id) { return true; } } } return false; } function vp_academic_create_subscription_for_user($user_id, $email, $product_id) { if (!function_exists('wc_create_order') || !function_exists('wcs_create_subscription')) { return new WP_Error('missing_woocommerce', 'WooCommerce Subscriptions nije dostupan.'); } $product = wc_get_product($product_id); if (!$product) { return new WP_Error('missing_product', 'Pretplata nije pronađena.'); } $user = get_user_by('id', $user_id); $order = wc_create_order(array( 'customer_id' => $user_id, )); if (is_wp_error($order)) { return $order; } $order->add_product($product, 1); $order->set_address(array( 'first_name' => $user && $user->first_name ? $user->first_name : 'Academic', 'last_name' => $user && $user->last_name ? $user->last_name : 'Pass', 'email' => $email, 'phone' => '-', 'address_1' => 'Adresa', 'address_2' => '', 'city' => 'Beograd', 'state' => 'RS', 'postcode' => '11000', 'country' => 'RS', ), 'billing'); $order->calculate_totals(); $order->update_status('completed', 'Academic Pass order created', true); $subscription = wcs_create_subscription(array( 'order_id' => $order->get_id(), 'customer_id' => $user_id, 'status' => 'active', 'billing_period' => WC_Subscriptions_Product::get_period($product), 'billing_interval' => WC_Subscriptions_Product::get_interval($product), )); if (is_wp_error($subscription)) { return $subscription; } $subscription->add_product($product, 1); /** * Uzimamo samo END date sa WooCommerce Subscription proizvoda. * Ne setujemo trial_end i next_payment. */ $start_date = gmdate('Y-m-d H:i:s'); $end_date = WC_Subscriptions_Product::get_expiration_date( $product, $start_date ); if ($end_date) { $subscription->update_dates(array( 'end' => $end_date, )); } $subscription->calculate_totals(); $subscription->save(); return $subscription; } /** * AJAX: submit forme. * Ovde se NE kreira korisnik. * Samo se proverava email, domen i šalje magic link. */ add_action('wp_ajax_vp_academic_send_link', 'vp_academic_send_link'); add_action('wp_ajax_nopriv_vp_academic_send_link', 'vp_academic_send_link'); function vp_academic_send_link() { check_ajax_referer('vp_academic_pass_nonce', 'nonce'); $email = isset($_POST['academic_email']) ? sanitize_email($_POST['academic_email']) : ''; $page_id = isset($_POST['page_id']) ? absint($_POST['page_id']) : 0; if (!is_email($email)) { wp_send_json_error(array( 'message' => 'Unesite ispravnu email adresu.', )); } if (!$page_id) { wp_send_json_error(array( 'message' => 'Stranica nije validna.', )); } $academic_domains_raw = get_field('academic_domains', $page_id); $target_product_id = (int) get_field('academic_subscription', $page_id); if (!$target_product_id) { wp_send_json_error(array( 'message' => 'Pretplata nije podešena.', )); } $email_domain = vp_academic_get_email_domain($email); if (!vp_academic_domain_allowed($email_domain, $academic_domains_raw)) { wp_send_json_error(array( 'message' => 'Uneli ste pogrešan mejl ili vaš akademski domen trenutno nije podržan za automatsku aktivaciju. Pošaljite mejl na pretplata@velikeprice.com ako mislite da je ovo greška.', )); } $existing_user = get_user_by('email', $email); if ($existing_user && vp_user_has_subscription_product($existing_user->ID, $target_product_id)) { wp_send_json_error(array( 'message' => 'Već imate akademski pristup na ovoj adresi. Ukoliko ste zaboravili šifru, otvorite stranicu Moj nalog.', )); } $token = wp_generate_password(48, false, false); $token_hash = hash('sha256', $token); $transient_key = 'vp_academic_token_' . $token_hash; $expires_at = time() + (30 * MINUTE_IN_SECONDS); set_transient($transient_key, array( 'email' => $email, 'product_id' => $target_product_id, 'page_id' => $page_id, 'created' => time(), 'expires_at' => $expires_at, 'activated' => 0, 'user_id' => 0, ), 30 * MINUTE_IN_SECONDS); $activation_url = add_query_arg(array( 'academic_activate' => 1, 'token' => rawurlencode($token), ), get_permalink($page_id)); add_filter('wp_mail_content_type', 'vp_academic_email_content_type'); $subject = 'Velike priče - aktivacija akademskog pristupa'; $body = ' Poštovani,

Kliknite na link ispod kako biste aktivirali svoj akademski pristup:

Aktivirajte akademski pristup

Link važi 30 minuta.

Srdačan pozdrav,
Velike priče '; $mail_sent = wp_mail($email, $subject, $body); remove_filter('wp_mail_content_type', 'vp_academic_email_content_type'); if (!$mail_sent) { delete_transient($transient_key); wp_send_json_error(array( 'message' => 'Email nije poslat. Pokušajte ponovo ili nas kontaktirajte.', )); } wp_send_json_success(array( 'message' => 'Poslali smo vam link za aktivaciju. Proverite inbox.', )); } /** * Magic link aktivacija. * Ovde se kreira korisnik ako ne postoji. * Ako postoji, samo mu se dodaje pretplata. */ add_action('template_redirect', function () { if (empty($_GET['academic_activate']) || empty($_GET['token'])) { return; } $token = sanitize_text_field(wp_unslash($_GET['token'])); $transient_key = 'vp_academic_token_' . hash('sha256', $token); $token_data = get_transient($transient_key); if (!$token_data || empty($token_data['email']) || empty($token_data['product_id']) || empty($token_data['expires_at'])) { global $wp_query; $wp_query->set_404(); status_header(404); nocache_headers(); include get_query_template('404'); exit; } if ((int) $token_data['expires_at'] < time()) { delete_transient($transient_key); global $wp_query; $wp_query->set_404(); status_header(404); nocache_headers(); include get_query_template('404'); exit; } $email = sanitize_email($token_data['email']); $product_id = (int) $token_data['product_id']; /** * Ako je token već aktiviran, pusti ga samo ako može da prikaže success. */ if (!empty($token_data['activated']) && !empty($token_data['user_id'])) { $user = get_user_by('id', (int) $token_data['user_id']); if ($user) { wp_set_current_user($user->ID); wp_set_auth_cookie($user->ID, true); do_action('wp_login', $user->user_login, $user); wp_safe_redirect(add_query_arg(array( 'token' => rawurlencode($token), ), get_permalink(VP_ACADEMIC_SUCCESS_PAGE_ID))); exit; } } $user = get_user_by('email', $email); if ($user && vp_user_has_subscription_product($user->ID, $product_id)) { wp_safe_redirect(add_query_arg(array( 'academic_error' => 'already_exists', ), get_permalink((int) $token_data['page_id']))); exit; } if (!$user) { $random_password = wp_generate_password(24, true, true); $user_id = wp_insert_user(array( 'user_login' => $email, 'user_pass' => $random_password, 'user_email' => $email, 'display_name' => $email, 'user_nicename' => sanitize_title(current(explode('@', $email))), 'role' => 'customer', )); if (is_wp_error($user_id)) { wp_die('Došlo je do greške prilikom kreiranja naloga.'); } $user = get_user_by('id', $user_id); /** * WordPress šalje email korisniku da postavi šifru. * Random password se ne šalje direktno korisniku. */ wp_new_user_notification($user_id, null, 'user'); } $subscription = vp_academic_create_subscription_for_user($user->ID, $email, $product_id); if (is_wp_error($subscription)) { wp_die($subscription->get_error_message()); } $remaining_ttl = max(1, (int) $token_data['expires_at'] - time()); $token_data['activated'] = 1; $token_data['user_id'] = $user->ID; set_transient($transient_key, $token_data, $remaining_ttl); wp_set_current_user($user->ID); wp_set_auth_cookie($user->ID, true); do_action('wp_login', $user->user_login, $user); wp_safe_redirect(add_query_arg(array( 'token' => rawurlencode($token), ), get_permalink(VP_ACADEMIC_SUCCESS_PAGE_ID))); exit; }); /** * AJAX: success strana proverava token. */ add_action('wp_ajax_vp_academic_success_data', 'vp_academic_success_data'); add_action('wp_ajax_nopriv_vp_academic_success_data', 'vp_academic_success_data'); function vp_academic_success_data() { check_ajax_referer('vp_academic_pass_nonce', 'nonce'); $token = isset($_POST['token']) ? sanitize_text_field(wp_unslash($_POST['token'])) : ''; if (!$token) { wp_send_json_error(array( 'message' => 'Token nije validan.', )); } $transient_key = 'vp_academic_token_' . hash('sha256', $token); $token_data = get_transient($transient_key); if (!$token_data || empty($token_data['activated']) || empty($token_data['user_id']) || empty($token_data['email']) || empty($token_data['expires_at'])) { wp_send_json_error(array( 'message' => 'Link nije validan ili je istekao.', )); } if ((int) $token_data['expires_at'] < time()) { delete_transient($transient_key); wp_send_json_error(array( 'message' => 'Link nije validan ili je istekao.', )); } if (!is_user_logged_in() || get_current_user_id() !== (int) $token_data['user_id']) { wp_send_json_error(array( 'message' => 'Nemate pristup ovoj strani.', )); } wp_send_json_success(array( 'email' => sanitize_email($token_data['email']), )); } https://velikeprice.com/politika/zasto-hrvatska-mirise-na-izbore/ 2026-06-08T08:47:50+02:00 Velike price sr 2026-06-08T05:43:11+02:00 Zašto Hrvatska miriše na izbore? https://velikeprice.com/kultura/kako-su-the-strokes-ipak-zavrsili-na-pravoj-strani/ 2026-06-07T18:39:57+02:00 Velike price sr 2026-06-08T05:37:33+02:00 Kako su The Strokes ipak završili na pravoj strani https://velikeprice.com/kultura/hunjadi-serija-madjarska-serbedzija/ 2026-06-07T18:40:31+02:00 Velike price sr 2026-06-08T05:34:21+02:00 Senke nad Dunavom 1456. https://velikeprice.com/sport/kad-je-istok-bio-ispred-zapada/ 2026-06-07T18:22:27+02:00 Velike price sr 2026-06-08T05:17:11+02:00 Kad je Istok bio ispred Zapada https://velikeprice.com/psihologija/za-sta-si-spreman-da-se-zrtvujes-i-da-li-je-to-zaista-tvoje/ 2026-06-08T08:47:54+02:00 Velike price sr 2026-06-08T05:00:34+02:00 Za šta si spreman da se žrtvuješ (i da li je to zaista tvoje) https://velikeprice.com/sport/edin-avdic-in-memoriam-komentator-milos-udvajanje/ 2026-06-07T21:44:25+02:00 Velike price sr 2026-06-07T20:42:16+02:00 Edine, ‘de razumi me ovog puta https://velikeprice.com/sport/pobij-ih-sve-i-vrati-se-sam/ 2026-06-07T18:28:13+02:00 Velike price sr 2026-06-07T08:11:02+02:00 Poslednja priča o Draženu Petroviću https://velikeprice.com/politika/treci-dnevnik-tv-beograd-7-jun-1989/ 2026-06-07T18:26:37+02:00 Velike price sr 2026-06-07T06:00:07+02:00 „Treći dnevnik“ TV Beograd (7. jun 1989) https://velikeprice.com/nauka/sta-rade-bugari-na-antarktiku/ 2026-06-07T18:26:51+02:00 Velike price sr 2026-06-07T05:54:45+02:00 Šta rade Bugari na Antarktiku? https://velikeprice.com/istorijske-lekcije-milana-st-protica/istorijske-lekcije-milana-st-protica-da-li-je-i-ateizam-fundamentalan/ 2026-06-06T23:02:41+02:00 Velike price sr 2026-06-07T05:46:17+02:00 Istorijske lekcije Milana St. Protića: Da li je i ateizam fundamentalan? https://velikeprice.com/kultura/izvodjac-kakav-se-pojavljuje-jednom-u-epohi/ 2026-06-05T15:33:56+02:00 Velike price sr 2026-06-07T05:28:17+02:00 Izvođač kakav se pojavljuje jednom u epohi https://velikeprice.com/drustvo/anatomija-jednog-samoubojstva/ 2026-06-07T13:53:00+02:00 Velike price sr 2026-06-07T05:15:22+02:00 Anatomija jednog samoubojstva https://velikeprice.com/psihologija/kuca-maca-i-beba-zasto-je-dobro-da-deca-odrastaju-uz-zivotinje/ 2026-06-07T18:25:29+02:00 Velike price sr 2026-06-07T05:00:38+02:00 Kuca, maca i beba: Zašto je dobro da deca odrastaju uz životinje https://velikeprice.com/drustvo/reci-brate/ 2026-06-07T00:18:26+02:00 Velike price sr 2026-06-07T00:00:55+02:00 Reci, brate?