Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-4917: leyka-ajax.php in leyka/tags/3.30.3/inc – WordPress Plugin Repository

The Leyka plugin for WordPress is vulnerable to Sensitive Information Exposure in versions up to, and including, 3.30.3 via the ‘leyka_ajax_get_env_and_options’ function. This can allow authenticated attackers with subscriber-level permissions or above to extract sensitive data including Sberbank API key and password, PayPal Client Secret, and more keys and passwords.

CVE
#web#google#js#wordpress#php#auth

1<?php if( !defined(‘WPINC’) ) die;2/** Different ajax handler functions */34/** @todo Check if this handler & its request are still in use */5function leyka_ajax_get_campaigns_list() {67 if(empty($_REQUEST[‘nonce’]) || !wp_verify_nonce($_REQUEST[‘nonce’], ‘leyka_get_campaigns_list_nonce’)) {8 die(json_encode([]));9 }1011 $_REQUEST[‘term’] = empty($_REQUEST[‘term’]) ? ‘’ : trim($_REQUEST[‘term’]);1213 $campaigns = leyka_get_campaigns_list([14 ‘posts_per_page’ => 10,15 ‘meta_query’ => [[16 ‘key’ => 'payment_title’, ‘value’ => $_REQUEST[‘term’], ‘compare’ => 'LIKE’, ‘type’ => 'CHAR’,17 ]],18 ], false);1920 $ids_found = [];21 $count = count($campaigns);22 for($i = 0; $i < $count; $i++) {2324 $ids_found[] = $campaigns[$i]->id;25 $campaigns[$i] = [26 ‘value’ => $campaigns[$i]->id,27 ‘label’ => $campaigns[$i]->title,28 ‘payment_title’ => $campaigns[$i]->payment_title,29 ];30 }3132 $campaigns_tmp = leyka_get_campaigns_list([33 ‘s’ => $_REQUEST[‘term’],34 ‘posts_per_page’ => 10,35 ‘post__not_in’ => $ids_found,36 ], false);3738 foreach($campaigns_tmp as $campaign) { // Any criteria search - low priority39 if( !in_array($campaign->id, $ids_found) ) {40 $campaigns[] = [41 ‘value’ => $campaign->id,42 ‘label’ => $campaign->title,43 ‘payment_title’ => $campaign->payment_title,44 ];45 }46 }4748 die(json_encode($campaigns));4950}51add_action('wp_ajax_leyka_get_campaigns_list’, ‘leyka_ajax_get_campaigns_list’);52add_action('wp_ajax_nopriv_leyka_get_campaigns_list’, ‘leyka_ajax_get_campaigns_list’);5354function leyka_recalculate_total_funded_action(){5556 if( !wp_verify_nonce($_GET[‘nonce’], ‘leyka_recalculate_total_funded_amount’) ) {57 wp_die(__('Error: incorrect request parameters’, ‘leyka’));58 }5960 if(empty($_GET[‘campaign_id’])) {61 wp_die(__('Error: campaign ID is missing’, ‘leyka’));62 }6364 $campaign = new Leyka_Campaign(absint($_GET[‘campaign_id’]));65 $campaign->update_total_funded_amount();6667 wp_die($campaign->total_funded);6869}70add_action('wp_ajax_leyka_recalculate_total_funded_amount’, ‘leyka_recalculate_total_funded_action’);71add_action('wp_ajax_nopriv_leyka_recalculate_total_funded_amount’, ‘leyka_recalculate_total_funded_action’);727374function leyka_get_gateway_redirect_data(){7576 leyka()->clear_session_errors(); // Clear all previous submits errors, if there are some7778 $form_errors = Leyka_Payment_Form::is_form_fields_valid();79 if(is_array($form_errors) && count($form_errors) > 0) {8081 $form_errors = reset($form_errors); // Return only the first error in the list8283 /** @var WP_Error $form_errors */84 die(json_encode([‘status’ => 1, ‘message’ => $form_errors->get_error_message(),]));8586 }8788 $pm = leyka_pf_get_payment_method_value();8990 if(empty($_POST[‘without_form_submission’])) { // Normal donation submit procedure9192 $donation_id = leyka()->log_submission();9394 if( !is_wp_error($donation_id) ) {9596 leyka_remember_donation_data([‘donation_id’ => $donation_id,]);9798 do_action(99 'leyka_payment_form_submission-'.$pm[‘gateway_id’],100 $pm[‘gateway_id’],101 implode('-', array_slice($pm, 1)),102 $donation_id,103 $_POST104 );105106 }107108 $payment_vars = [109 ‘status’ => 0,110 ‘payment_url’ => apply_filters('leyka_submission_redirect_url-'.$pm[‘gateway_id’], '’, $pm[‘payment_method_id’]),111 ‘submission_redirect_type’ => apply_filters(112 'leyka_submission_redirect_type-'.$pm[‘gateway_id’],113 'auto’, $pm[‘payment_method_id’], $donation_id114 ),115 ];116117 if(is_wp_error($donation_id)) {118119 $payment_vars[‘errors’] = $donation_id;120 $payment_vars[‘message’] = $donation_id->get_error_message();121 $payment_vars[‘status’] = 1;122123 } else if(leyka()->payment_form_has_errors()) {124125 $error = leyka()->get_payment_form_errors();126 $error = reset($error);127128 $payment_vars[‘errors’] = $error;129 $payment_vars[‘message’] = $error->get_error_message();130 $payment_vars[‘status’] = 1;131132 } else { // Donation created successfully133134 $payment_vars[‘donation_id’] = $donation_id;135 $donation = Leyka_Donations::get_instance()->get($donation_id);136137 if( // Direct integration with GUA - checkout event:138 leyka_options()->opt(‘use_gtm_ua_integration’) === 'enchanced_ua_only’139 && leyka_options()->opt(‘gtm_ua_tracking_id’)140 ) {141142 require_once LEYKA_PLUGIN_DIR.’vendor/autoload.php’;143144 $analytics = new TheIconic\Tracking\GoogleAnalytics\Analytics(true);145 $analytics // Main params:146 ->setProtocolVersion(‘1’)147 ->setTrackingId(leyka_options()->opt(‘gtm_ua_tracking_id’))148 ->setClientId($donation->ga_client_id ? $donation->ga_client_id : leyka_gua_get_client_id())149 ->setDocumentLocationUrl(get_permalink($donation->campaign_id))150 // Transaction params:151 ->setTransactionId($donation_id)152 ->setAffiliation(get_bloginfo(‘name’))153 ->setRevenue($donation->amount)154 ->addProduct([ // Donation params155 ‘name’ => $donation->payment_title,156 ‘price’ => $donation->amount,157 ‘brand’ => get_bloginfo(‘name’), // Mb, it won’t work with it158 ‘category’ => $donation->type_label, // Mb, it won’t work with it159 ‘quantity’ => 1,160 ])161 ->setProductActionToCheckout()162 ->setCheckoutStep(1)163 ->setCheckoutStepOption($donation->pm_label)164 ->setEventCategory(‘Checkout’)165 ->setEventAction(‘Checkout’) // 'Purchase’166 ->sendEvent();167168 } // Direct integration with GUA - checkout event END169170 }171172 $payment_vars = array_merge(173 apply_filters('leyka_submission_form_data-'.$pm[‘gateway_id’], $_POST, $pm[‘payment_method_id’], $donation_id),174 $payment_vars175 );176177 } else { // Get payment vars without donation submit178 $payment_vars = array_merge(179 apply_filters('leyka_submission_form_data-'.$pm[‘gateway_id’], $_POST, $pm[‘payment_method_id’], false),180 [181 ‘status’ => 0,182 ‘payment_url’ => apply_filters('leyka_submission_redirect_url-'.$pm[‘gateway_id’], '’, $pm[‘payment_method_id’]),183 ]184 );185 }186187 die(json_encode($payment_vars));188189}190add_action('wp_ajax_leyka_ajax_get_gateway_redirect_data’, ‘leyka_get_gateway_redirect_data’);191add_action('wp_ajax_nopriv_leyka_ajax_get_gateway_redirect_data’, ‘leyka_get_gateway_redirect_data’);192193function leyka_process_success_form(){194195 if(196 leyka_options()->opt(‘check_nonce_on_public_donor_actions’)197 && (empty($_POST[‘_wpnonce’]) || !wp_verify_nonce($_POST[‘_wpnonce’], ‘leyka_donor_subscription’))198 ) {199 die(json_encode([200 ‘status’ => 1,201 ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),202 ]));203 } else if(empty($_POST[‘leyka_donation_id’])) {204 die(json_encode([‘status’ => 1, ‘message’ => __('No donation ID found in the submitted data’, ‘leyka’),]));205 }206207 $donation = Leyka_Donations::get_instance()->get($_POST[‘leyka_donation_id’]);208 if( !$donation ) {209 die(json_encode([‘status’ => 1, ‘message’ => __('Wrong donation ID in the submitted data’, ‘leyka’),]));210 }211212 if(isset($_POST[‘leyka_donor_name’]) && leyka_validate_donor_name($_POST[‘leyka_donor_name’])) {213 $donation->donor_name = $_POST[‘leyka_donor_name’];214 }215216 if(isset($_POST[‘leyka_donor_email’]) && leyka_validate_email($_POST[‘leyka_donor_email’])) {217218 $donation->donor_email = $donation->donor_email ? $donation->donor_email : $_POST[‘leyka_donor_email’];219 $donation->donor_subscription_email = $_POST[‘leyka_donor_email’];220 $donation->donor_subscribed = $donation->campaign_id;221222 }223224 leyka_remembered_data('donation_id’, false, true); // Delete the donor data cookie225226 die(json_encode([‘status’ => 0,]));227228}229add_action('wp_ajax_leyka_donor_subscription’, ‘leyka_process_success_form’);230add_action('wp_ajax_nopriv_leyka_donor_subscription’, ‘leyka_process_success_form’);231232function leyka_set_campaign_photo(){233234 if(empty($_POST[‘nonce’]) || !wp_verify_nonce($_POST[‘nonce’], ‘set-campaign-photo’)) {235 die(json_encode([236 ‘status’ => 'error’,237 ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),238 ]));239 } else if(empty($_POST[‘campaign_id’])) {240 die(json_encode([241 ‘status’ => 'error’,242 ‘message’ => __('Error: campaign ID is missing’, ‘leyka’),243 ]));244 }245246 $attachment_id = absint($_POST[‘attachment_id’]);247 $campaign_id = absint($_POST[‘campaign_id’]);248249 update_post_meta($campaign_id, '_thumbnail_id’, $attachment_id);250 sleep(1);251252 die(json_encode([‘status’ => 'ok’, ‘post’ => $_POST,]));253254}255add_action('wp_ajax_leyka_set_campaign_photo’, ‘leyka_set_campaign_photo’);256257function leyka_set_campaign_attachment(){258259 $_POST[‘campaign_id’] = empty($_POST[‘campaign_id’]) ? false : absint($_POST[‘campaign_id’]);260 $_POST[‘attachment_id’] = empty($_POST[‘attachment_id’]) ? false : absint($_POST[‘attachment_id’]);261262 if(empty($_POST[‘nonce’]) || !wp_verify_nonce($_POST[‘nonce’], ‘set-campaign-attachment’)) {263 die(json_encode([‘status’ => 'error’, ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),]));264 } else if(empty($_POST[‘campaign_id’])) {265 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: campaign ID is missing’, ‘leyka’),]));266 } else if(empty($_POST[‘field_name’])) {267 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: field name is missing’, ‘leyka’),]));268 }269270 update_post_meta($_POST[‘campaign_id’], esc_attr($_POST[‘field_name’]), $_POST[‘attachment_id’]);271 sleep(1);272273 die(json_encode([274 ‘status’ => 'ok’,275 ‘post’ => $_POST,276 ‘img_url’ => wp_get_attachment_image_url(absint($_POST[‘attachment_id’]), ‘thumbnail’),277 ]));278279}280add_action('wp_ajax_leyka_set_campaign_attachment’, ‘leyka_set_campaign_attachment’);281282function leyka_set_campaign_template(){283284 if(empty($_POST[‘nonce’]) || !wp_verify_nonce($_POST[‘nonce’], ‘set-campaign-template’)) {285 die(json_encode([‘status’ => 'error’, ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),]));286 } else if(empty($_POST[‘campaign_id’])) {287 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: campaign ID is missing’, ‘leyka’),]));288 }289290 update_post_meta(absint($_POST[‘campaign_id’]), 'campaign_template’, $_POST[‘template’]);291292 die(json_encode([‘status’ => 'ok’, ‘post’ => $_POST,]));293294}295add_action('wp_ajax_leyka_set_campaign_template’, ‘leyka_set_campaign_template’);296297function leyka_edit_campaign_slug(){298299 if(empty($_POST[‘nonce’]) || !wp_verify_nonce($_POST[‘nonce’], ‘leyka-edit-campaign-slug’)) {300 die(json_encode([‘status’ => 'error’, ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),]));301 } else if(empty($_POST[‘campaign_id’]) || empty($_POST[‘slug’])) {302 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: the campaign data needed are missing’, ‘leyka’),]));303 }304305 $campaign = get_post($_POST[‘campaign_id’]);306 if( !$campaign || $campaign->post_type !== Leyka_Campaign_Management::$post_type ) {307 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: wrong campaign ID given’, ‘leyka’),]));308 }309310 $_POST[‘slug’] = wp_unique_post_slug(sanitize_title($_POST[‘slug’]), $_POST[‘campaign_id’], $campaign->post_status, $campaign->post_type, null);311312 $res = wp_update_post([313 ‘ID’ => absint($_POST[‘campaign_id’]),314 ‘post_name’ => $_POST[‘slug’],315 ]);316317 if($res) {318 die(json_encode([‘status’ => 'ok’, ‘slug’ => $_POST[‘slug’],]));319 } else {320 die(json_encode([‘status’ => 'error’, ‘message’ => __(“Error: the campaign slug wasn’t updated", ‘leyka’),]));321 }322323}324add_action('wp_ajax_leyka_edit_campaign_slug’, ‘leyka_edit_campaign_slug’);325326function leyka_update_pm_list(){327328 if(empty($_POST[‘nonce’]) || !wp_verify_nonce($_POST[‘nonce’], ‘leyka-update-pm-order’)) {329 die(json_encode([‘status’ => 'error’, ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),]));330 } else if(empty($_POST[‘pm_order’])) {331 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: PM order value is missing’, ‘leyka’),]));332 }333334 leyka_options()->opt('pm_order’, $_POST[‘pm_order’]);335 leyka_options()->opt('pm_available’, explode('&’, str_replace('pm_order[]=’, '’, $_POST[‘pm_order’])));336337 if( !empty($_POST[‘pm_labels’]) && is_array($_POST[‘pm_labels’]) ) {338 foreach($_POST[‘pm_labels’] as $pm_full_id => $pm_label) {339 leyka_options()->opt($pm_full_id, $pm_label);340 }341 }342343 die(json_encode([‘status’ => 'ok’,]));344345}346add_action('wp_ajax_leyka_update_pm_list’, ‘leyka_update_pm_list’);347348function leyka_upload_l10n(){349350 $url = 'https://translate.wordpress.org/projects/wp-plugins/leyka/stable/ru/default/export-translations?format=mo’;351 $file = download_url($url, 60);352353 $res = null;354355 if(is_wp_error($file)) {356 $res = [‘status’ => 'error’, ‘message’ => 'Ошибка! Не удалось скачать файл локализации. '.$file->get_error_message()];357 } else {358359 if( !is_dir(WP_CONTENT_DIR."/languages”) ) {360 $res = [‘status’ => ‘error’, ‘message’ => sprintf(‘Ошибка! Папка локализации не найдена: %s’, WP_CONTENT_DIR.’/languages’)];361 } else if( !is_dir(WP_CONTENT_DIR.’/languages/plugins’) ) {362 $res = [363 ‘status’ => ‘error’,364 ‘message’ => sprintf(‘Ошибка! Папка локализации плагинов не найдена: %s’, WP_CONTENT_DIR.’/languages/plugins’)365 ];366 } else {367368 try {369 if(copy($file, WP_CONTENT_DIR.’/languages/plugins/leyka-ru_RU.mo’)) {370 unlink($file);371 } else {372 $res = [373 ‘status’ => 'error’,374 ‘message’ => sprintf(‘Ошибка! Нет прав для записи в папку %s’, WP_CONTENT_DIR.’/languages/plugins’)375 ];376 }377 } catch(Exception $ex) {378 $res = [‘status’ => 'error’, ‘message’ => 'Ошибка! Не удалось установить файл локализации! '.$ex->getMessage()];379 }380 }381382 }383384 if( !$res ) {385 $res = [‘status’ => 'ok’, ‘message’ => 'Перевод успешно загружен’,];386 }387388 die(json_encode($res));389390}391add_action('wp_ajax_leyka_upload_l10n’, ‘leyka_upload_l10n’);392393function leyka_ajax_get_env_and_options(){394 die(‘<pre>’.format_debug_data(humanaize_debug_data(leyka_get_env_and_options())).’</pre>’);395}396add_action('wp_ajax_leyka_get_env_and_options’, ‘leyka_ajax_get_env_and_options’);397398function leyka_setup_donor_password(){399400 $res = [‘status’ => 'ok’, ‘message’ => __('The password is set. Welcome to your personal account!’, ‘leyka’)];401402 if(403 leyka_options()->opt(‘check_nonce_on_public_donor_actions’)404 && (empty($_POST[‘nonce’]) || !wp_verify_nonce($_POST[‘nonce’], ‘leyka_account_password_setup’))405 ) {406 $res = [407 ‘status’ => 'error’,408 ‘message’ => sprintf(__('Wrong request. Please, <a href="mailto:%s" target="_blank">contact the website tech. support</a> about it.’, ‘leyka’), leyka_get_website_tech_support_email())409 ];410 } else if(411 empty($_POST[‘leyka_donor_pass’])412 || empty($_POST[‘leyka_donor_pass2’])413 || $_POST[‘leyka_donor_pass’] !== $_POST[‘leyka_donor_pass2’]414 || empty($_POST[‘donor_account_email’])415 || !leyka_is_email($_POST[‘donor_account_email’])416 ) {417 $res = [‘status’ => 'error’, ‘message’ => sprintf(__('Wrong request data. Please, <a href="mailto:%s" target="_blank">contact the website tech. support</a> about it.’, ‘leyka’), leyka_get_website_tech_support_email())];418 } else {419420 $donor_account = get_user_by('email’, $_POST[‘donor_account_email’]);421 if( !$donor_account ) {422423 die(json_encode([424 ‘status’ => 'error’,425 ‘message’ => sprintf(__('Wrong request data. Please, <a href="mailto:%s" target="_blank">contact the website tech. support</a> about it.’, ‘leyka’), leyka_get_website_tech_support_email())426 ]));427428 } else if(429 !$donor_account->user_login430 || !is_a(check_password_reset_key(431 (empty($_POST[‘donor_account_password_reset_code’]) ? ‘’ : $_POST[‘donor_account_password_reset_code’]),432 $donor_account->user_login433 ), ‘WP_User’)434 ) {435436 die(json_encode([437 ‘status’ => 'error’,438 ‘message’ => sprintf(__('Wrong request data. Please, <a href="mailto:%s" target="_blank">contact the website tech. support</a> about it.’, ‘leyka’), leyka_get_website_tech_support_email())439 ]));440441 }442443 try {444 $donor = new Leyka_Donor($_POST[‘donor_account_email’]);445 } catch(Exception $e) {446 die(json_encode([‘status’ => 'error’, ‘message’ => __('Wrong Donor ID given’, ‘leyka’)]));447 }448449 $donor->password = $_POST[‘leyka_donor_pass’];450 $donor->account_activation_code = false;451452 if( !empty($_POST[‘auto-login’]) ) { // Password initial setup (account activation)453454 $donor_logged_in = $donor->login($_POST[‘leyka_donor_pass’], true);455456 if(is_wp_error($donor_logged_in)) { /** @var $donor_logged_in WP_Error */457 $res = [‘status’ => 'error’, ‘message’ => strip_tags($donor_logged_in->get_error_message()),];458 }459460 } else { // Password resetting461 $res = [‘status’ => 'ok’, ‘message’ => sprintf(__('The password is changed. You may <a href="%s">log in</a>’, ‘leyka’), home_url(‘/donor-account/login/’))];462 }463464 }465466 die(json_encode($res));467468}469add_action('wp_ajax_leyka_setup_donor_password’, ‘leyka_setup_donor_password’);470add_action('wp_ajax_nopriv_leyka_setup_donor_password’, ‘leyka_setup_donor_password’);471472function leyka_donor_login(){473474 $res = [‘status’ => 'ok’, ‘message’ => __('You are logged in and will be redirected in a moment. Welcome to your personal account :)', ‘leyka’)];475476 if(477 leyka_options()->opt(‘check_nonce_on_public_donor_actions’)478 && (empty($_POST[‘nonce’]) || !wp_verify_nonce($_POST[‘nonce’], ‘leyka_donor_login’))479 ) {480 $res = [481 ‘status’ => 'error’,482 ‘message’ => sprintf(__('Wrong request. Please, <a href="mailto:%s" target="_blank">contact the website tech. support</a> about it.’, ‘leyka’), leyka_get_website_tech_support_email())483 ];484 } else if(485 empty($_POST[‘leyka_donor_email’])486 || !is_email($_POST[‘leyka_donor_email’])487 || empty($_POST[‘leyka_donor_pass’])488 ) {489 $res = [490 ‘status’ => 'error’,491 ‘message’ => sprintf(__('Wrong request data. Please, <a href="mailto:%s" target="_blank">contact the website tech. support</a> about it.’, ‘leyka’), leyka_get_website_tech_support_email())492 ];493 } else {494495 try {496 $donor = new Leyka_Donor($_POST[‘leyka_donor_email’]);497 } catch(Exception $e) {498 $donor = false;499 }500501 if( !$donor ) {502 $res = [‘status’ => 'error’, ‘message’ => __('Incorrect email or password.’, ‘leyka’),];503 } else if( !$donor->has_account_access ) {504 $res = [‘status’ => 'error’, ‘message’ => __(“You don’t have an access for the donor account yet.", ‘leyka’),];505 } else {506507 $donor_logged_in = $donor->login($_POST[‘leyka_donor_pass’], true);508509 if(is_wp_error($donor_logged_in)) {510 $res = [‘status’ => 'error’, ‘message’ => strip_tags($donor_logged_in->get_error_message()),];511 }512513 }514515 }516517 die(json_encode($res));518519}520add_action('wp_ajax_leyka_donor_login’, ‘leyka_donor_login’);521add_action('wp_ajax_nopriv_leyka_donor_login’, ‘leyka_donor_login’);522523function leyka_donor_password_reset_request(){524525 $res = [‘status’ => 'ok’, ‘message’ => __('Your password is ready to reset! Check your email for the confirmation link.’, ‘leyka’)];526527 if(528 leyka_options()->opt(‘check_nonce_on_public_donor_actions’)529 && (empty($_POST[‘nonce’]) || !wp_verify_nonce($_POST[‘nonce’], ‘leyka_donor_password_reset’))530 ) {531 $res = [532 ‘status’ => 'error’,533 ‘message’ => sprintf(__('Wrong request. Please, <a href="mailto:%s” target="_blank">contact the website tech. support</a> about it.’, ‘leyka’), leyka_get_website_tech_support_email())534 ];535 } else if(empty($_POST[‘leyka_donor_email’]) || !is_email($_POST[‘leyka_donor_email’])) {536 $res = [537 ‘status’ => 'error’,538 ‘message’ => sprintf(__('Wrong request data. Please, <a href="mailto:%s" target="_blank">contact the website tech. support</a> about it.’, ‘leyka’), leyka_get_website_tech_support_email())539 ];540 } else {541542 try {543 $donor = new Leyka_Donor($_POST[‘leyka_donor_email’]);544 } catch(Exception $e) {545 $donor = false;546 }547548 if( !$donor ) {549 $res = [‘status’ => 'error’, ‘message’ => __(‘Incorrect email.’, ‘leyka’),];550 } else {551552 $pass_reset_key = $donor->get_password_reset_key();553554 if($pass_reset_key && !is_wp_error($pass_reset_key)) {555556 $email_text = sprintf(557 __("Hello, %s!\n\nYou received this email because someone asked to reset your email on the <a href=’%s’>%s</a> website.\n\nIf it was not you, just ignore this email and nothing will happen.\n\n If you really wish to reset your password, click <a href=’%s’ target=’_blank’>here</a>.\n\nGood day to you!", ‘leyka’),558 $donor->display_name,559 home_url(),560 get_bloginfo(‘name’),561 home_url('/donor-account/reset-password/?code=’.$pass_reset_key.’&donor=’.urlencode($_POST[‘leyka_donor_email’]))562 );563564 add_filter('wp_mail_content_type’, ‘leyka_set_html_content_type’);565566 $email_sent = wp_mail(567 $_POST[‘leyka_donor_email’],568 apply_filters('leyka_email_donor_password_reset_title’, __('Your account access resetting’, ‘leyka’), $donor),569 wpautop(apply_filters('leyka_email_donor_password_reset_text’, $email_text, $donor)),570 [571 'From: '.apply_filters(572 ‘leyka_email_from_name’,573 leyka_options()->opt_safe(‘email_from_name’),574 $donor575 ).’ <’.leyka_options()->opt_safe(‘email_from’).’>’,576 ]577 );578 if( !$email_sent ) {579 $res = [580 ‘status’ => 'error’,581 ‘message’ => sprintf(__('Sorry, we could not send the password resetting email to you. Please, <a href="mailto:%s" target="_blank">contact the website tech. support</a> about it.’, ‘leyka’), leyka_get_website_tech_support_email())582 ];583 }584585 remove_filter('wp_mail_content_type’, ‘leyka_set_html_content_type’);586587 } else {588 $res = [‘status’ => 'error’, ‘message’ => __(“Can’t get the password reset key.", ‘leyka’),];589 }590591 }592593 }594595 die(json_encode($res));596597}598add_action('wp_ajax_leyka_donor_password_reset_request’, ‘leyka_donor_password_reset_request’);599add_action('wp_ajax_nopriv_leyka_donor_password_reset_request’, ‘leyka_donor_password_reset_request’);600601function leyka_get_donations_history_page() {602603 $res = [‘status’ => 'ok’, ‘items_html’ => ‘’];604605 if(606 leyka_options()->opt(‘check_nonce_on_public_donor_actions’)607 && (empty($_POST[‘nonce’]) || !wp_verify_nonce($_POST[‘nonce’], ‘leyka_get_donor_donations_history’))608 ) {609 die(json_encode([‘status’ => 'error’,]));610 }611612 if(empty($_POST[‘donor_id’]) || empty($_POST[‘page’])) {613 die(json_encode([‘status’ => 'error’,]));614 }615616 try {617 $donor = new Leyka_Donor(absint($_POST[‘donor_id’]));618 } catch(Exception $e) {619 die(json_encode([‘status’ => 'error’,]));620 }621622 foreach($donor->get_donations(absint($_POST[‘page’])) as $donation) {623 $res[‘items_html’] .= leyka_get_donor_account_donations_list_item_html(false, $donation)."\n";624 }625626 die(json_encode($res));627628}629add_action('wp_ajax_leyka_get_donations_history_page’, ‘leyka_get_donations_history_page’);630add_action('wp_ajax_nopriv_leyka_get_donations_history_page’, ‘leyka_get_donations_history_page’);631632function leyka_cancel_recurring_subscription(){633634 if(635 leyka_options()->opt(‘check_nonce_on_public_donor_actions’)636 && (empty($_POST[‘_wpnonce’]) || !wp_verify_nonce($_POST[‘_wpnonce’], ‘leyka_cancel_subscription’))637 ) {638 die(json_encode([639 ‘status’ => 'error’,640 ‘message’ => sprintf(__('Wrong request. Please, <a href="mailto:%s” target="_blank">contact the website tech. support</a> about it.’, ‘leyka’), leyka_options()->opt(‘tech_support_email’))641 ]));642 } else if(empty($_POST[‘leyka_campaign_id’]) || empty($_POST[‘leyka_donation_id’])) {643 die(json_encode([644 ‘status’ => 'error’,645 ‘message’ => sprintf(__('Wrong request data. Please, <a href="mailto:%s" target="_blank">contact the website tech. support</a> about it.’, ‘leyka’), leyka_options()->opt(‘tech_support_email’))646 ]));647 }648649 $campaign_id = absint($_POST[‘leyka_campaign_id’]);650 $donation_id = absint($_POST[‘leyka_donation_id’]);651652 try {653 $donor = new Leyka_Donor(get_current_user_id());654 } catch(Exception $e) {655 $donor = false;656 }657658 $campaign = new Leyka_Campaign($campaign_id);659 $init_recurring_donation = Leyka_Donations::get_instance()->get($donation_id);660661 $cancel_reasons = is_array($_POST[‘leyka_cancel_subscription_reason’]) ?662 $_POST[‘leyka_cancel_subscription_reason’] : [$_POST[‘leyka_cancel_subscription_reason’]];663664 if($cancel_reasons) {665666 $leyka_possible_reasons = leyka_get_recurring_subscription_cancelling_reasons();667 $reason_text_lines = [];668669 foreach($cancel_reasons as $reason) {670671 if($reason === ‘other’) {672 $line = sprintf(__('Other reason: %s’, ‘leyka’), isset($_POST[‘leyka_donor_custom_reason’]) ? $_POST[‘leyka_donor_custom_reason’] : ‘’);673 } else {674 $line = $leyka_possible_reasons[$reason];675 }676677 $reason_text_lines[] = $line;678679 }680681 $reason_text = implode(“\n", $reason_text_lines);682683 } else {684 $reason_text = '’;685 }686687 if( !$donor || !$donor->has_account_access ) {688 die(json_encode([689 ‘status’ => 'error’,690 ‘message’ => __('This operation is allowed only for registered donors.’, ‘leyka’),691 ]));692 } else if( !$campaign ) {693 die(json_encode([694 ‘status’ => 'error’,695 ‘message’ => sprintf(__('The campaign #%s is not found. Please, <a href="mailto:%s” target="_blank">contact the website tech. support</a> about it.’, ‘leyka’), $campaign_id, leyka()->opt(‘tech_support_email’))696 ]));697 } else if( !$init_recurring_donation ) {698 die(json_encode([699 ‘status’ => 'error’,700 ‘message’ => sprintf(__('Donation #%s is not found. Please, <a href="mailto:%s" target="_blank">contact the website tech. support</a> about it.’, ‘leyka’), $donation_id, leyka()->opt(‘tech_support_email’))701 ]));702 }703704 $res = [‘status’ => 'ok’, ‘message’ => __('Your request to unsubscribe accepted.’, ‘leyka’)];705706 $donation_gateway = leyka_get_gateway_by_id($init_recurring_donation->gateway_id);707 if($donation_gateway->has_recurring_auto_cancelling_support) { // Recurring auto-cancelling supported - do it708709 $cancelling_result = $donation_gateway->cancel_recurring_subscription($init_recurring_donation);710711 if(is_wp_error($cancelling_result)) { /** @var $cancelling_result WP_Error */712 die( json_encode([‘status’ => 'error’, ‘message’ => $cancelling_result->get_error_message()]) );713 } else if( !$cancelling_result ) {714 die(json_encode([715 ‘status’ => 'error’,716 ‘message’ => sprintf(__('Error while trying to cancel the recurring subscription.<br><br>Please, email abount this to the <a href="mailto:%s" target="_blank">website tech. support</a>.<br><br>We are very sorry for inconvenience.’, ‘leyka’), leyka_get_website_tech_support_email())717 ]));718 }719720 $init_recurring_donation->recurring_cancel_reason = $reason_text;721722 $res[‘message’] = __('Your recurring subscription cancelled.’, ‘leyka’);723724 } else { // We can only "request to cancel a recurring subscription", so the website admin could cancel it manually725726 $init_recurring_donation->cancel_recurring_requested = true; // Save unsubscribe request flag727728 $email_text = sprintf(729 __(“Hello!\n\nDonor %s with email %s and ID %s would like to unsubscribe from campaign <a href=’%s’>%s</a> with ID %s on the <a href=’%s’>%s</a> website.\n\nLink to subscription: %s\n\nThe reasons are:\n%s", ‘leyka’),730 $donor->name,731 $donor->email,732 $donor->id,733 $campaign->permalink,734 $campaign->title,735 $campaign->ID,736 home_url(),737 get_bloginfo(‘name’),738 admin_url('admin.php?page=leyka_donation_info&donation=’.$init_recurring_donation->id),739 $reason_text740 );741 add_filter('wp_mail_content_type’, ‘leyka_set_html_content_type’);742743 $email_sent = wp_mail(744 leyka_get_dm_list_or_alternatives(),745 apply_filters('leyka_email_manager_cancel_subscription_title’, __('New cancel campaign subscription request’, ‘leyka’), $donor, $campaign),746 wpautop(apply_filters('leyka_email_manager_cancel_subscription_text’, $email_text, $donor, $campaign)),747 [748 'From: '.apply_filters(‘leyka_email_from_name’, leyka_options()->opt_safe(‘email_from_name’), $donor)749 .’ <’.leyka_options()->opt_safe(‘email_from’).’>’,750 ]751 );752753 if( !$email_sent ) {754 $res = [755 ‘status’ => 'error’,756 ‘message’ => sprintf(__('Sorry, we could not send unsubscription request. Please, <a href="mailto:%s” target="_blank">contact the website tech. support</a> about it.’, ‘leyka’), leyka()->opt(‘tech_support_email’))757 ];758 }759760 remove_filter('wp_mail_content_type’, ‘leyka_set_html_content_type’);761762 }763764 if(in_array('uncomfortable_pm’, $cancel_reasons) || in_array('too_much’, $cancel_reasons)) {765 $res[‘redirect_to’] = $campaign->url;766 }767768 die(json_encode($res));769770}771add_action('wp_ajax_leyka_cancel_recurring’, ‘leyka_cancel_recurring_subscription’); // leyka_unsubscribe_persistent_campaign772add_action('wp_ajax_nopriv_leyka_cancel_recurring’, ‘leyka_cancel_recurring_subscription’);773774function leyka_cancel_recurring_subscription_by_manager(){775776 $donation_id = absint($_POST[‘donation_id’]);777 $init_recurring_donation = Leyka_Donations::get_instance()->get($donation_id);778779 if( $_POST[‘state’] === ‘true’ && !$init_recurring_donation->recurring_is_active ) {780 $init_recurring_donation->recurring_is_active = 'true’;781 } else if( $_POST[‘state’] !== ‘true’ && $init_recurring_donation->recurring_is_active ) {782783 $donation_gateway = leyka_get_gateway_by_id($init_recurring_donation->gateway_id);784 $donation_gateway->cancel_recurring_subscription($init_recurring_donation);785786 }787788 die(json_encode([‘status’ => ‘ok’]));789790}791add_action('wp_ajax_leyka_cancel_recurring_by_manager’, ‘leyka_cancel_recurring_subscription_by_manager’);792793function leyka_reset_campaign_attachment(){794795 $_POST[‘campaign_id’] = empty($_POST[‘campaign_id’]) ? false : absint($_POST[‘campaign_id’]);796 $_POST[‘attachment_id’] = empty($_POST[‘attachment_id’]) ? false : absint($_POST[‘attachment_id’]);797798 if(empty($_POST[‘nonce’]) || !wp_verify_nonce($_POST[‘nonce’], ‘reset-campaign-attachment’)) {799 die(json_encode([‘status’ => 'error’, ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),]));800 } else if(empty($_POST[‘campaign_id’])) {801 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: campaign ID is missing’, ‘leyka’),]));802 } else if(empty($_POST[‘img_mission’])) {803 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: field name is missing’, ‘leyka’),]));804 }805806 delete_post_meta($_POST[‘campaign_id’], 'campaign_’.esc_attr(sanitize_text_field($_POST[‘img_mission’])));807808 die(json_encode([‘status’ => 'ok’,]));809810}811add_action('wp_ajax_leyka_reset_campaign_attachment’, ‘leyka_reset_campaign_attachment’);812813function leyka_usage_stats_y(){814815 if(empty($_POST[‘nonce’]) || !wp_verify_nonce($_POST[‘nonce’], ‘usage_stats_y’)) {816 die(json_encode([‘status’ => 'error’, ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),]));817 }818819 update_option('leyka_plugin_stats_option_needs_sync’, time());820 $stats_option_synch_res = leyka_sync_plugin_stats_option();821822 if(is_wp_error($stats_option_synch_res)) {823 die(json_encode([824 ‘status’ => 'error’,825 ‘message’ => __('Connection to leyka statistics server failed!’, ‘leyka’),826 ]));827 } else {828829 delete_option(‘leyka_plugin_stats_option_needs_sync’);830 update_option('leyka_plugin_stats_option_sync_done’, time());831832 leyka()->opt('send_plugin_stats’, ‘y’);833834 }835836 die(json_encode([‘status’ => 'ok’, ‘message’ => __('Thank you!’, ‘leyka’),]));837838}839add_action('wp_ajax_leyka_usage_stats_y’, ‘leyka_usage_stats_y’);840841function leyka_donors_autocomplete(){842843 $search_query = isset($_GET[‘term’]) ? sanitize_text_field($_GET[‘term’]) : '’;844 $res = [];845846 if( !$search_query ) {847 die(json_encode($res));848 }849850 if(isset($_GET[‘type’]) && $_GET[‘type’] === ‘users’) { // Search for donors in user accounts851852 $donors = get_users([853 ‘role__in’ => [Leyka_Donor::DONOR_USER_ROLE,],854 ‘number’ => 10,855 ‘search’ => '*’.str_replace('*’, '’, $search_query).’*’,856 ‘search_columns’ => ['login’, 'nicename’, ‘email’],857 ]);858859 foreach($donors as $donor) {860 $res[] = [861 ‘label’ => sprintf('%s (%s)', $donor->display_name, $donor->user_email),862 ‘value’ => $donor->user_email863 ];864 }865866 } else { // Search for donors in Donations fields values867868 $donations = Leyka_Donations::get_instance()->get([869 ‘status’ => 'funded’,870 ‘results_limit’ => 10,871 ‘donor_name_email’ => '%’.$search_query,872 ]);873874// get_posts([875// ‘post_type’ => Leyka_Donation_Management::$post_type,876// ‘post_status’ => 'funded’,877// ‘posts_per_page’ => 10,878// ‘meta_query’ => [879// ‘relation’ => 'OR’,880// [‘key’ => 'leyka_donor_name’, ‘value’ => $search_query, ‘compare’ => 'LIKE’,],881// [‘key’ => 'leyka_donor_email’, ‘value’ => $search_query, ‘compare’ => 'LIKE’,],882// ]883// ]);884885 $tmp_res = []; // Find unique emails886 foreach($donations as $donation) {887888 $donation = Leyka_Donations::get_instance()->get_donation($donation);889 if( !array_key_exists($donation->donor_email, $tmp_res) ) {890 $tmp_res[$donation->donor_email] = $donation->donor_name;891 }892893 }894 foreach($tmp_res as $email => $name) {895 $res[] = [‘label’ => sprintf('%s (%s)', $name, $email), ‘value’ => $email];896 }897898 }899900 die(json_encode($res));901902}903add_action('wp_ajax_leyka_donors_autocomplete’, ‘leyka_donors_autocomplete’);904905function leyka_gateways_autocomplete(){906907 $res = [];908909 $pm_list = leyka_get_pm_list();910 foreach($pm_list as $pm) {911 $res[] = [‘label’ => sprintf("%s (%s)", $pm->title, $pm->gateway->title), ‘value’ => $pm->full_id];912 }913914 die(json_encode($res));915916}917add_action('wp_ajax_leyka_gateways_autocomplete’, ‘leyka_gateways_autocomplete’);918919function leyka_campaigns_autocomplete(){920921 $filter = isset($_GET[‘term’]) ? sanitize_text_field($_GET[‘term’]) : '’;922 $res = [];923924 $campaigns = leyka_get_campaigns_list([‘s’ => $filter,], false);925926 foreach($campaigns as $campaign) {927 $res[] = [‘value’ => $campaign->id, ‘label’ => $campaign->title, ‘payment_title’ => $campaign->payment_title,];928 }929930 die(json_encode($res));931932}933add_action('wp_ajax_leyka_campaigns_autocomplete’, ‘leyka_campaigns_autocomplete’);934935function leyka_donors_tags_autocomplete(){936937 $filter = isset($_GET[‘term’]) ? sanitize_text_field($_GET[‘term’]) : '’;938939 $res = [];940941 if($filter) {942 $donors_tags = get_terms(943 Leyka_Donor::DONORS_TAGS_TAXONOMY_NAME,944 [‘hide_empty’ => false, ‘orderby’ => 'name’, ‘order’ => 'ASC’, ‘search’ => $filter,]945 );946 } else {947 $donors_tags = get_terms(948 Leyka_Donor::DONORS_TAGS_TAXONOMY_NAME,949 [‘hide_empty’ => false, ‘orderby’ => 'count’, ‘order’ => 'DESC’, ‘count’ => 10,]950 );951 }952953 foreach($donors_tags as $tag) {954 $res[] = [‘label’ => $tag->name, ‘value’ => $tag->term_id,];955 }956957 die(json_encode($res));958959}960add_action('wp_ajax_leyka_donors_tags_autocomplete’, ‘leyka_donors_tags_autocomplete’);961962function leyka_add_donor_comment(){963964 if(empty($_POST[‘nonce’]) || !wp_verify_nonce($_POST[‘nonce’], ‘leyka_add_donor_comment’)) {965 die(json_encode([‘status’ => 'error’, ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),]));966 }967968 try {969 $donor = new Leyka_Donor(absint($_POST[‘donor’]));970 } catch(Exception $e) {971 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: donor not found’, ‘leyka’),]));972 }973974 if(empty($_POST[‘comment’])) {975 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: empty comment’, ‘leyka’),]));976 }977978 $comment_text = sanitize_text_field($_POST[‘comment’]);979 $donor->add_comment($comment_text);980981 $comments = $donor->get_comments();982 $comment_id = 0;983 $comment = [];984985 foreach($comments as $donor_comment_id => $donor_comment) {986 $comment_id = $donor_comment_id;987 $comment = $donor_comment;988 }989990 $comment = [991 ‘id’ => $comment_id,992 ‘text’ => stripslashes(esc_html($comment[‘text’])),993 ‘date’ => time(),994 ‘author_name’ => $comment[‘author_name’],995 ];996997 $comment_table_row_html = leyka_admin_get_donor_comment_table_row($comment_id, $comment);998999 die(json_encode([‘status’ => 'ok’, ‘comment_html’ => $comment_table_row_html]));10001001}1002add_action('wp_ajax_leyka_add_donor_comment’, ‘leyka_add_donor_comment’);10031004function leyka_delete_donor_comment(){10051006 if(empty($_POST[‘comment_id’])) {1007 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: undefined comment id’, ‘leyka’),]));1008 }10091010 $_POST[‘comment_id’] = absint($_POST[‘comment_id’]);10111012 if(empty($_POST[‘nonce’]) || !wp_verify_nonce($_POST[‘nonce’], ‘leyka_delete_donor_comment’)) {1013 die(json_encode([‘status’ => 'error’, ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),]));1014 }10151016 try {1017 $donor = new Leyka_Donor(absint($_POST[‘donor’]));1018 } catch(Exception $e) {1019 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: donor not found’, ‘leyka’),]));1020 }10211022 try {1023 $donor->delete_comment($_POST[‘comment_id’]);1024 } catch(Exception $ex) {1025 die(json_encode([1026 ‘status’ => 'error’,1027 ‘message’ => $ex->getMessage()1028 ]));1029 }10301031 die(json_encode([‘status’ => 'ok’,]));10321033}1034add_action('wp_ajax_leyka_delete_donor_comment’, ‘leyka_delete_donor_comment’);10351036function leyka_save_editable_comment(){10371038 if(empty($_POST[‘nonce’]) || !wp_verify_nonce($_POST[‘nonce’], ‘leyka_save_editable_str’)) {1039 die(json_encode([‘status’ => 'error’, ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),]));1040 }10411042 try {1043 $donor = new Leyka_Donor(absint($_POST[‘donor’]));1044 } catch(Exception $e) {1045 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: donor not found’, ‘leyka’),]));1046 }10471048 if(empty($_POST[‘text_item_id’])) {1049 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: empty comment id’, ‘leyka’),]));1050 }10511052 if(empty($_POST[‘text’])) {1053 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: empty text’, ‘leyka’),]));1054 }10551056 $comment_text = sanitize_text_field($_POST[‘text’]);1057 $donor->update_comment(absint($_POST[‘text_item_id’]), $comment_text);10581059 die(json_encode([1060 ‘status’ => 'ok’,1061 ‘saved_text’ => stripcslashes(stripcslashes(htmlspecialchars_decode($comment_text))),1062 ]));10631064}1065add_action('wp_ajax_leyka_save_editable_comment’, ‘leyka_save_editable_comment’);10661067// Donor’s Donations data table AJAX data source:1068function leyka_admin_get_donor_donations(){10691070 try {1071 $donor = new Leyka_Donor(absint($_POST[‘donor_id’]));1072 } catch(Exception $e) {1073 die( json_encode([‘draw’ => (int)$_POST[‘draw’], ‘error’ => $e->getMessage()]) );1074 }10751076 $_POST[‘start’] = empty($_POST[‘start’]) ? 0 : absint($_POST[‘start’]); // Result record number to start from1077 $_POST[‘length’] = empty($_POST[‘length’]) ? 10 : absint($_POST[‘length’]); // Donations per table "page"10781079 $total_donor_donations = $donor->get_donations_count();1080 $page_number = ($_POST[‘start’]/$_POST[‘length’]) + 1;10811082 $result = [1083 ‘draw’ => (int)$_POST[‘draw’],1084 ‘recordsTotal’ => $total_donor_donations,1085 ‘recordsFiltered’ => $total_donor_donations,1086 ‘data’ => [],1087 ];10881089 foreach($donor->get_donations($page_number, $_POST[‘length’]) as $donation) {10901091 $gateway = leyka_get_gateway_by_id($donation->gateway_id);10921093 $result[‘data’][] = [1094 ‘donation_id’ => $donation->id,1095 ‘payment_type’ => [1096 ‘id’ => $donation->is_init_recurring_donation ? ‘rebill-init’ : $donation->payment_type,1097 ‘label’ => $donation->payment_type_label,1098 ],1099 ‘date’ => $donation->date_time_label,1100 ‘status’ => [1101 ‘id’ => $donation->status,1102 ‘label’ => $donation->status_label,1103 ‘description’ => $donation->status_description,1104 ],1105 ‘campaign_title’ => $donation->campaign_title,1106 ‘gateway_pm’ => [1107 ‘gateway_icon_url’ => $gateway ? $gateway->icon_url : '’,1108 ‘gateway_label’ => $donation->gateway_label,1109 ‘pm_label’ => $donation->pm_label,1110 ],1111 ‘amount’ => [1112 ‘amount_formatted’ => $donation->main_currency_amount,1113 ‘amount_total_formatted’ => $donation->main_currency_amount_total,1114 ‘currency_label’ => leyka_get_currency_label(),1115 ],1116 ];11171118 }11191120 die(json_encode($result));11211122}1123add_action('wp_ajax_leyka_get_donor_donations’, ‘leyka_admin_get_donor_donations’);1124// Donor’s Donations data table AJAX data source - END11251126// Campaign Donations data table AJAX data source:1127function leyka_admin_get_campaign_donations(){11281129 $campaign = new Leyka_Campaign($_POST[‘campaign_id’]);11301131// die( json_encode([(‘draw’ => (int)$_POST[‘draw’], ‘error’ => $e->getMessage()]) );11321133 $_POST[‘start’] = empty($_POST[‘start’]) ? 0 : absint($_POST[‘start’]); // Result record number to start from1134 $_POST[‘length’] = empty($_POST[‘length’]) ? 10 : absint($_POST[‘length’]); // Donations per table "page"11351136 $total_campaign_donations = $campaign->get_donations_count();1137 $page_number = ($_POST[‘start’] / $_POST[‘length’]) + 1;11381139 $result = [1140 ‘draw’ => (int)$_POST[‘draw’],1141 ‘recordsTotal’ => $total_campaign_donations,1142 ‘recordsFiltered’ => $total_campaign_donations,1143 ‘data’ => [],1144 ];11451146 $campaign_donations = Leyka_Donations::get_instance()->get([1147 ‘status’ => ['submitted’, 'funded’, 'refunded’, 'failed’,],1148 ‘campaign_id’ => $campaign->id,1149 ‘results_limit’ => $_POST[‘length’],1150 ‘page’ => $page_number,1151 ‘orderby’ => 'ID’,1152 ‘order’ => 'DESC’,1153 ]);11541155 foreach($campaign_donations as $donation) {11561157 $gateway = leyka_get_gateway_by_id($donation->gateway_id);11581159 $result[‘data’][] = [1160 ‘donation_id’ => $donation->id,1161 ‘payment_type’ => [1162 ‘id’ => $donation->is_init_recurring_donation ? ‘rebill-init’ : $donation->payment_type,1163 ‘label’ => $donation->payment_type_label,1164 ],1165 ‘donor’ => [1166 ‘name’ => $donation->donor_name,1167 ‘email’ => $donation->donor_email,1168 ‘id’ => leyka_options()->opt(‘donor_management_available’) && $donation->donor_id ? $donation->donor_id : 0,1169 ],1170 ‘amount’ => [1171 ‘amount’ => $donation->amount,1172 ‘formatted’ => $donation->amount_formatted,1173 ‘total’ => $donation->amount_total,1174 ‘total_formatted’ => $donation->amount_total_formatted,1175 ‘currency_label’ => $donation->currency_label,1176 ],1177 ‘status’ => [1178 ‘id’ => $donation->status,1179 ‘label’ => $donation->status_label,1180 ‘description’ => $donation->status_description,1181 ],1182 ‘date’ => $donation->date_time_label,1183 ‘gateway_pm’ => [1184 ‘gateway_icon_url’ => $gateway ? $gateway->icon_url : '’,1185 ‘gateway_label’ => $donation->gateway_id == ‘correction’ ?1186 __('Custom payment info’, ‘leyka’) : $donation->gateway_label,1187 ‘pm_label’ => $donation->pm_label,1188 ],1189 ];11901191 }11921193 die(json_encode($result));11941195}1196add_action('wp_ajax_leyka_get_campaign_donations’, ‘leyka_admin_get_campaign_donations’);1197// Campaign Donations data table AJAX data source - END11981199// Recurring subscription Donations data table AJAX data source:1200function leyka_admin_get_recurring_subscription_donations(){12011202 $_POST[‘recurring_subscription_id’] = absint($_POST[‘recurring_subscription_id’]);1203 if( !$_POST[‘recurring_subscription_id’] ) {1204 die( json_encode([‘draw’ => (int)$_POST[‘draw’], ‘error’ => __('Incorrect recurring subscription ID given’, ‘leyka’)]) );1205 }12061207 try {1208 $recurring_subscription = Leyka_Donations::get_instance()->get($_POST[‘recurring_subscription_id’]);1209 } catch(Exception $ex) {1210 die( json_encode([‘draw’ => (int)$_POST[‘draw’], ‘error’ => $ex->getMessage()]) );1211 }12121213 if( !$recurring_subscription->is_init_recurring_donation ) {1214 die( json_encode([‘draw’ => (int)$_POST[‘draw’], ‘error’ => __('ID given is not of a recurring subscription’, ‘leyka’)]) );1215 }12161217 $_POST[‘start’] = empty($_POST[‘start’]) ? 0 : absint($_POST[‘start’]); // Result record number to start from1218 $_POST[‘length’] = empty($_POST[‘length’]) ? 10 : absint($_POST[‘length’]); // Donations per table "page"12191220 $total_recurring_donations = Leyka_Donations::get_instance()->get_count([1221 ‘status’ => ['submitted’, 'funded’, 'refunded’, 'failed’,],1222 ‘recurring_rebills_of’ => $recurring_subscription->id,1223 ‘get_all’ => true,1224 ]);1225 $page_number = ($_POST[‘start’] / $_POST[‘length’]) + 1;12261227 $result = [1228 ‘draw’ => (int)$_POST[‘draw’],1229 ‘recordsTotal’ => $total_recurring_donations,1230 ‘recordsFiltered’ => $total_recurring_donations,1231 ‘data’ => [],1232 ];12331234 $donations = Leyka_Donations::get_instance()->get([1235 ‘status’ => ['submitted’, 'funded’, 'refunded’, 'failed’,],1236 ‘recurring_rebills_of’ => $recurring_subscription->id,1237 ‘results_limit’ => $_POST[‘length’],1238 ‘page’ => $page_number,1239 ‘orderby’ => 'ID’,1240 ‘order’ => 'DESC’,1241 ]);12421243 foreach($donations as $donation) {12441245 $gateway = leyka_get_gateway_by_id($donation->gateway_id);1246 $pm = $donation->gateway_id && $donation->gateway_id !== ‘correction’ ?1247 leyka_get_pm_by_id($donation->pm_full_id, true) : $donation->pm_id;12481249 if($donation->status === ‘failed’) {12501251 $error = $donation->error; /** @var $error Leyka_Donation_Error */1252 $error = is_a($error, ‘Leyka_Donation_Error’) ?1253 $error : Leyka_Donations_Errors::get_instance()->get_error_by_id(false);12541255 }12561257 $result[‘data’][] = [1258 ‘donation_id’ => $donation->id,1259 ‘type’ => [1260 ‘name’ => $donation->type,1261 ‘label’ => $donation->type_label1262 ],1263 ‘donor’ => [1264 ‘name’ => $donation->donor_name,1265 ‘email’ => $donation->donor_email,1266 ‘id’ => leyka_options()->opt(‘donor_management_available’) && $donation->donor_id ? $donation->donor_id : 0,1267 ‘email_sent’ => (bool)$donation->donor_email_date,1268 ‘email_date’ => $donation->donor_email_date ? date('d.m.Y’, $donation->donor_email_date) : '’,1269 ‘wp_nonce’ => wp_create_nonce(‘leyka_donor_email’)1270 ],1271 ‘date’ => [1272 ‘date_label’ => $donation->date_label,1273 ‘time_label’ => $donation->time_label1274 ],1275 ‘amount’ => [1276 ‘amount’ => $donation->amount,1277 ‘formatted’ => $donation->amount_formatted,1278 ‘total’ => $donation->amount_total,1279 ‘total_formatted’ => $donation->amount_total_formatted,1280 ‘currency_label’ => $donation->currency_label,1281 ],1282 ‘status’ => [1283 ‘id’ => $donation->status,1284 ‘label’ => $donation->status_label,1285 ‘description’ => $donation->status_description,1286 ‘error’ => [1287 ‘id’ => $donation->status === ‘failed’ ? $error->id : '’,1288 ‘name’ => $donation->status === ‘failed’ ? $error->name : '’,1289 ‘full_info’ => $donation->status === ‘failed’ ? leyka_show_donation_error_full_info($error, true) : '’1290 ]1291 ],1292 ‘gateway_pm’ => [1293 ‘leyka_plugin_base_url’ => LEYKA_PLUGIN_BASE_URL, // TODO: Получить в JS?1294 ‘gateway’ => [1295 ‘icon_url’ => $gateway ? $gateway->icon_url : '’,1296 ‘label’ => $donation->gateway_id == ‘correction’ ?1297 __('Custom payment info’, ‘leyka’) : $donation->gateway_label1298 ],1299 ‘pm’ => [1300 ‘label’ => is_a($pm, ‘Leyka_Payment_Method’) ? $donation->pm_label : '’,1301 ‘admin_icon_url’ => is_a($pm, ‘Leyka_Payment_Method’) ? $pm->admin_icon_url : '’1302 ]1303 ]1304 ];13051306 }13071308 die(json_encode($result));13091310}1311add_action('wp_ajax_leyka_get_recurring_subscription_donations’, ‘leyka_admin_get_recurring_subscription_donations’);1312// Recurring subscription Donations data table AJAX data source - END13131314function leyka_save_donor_description(){13151316 if(empty($_POST[‘nonce’]) || !wp_verify_nonce($_POST[‘nonce’], ‘leyka_save_editable_str’)) {1317 die(json_encode([‘status’ => 'error’, ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),]));1318 }13191320 try {1321 $donor = new Leyka_Donor(absint($_POST[‘donor’]));1322 } catch(Exception $e) {1323 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: donor not found’, ‘leyka’),]));1324 }13251326 $donor->description = !empty($_POST[‘text’]) ? sanitize_text_field($_POST[‘text’]) : “";13271328 die(json_encode([1329 ‘status’ => 'ok’,1330 ‘saved_text’ => stripcslashes(stripcslashes(htmlspecialchars_decode($donor->description))),1331 ]));13321333}1334add_action('wp_ajax_leyka_save_donor_description’, ‘leyka_save_donor_description’);13351336function leyka_save_donor_name(){13371338 if(empty($_POST[‘nonce’]) || !wp_verify_nonce($_POST[‘nonce’], ‘leyka_save_editable_str’)) {1339 die(json_encode([‘status’ => 'error’, ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),]));1340 }13411342 try {1343 $donor = new Leyka_Donor(absint($_POST[‘donor’]));1344 } catch(Exception $e) {1345 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: donor not found’, ‘leyka’),]));1346 }13471348 $donor->name = !empty($_POST[‘text’]) ? sanitize_text_field($_POST[‘text’]) : '’;13491350 die(json_encode([1351 ‘status’ => 'ok’,1352 ‘saved_text’ => stripcslashes(stripcslashes(htmlspecialchars_decode($donor->name))),1353 ]));13541355}1356add_action('wp_ajax_leyka_save_donor_name’, ‘leyka_save_donor_name’);13571358function leyka_save_donor_tags(){13591360 if(empty($_POST[‘nonce’]) || !wp_verify_nonce($_POST[‘nonce’], ‘leyka_save_donor_tags’)) {1361 die(json_encode([‘status’ => 'error’, ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),]));1362 }13631364 try {1365 $donor = new Leyka_Donor(absint($_POST[‘donor’]));1366 } catch(Exception $e) {1367 die(json_encode([‘status’ => 'error’, ‘message’ => __('Error: donor not found’, ‘leyka’),]));1368 }13691370 $tags = !empty($_POST[‘tags’]) ? explode(',’, sanitize_text_field($_POST[‘tags’])) : '’;1371 wp_set_object_terms($donor->id, $tags, Leyka_Donor::DONORS_TAGS_TAXONOMY_NAME);13721373 die(json_encode([‘status’ => 'ok’,]));13741375}1376add_action('wp_ajax_leyka_save_donor_tags’, ‘leyka_save_donor_tags’);13771378function leyka_close_dashboard_banner(){13791380 if(empty($_POST[‘banner_id’])) {1381 die(json_encode([‘status’ => 'error’,]));1382 }13831384 try {1385 update_user_meta(get_current_user_id(), 'leyka_dashboard_banner_closed-'.$_POST[‘banner_id’], true);1386 } catch(Exception $e) {1387 die(json_encode([‘status’ => 'error’,]));1388 }13891390 die(json_encode([‘status’ => 'ok’,]));13911392}1393add_action('wp_ajax_leyka_close_dashboard_banner’, ‘leyka_close_dashboard_banner’);13941395// Ajax files uploading handler (admin only):1396function leyka_files_upload(){13971398 $data = array_merge(isset($_POST) ? $_POST : [], isset($_FILES) ? $_FILES : []);13991400 if( !wp_verify_nonce($data[‘nonce’], 'leyka-upload-'.$data[‘option_id’]) ) {1401 die(json_encode([‘status’ => -1, ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),]));1402 }14031404 $uploaded_file = wp_handle_upload($data[‘files’], [‘test_form’ => false,]);14051406 if($uploaded_file && !isset($uploaded_file[‘error’])) {14071408 $upload_dir_base_path = wp_upload_dir();1409 $upload_dir_base_path = $upload_dir_base_path[‘basedir’];1410 $filename = basename($uploaded_file[‘url’]);14111412 $response = [1413 ‘status’ => 0,1414 ‘filename’ => $filename,1415 ‘url’ => $uploaded_file[‘url’],1416 ‘path’ => str_replace($upload_dir_base_path, '’, $uploaded_file[‘file’]),1417 ‘type’ => $uploaded_file[‘type’],1418 ];14191420 } else {1421 $response = [‘status’ => -1, ‘error’ => $uploaded_file[‘error’],];1422 }14231424 die(json_encode($response));14251426}1427add_action('wp_ajax_leyka_files_upload’, ‘leyka_files_upload’);14281429// Ajax handler for Donors bulk edit (admin only):1430function leyka_bulk_edit_donors(){14311432 if( !wp_verify_nonce($_POST[‘nonce’], ‘leyka-bulk-edit-donors’) ) {1433 die(json_encode([‘status’ => -1, ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),]));1434 }14351436 $_POST[‘bulk-edit-action’] = empty($_POST[‘bulk-edit-action’]) || !in_array($_POST[‘bulk-edit-action’], ['add’, 'remove’, ‘replace’]) ?1437 ‘add’ : trim($_POST[‘bulk-edit-action’]);14381439 if( !empty($_POST[‘donors’]) && !empty($_POST[‘donors-bulk-tags’]) ) {1440 foreach((array)$_POST[‘donors’] as $donor_user_id) {14411442 array_walk($_POST[‘donors-bulk-tags’], function( &$value ){1443 $value = absint($value);1444 });14451446 if($_POST[‘bulk-edit-action’] === ‘add’ || $_POST[‘bulk-edit-action’] === ‘replace’) {1447 $result = wp_set_object_terms($donor_user_id, $_POST[‘donors-bulk-tags’], Leyka_Donor::DONORS_TAGS_TAXONOMY_NAME, $_POST[‘bulk-edit-action’] === ‘add’);1448 } else if($_POST[‘bulk-edit-action’] === ‘remove’) {1449 $result = wp_remove_object_terms($donor_user_id, $_POST[‘donors-bulk-tags’], Leyka_Donor::DONORS_TAGS_TAXONOMY_NAME);1450 }14511452 if( !empty($result) && is_wp_error($result)) {14531454 $response = [‘status’ => -1, ‘error’ => $result->get_error_message(),];1455 break;14561457 }14581459 }1460 }14611462 die(json_encode([‘status’ => 'ok’,]));14631464}1465add_action('wp_ajax_leyka_bulk_edit_donors’, ‘leyka_bulk_edit_donors’);14661467function leyka_delete_extension(){14681469 if(empty($_POST[‘extension_id’]) || !Leyka_Extension::get_by_id($_POST[‘extension_id’])) {1470 die(json_encode([‘status’ => -1, ‘message’ => __('Cannot found given extension’, ‘leyka’),]));1471 } else if( !wp_verify_nonce($_POST[‘nonce’], 'leyka_delete_extension_’.$_POST[‘extension_id’]) ) {1472 die(json_encode([‘status’ => -1, ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),]));1473 }14741475 $extension = Leyka_Extension::get_by_id($_POST[‘extension_id’]);14761477 if( !$extension->folder || !file_exists($extension->folder) || !is_dir($extension->folder) ) {1478 die(json_encode([‘status’ => -1, ‘message’ => __('Cannot found the extension folder’, ‘leyka’),]));1479 }14801481 if( !leyka_delete_dir($extension->folder) ) {1482 die(json_encode([1483 ‘status’ => -1,1484 ‘message’ => sprintf(__('Cannot delete the extension. Please report this problem to the <a href="mailto:%s” target="_blank">Leyka technical support</a>.’, ‘leyka’), leyka_get_website_tech_support_email())1485 ]));1486 }14871488 die(json_encode([‘status’ => 0,]));14891490}1491add_action('wp_ajax_leyka_delete_extension’, ‘leyka_delete_extension’);14921493function leyka_support_packages_set_no_campaign_behavior(){14941495 if( !wp_verify_nonce($_POST[‘nonce’], ‘support-packages-no-campaign-behavior’) ) {1496 die(json_encode([‘status’ => -1, ‘message’ => __('Wrong nonce in the submitted data’, ‘leyka’),]));1497 }14981499 if(empty($_POST[‘behavior’])) {1500 die(json_encode([‘status’ => -1, ‘message’ => __('No new behavior is given for the Support packages’, ‘leyka’),]));1501 } else if( !in_array($_POST[‘behavior’], ['another-campaign’, 'content-open’, 'content-closed’,])) {1502 die(json_encode([‘status’ => -1, ‘message’ => __('Incorrect behavior is given for the Support packages’, ‘leyka’),]));1503 }15041505 if($_POST[‘behavior’] === ‘another-campaign’) {15061507 if( !absint($_POST[‘campaign_id’]) ) {1508 die(json_encode([‘status’ => -1, ‘message’ => __('No new campaign is given for the Support packages’, ‘leyka’),]));1509 }15101511 leyka_options()->opt('support_packages_campaign’, absint($_POST[‘campaign_id’]));1512 delete_option(‘leyka_support_packages_no_campaign_behavior’);15131514 } else if($_POST[‘behavior’] === ‘content-open’) {1515 update_option('leyka_support_packages_no_campaign_behavior’, ‘content-open’);1516 } else if($_POST[‘behavior’] === ‘content-closed’) {1517 update_option('leyka_support_packages_no_campaign_behavior’, ‘content-closed’);1518 }15191520 die(json_encode([‘status’ => 0,]));15211522}1523add_action('wp_ajax_leyka_support_packages_set_no_campaign_behavior’, ‘leyka_support_packages_set_no_campaign_behavior’);15241525function leyka_ajax_get_currencies_rates() {1526 die(json_encode(leyka_get_currencies_rates()));1527}1528add_action('wp_ajax_leyka_get_currencies_rates’, ‘leyka_ajax_get_currencies_rates’);

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907