/**
* 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?