44 Commits

Author SHA1 Message Date
asus
d0bfe90715 nop it wasn't my plugin's fault 2024-03-14 13:48:19 +01:00
asus
e14acfb739 wip i broke everyhting :p 2024-03-14 13:10:05 +01:00
asus
76f2e8ba00 wip debug redirections 2024-03-14 12:31:31 +01:00
asus
ecc072e25b added redirection without need of a page, use it for paypal success or failure message already 2024-03-14 10:29:02 +01:00
asus
2f4a5bb9ef wip handle custom form submit 2024-03-14 01:18:31 +01:00
asus
12de8ee12f some improvments on shortcode user_info, to output the right secure string in most cases 2024-03-13 14:57:01 +01:00
asus
10ca070d81 - wip create role at registration
- upgraded shortcode user_infos to output acf format
2024-03-13 13:28:14 +01:00
asus
f6e092f67d - moved reset field function outside renew_card file
- created a patch for formbuilder calculation pbm
2024-03-12 21:53:32 +01:00
asus
38f9b0ba72 - in plgntls transformed process to add fetch script even if list of srcs is empty
- created a patch for form builder calculation
2024-03-12 19:54:18 +01:00
asus
591add448f wip check offres for newsletter 2024-03-11 23:20:38 +01:00
asus
046b31579c changed all role occurences by a const 2024-03-11 00:02:55 +01:00
asus
4f4bfd1c88 card number id created 2024-03-10 23:12:20 +01:00
asus
c1944dbc39 added info in class about path construction 2024-03-10 22:53:15 +01:00
asus
1021d9bf71 - added a default css file to include to have a first handle
- cahnged get_path/url to root_path/url
- changed path setup -> now automatic from inside plugin
2024-03-10 22:37:38 +01:00
asus
9ee35b23bc - renew state : removed
- payment state : in acf
2024-03-10 14:51:47 +01:00
asus
b457ed119e changed meta field payment_status for acf field 2024-03-10 14:12:24 +01:00
asus
faefa98114 - added debug function
- fixed issues in acf fields use
2024-03-10 11:13:44 +01:00
asus
f3a9be5a89 wip upgrade and clean payment process 2024-03-09 22:03:22 +01:00
asus
fc3a205359 updates acf fields const values in class to avoid errors 2024-03-08 17:57:04 +01:00
asus
789a361871 moved all const in class 2024-03-08 09:23:51 +01:00
asus
022468c096 moved and updated reset fields into rebew file 2024-03-07 23:48:01 +01:00
asus
909a34cd37 renew page message are working 2024-03-07 23:27:20 +01:00
asus
9b5e44dfd3 changed plugin name to cipf 2024-03-07 22:35:39 +01:00
asus
be79310404 changed all instances of fipf to cipf 2024-03-07 22:32:50 +01:00
asus
f870f77a2c wip prof check page now handle the success message on paiement 2024-03-07 21:34:48 +01:00
asus
5e28bf3059 update payment validation by changing prof to active 2024-03-07 19:21:11 +01:00
asus
afd34e5296 updated som error in filter email for special query author page 2024-03-07 19:08:03 +01:00
asus
4916defcaa updated filter email to filter the author page special keyword 2024-03-07 19:03:42 +01:00
asus
31c3ed55f4 wip author page checks, waiting page redirection working 2024-03-07 17:50:45 +01:00
asus
d65af4cd43 - wip filter page prof
- upgraded user info shortcode to default behavior on author page
2024-03-07 17:05:55 +01:00
asus
b244b59deb small correction in user info 2024-03-07 15:13:16 +01:00
asus
60f46265c2 updated user info shortcode to output author page and format date 2024-03-07 14:51:10 +01:00
asus
b8fbd84d53 - payment : first date error corrected
- payment : added httpErrorException
- payment : error handling wip
- profil page restriction gives access to admin and editor
2024-03-07 10:26:11 +01:00
asus
2fb1ec35aa - improved payement paypal for date and other things 2024-03-06 23:44:46 +01:00
asus
1661f16aff wip payment kind of works with bugs 2024-03-06 13:53:47 +01:00
asus
917d51a097 - wip payment
- already solved success and failure messages and redirection
  - solved increase date multiple times
- users redirection works if error AND partner to posts instead of project
2024-03-05 17:22:11 +01:00
asus
620aa9329b added check for logged in user in filter email 2024-03-05 10:44:36 +01:00
asus
39c9f492dc upgraded email filter to filter also wp hook 2024-03-05 09:55:54 +01:00
asus
63cc1f28c0 created a new function to filter emails 2024-03-05 00:10:53 +01:00
asus
44e122d415 renamed formbuilder patch files 2024-03-04 08:52:18 +01:00
asus
cf9a020162 - added a reinit function for acf fields after form validation
- added a plugin version of the modal patch for form builder
2024-03-03 21:48:39 +01:00
asus
483c02a4c6 small improvement in print user infos list 2024-03-03 10:39:34 +01:00
asus
cae80d7d24 shortcode to get user infos 2024-03-03 01:37:10 +01:00
asus
8862bab1bd some more little codes for restrictions and registrations 2024-03-02 21:43:43 +01:00
65 changed files with 3079 additions and 4150 deletions

View File

@@ -1,4 +1,4 @@
# fipf 2024 # cipf 2024
- this project uses submodules recursively, so after cloning you need to do : - this project uses submodules recursively, so after cloning you need to do :
`git submodule update --init --recursive` `git submodule update --init --recursive`

View File

@@ -0,0 +1,65 @@
<?php
/*
Plugin Name: cipf_plugin
Plugin URI:
Description:
Author: hugogogo
Version: 1.1.0
Author URI:
*/
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
* plugin dir root
PLGNTLS_class::set_root_dir( plugin_dir_path(__FILE__), plugin_dir_url(__FILE__) );
*/
include_once( plugin_dir_path(__FILE__) . '/utils/plgntls_class.php');
/*
* general inclusions
*/
// utils :
include_once(PLGNTLS_class::root_path() . 'php/utils/globals.php');
include_once(PLGNTLS_class::root_path() . 'utils/console_log.php');
include_once(PLGNTLS_class::root_path() . 'php/admin_menu/example_menu.php');
include_once(PLGNTLS_class::root_path() . 'php/paypal/paypal.php');
include_once(PLGNTLS_class::root_path() . '/php/user_infos.php');
//include_once(PLGNTLS_class::root_path() . '/php/hide_admin.php');
//include_once(PLGNTLS_class::root_path() . '/php/menus.php');
include_once(PLGNTLS_class::root_path() . 'php/register_partenaires.php');
include_once(PLGNTLS_class::root_path() . 'php/redirections.php');
include_once(PLGNTLS_class::root_path() . 'php/author_restriction.php');
include_once(PLGNTLS_class::root_path() . 'php/filter_mail.php');
include_once(PLGNTLS_class::root_path() . 'php/prof_check_page.php');
include_once(PLGNTLS_class::root_path() . 'php/renew_card.php');
//include_once(PLGNTLS_class::root_path() . 'php/reset_card_form.php');
include_once(PLGNTLS_class::root_path() . 'php/partner_check_page.php');
include_once(PLGNTLS_class::root_path() . 'php/format_user_infos.php');
include_once(PLGNTLS_class::root_path() . 'php/admin_modif_prof.php');
// form builder patch :
/*
include_once(PLGNTLS_class::root_path() . 'php/form_builder_patch/url_validation.php');
include_once(PLGNTLS_class::root_path() . 'php/form_builder_patch/multiple_modals.php');
include_once(PLGNTLS_class::root_path() . 'php/form_builder_patch/form_calculation.php');
*/
?>

View File

@@ -0,0 +1,2 @@
<div id="paypal-button-container"></div>
<p id="result-message"></p>

View File

@@ -0,0 +1,24 @@
/*
cipf_admin_activate_prof_form
*/
function admin_activate_form_submit_prevent_CIPF() {
let form_activate_prof = document.querySelector('#cipf_admin_activate_prof_form form');
console.log("form:");
console.log(form_activate_prof);
if (form_activate_prof === null)
return;
function handle_form(event) {
event.preventDefault();
let form_data = new FormData(event.target);
for (var pair of form_data.entries()) {
console.log(pair[0]+ ': ' + pair[1]);
}
}
form_activate_prof.addEventListener('submit', handle_form);
}
admin_activate_form_submit_prevent_CIPF();

View File

@@ -0,0 +1,71 @@
function patch_form_calculation_CIPF() {
let form_calculation = document.querySelector('form.fb_form.multistep');
if (form_calculation === null)
return;
/*
* finds the input:checked in the element .calculate_field
* and trigger the event 'change' on it
* - this event 'change' is added by form builder in divi-form-calc-min.js :
* $(document).on(
* 'change',
* '.calculate_field input:not([type="hidden"]), .calculate_field select',
* function () {
* ...
* }
* );
*
*/
function trigger_change(element) {
/*
* jquery version
*
let inputs = $(element).find('input:checked');
inputs.trigger('change');
*/
/*
* js version
*
*/
let inputs = element.querySelectorAll('input:checked');
// loop through inputs and trigger 'change' event on each
inputs.forEach(function(input) {
// Triggering 'change' event
let change_event = new Event('change', {
bubbles: true,
cancelable: true,
});
input.dispatchEvent(change_event);
});
}
// create an observer on form to check if child nodes are modified
const observer_form = new MutationObserver(wait_for_calculation_class);
observer_form.observe(form_calculation, {
subtree: true,
attributes: true,
});
// observe mutations to see if they include the addition of class .calculate_field
// if the class is added, call the function that might trigger the change event on it
function wait_for_calculation_class(mutationsList) {
mutationsList.forEach((mutation) => {
// check if class where added
if (mutation.type !== 'attributes')
return;
if (mutation.attributeName !== 'class')
return;
// check if added class is .calculate_field
let target = mutation.target;
if (target.classList.contains('calculate_field')) {
// If the class is added, trigger the 'change' event
trigger_change(target);
}
});
}
}
patch_form_calculation_CIPF();

View File

@@ -0,0 +1,30 @@
let modal_wrapper_CIPF = document.querySelector('#de-fb-modal-wrapper-');
// create an observer on first #de-fb-modal-wrapper- to check if child nodes are added
const observer_CIPF = new MutationObserver(wait_for_close_button_CIPF);
observer_CIPF.observe(modal_wrapper_CIPF, {
subtree: true,
childList: true,
});
// observe mutations to see if they include the creation of the button .modal-close
// if the button is created, add an eventListener to it
function wait_for_close_button_CIPF(mutationsList) {
mutationsList.forEach((mutation) => {
// check if nodes were added
if (mutation.type !== 'childList')
return;
// check if added nodes includes the button .modal-close
let modal_close = document.querySelector('#de-fb-modal-wrapper- .modal-close');
if (modal_close !== null) {
modal_close.addEventListener("click", delete_modal_CIPF);
}
});
}
// when triggered, the .modal-close button will remove all childs from #de-fb-modal-wrapper-
function delete_modal_CIPF() {
modal_wrapper_CIPF.innerHTML = '';
}

View File

@@ -1,44 +1,40 @@
import { resultMessage } from './result_message.js'; import { resultMessage } from './result_message.js';
import { PLGNTLS_fetch } from '../../utils/plgntls_fetch.js'; import { PLGNTLS_fetch } from '../../utils/plgntls_fetch.js';
/**
* @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend /*
*/ * @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend
//async function createOrder() { *
*/
export async function createOrder() { export async function createOrder() {
try { try {
//const fetch_create_url = PLGNTLS_data.fetch_url + "/fipf_plugin/api/v1/orders"; const response = await PLGNTLS_fetch('/cipf_plugin/api/v1/orders', {
//console.log("fetch_create_url:", fetch_create_url);
//const response = await fetch(fetch_create_url, {
const response = await PLGNTLS_fetch('/fipf_plugin/api/v1/orders', {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
//"X-WP-Nonce": PLGNTLS_data.rest_nonce,
}, },
// use the "body" param to optionally pass additional order information
// like product ids and quantities
body: JSON.stringify({
cart: [
{
id: "1234",
quantity: "1",
},
],
}),
}); });
const orderData = await response.json(); const orderData = await response.json();
/*
* is it necessary since the error is catched according to the presence of id ?
* -> i think yes, because we want to know the type of http error, right ?
* -> actually the http error code will be shown in the console anyway, so...
*
if (!response.ok) {
throw new Error('Network response was not ok : ' + orderData.data.status + ' message : ' + orderData.message);
}
*/
if (orderData.id) { if (orderData.id) {
return orderData.id; return orderData.id;
} else { }
else { // throw an error
const errorDetail = orderData?.details?.[0]; const errorDetail = orderData?.details?.[0];
const errorMessage = errorDetail const errorMessage = errorDetail
? `${errorDetail.issue} ${errorDetail.description} (${orderData.debug_id})` ? `${errorDetail.issue} ${errorDetail.description} (${orderData.debug_id})`
: JSON.stringify(orderData); : JSON.stringify(orderData);
throw new Error(errorMessage); throw new Error(errorMessage);
} }
} catch (error) { } catch (error) {
@@ -52,7 +48,7 @@ export async function createOrder() {
* *
// Call your server to set up the transaction // Call your server to set up the transaction
function createOrder(data, actions) { function createOrder(data, actions) {
const fetch_create_url = PLGNTLS_data.fetch_url + "/fipf_plugin/api/v1/orders"; const fetch_create_url = PLGNTLS_data.fetch_url + "/cipf_plugin/api/v1/orders";
console.log("fetch_create_url:", fetch_create_url); console.log("fetch_create_url:", fetch_create_url);
return fetch(fetch_create_url, { return fetch(fetch_create_url, {
method: 'post' method: 'post'

View File

@@ -0,0 +1,58 @@
import { resultMessage } from './result_message.js';
import { PLGNTLS_fetch } from '../../utils/plgntls_fetch.js';
/*
* @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend
*
*/
export async function onApprove(data, actions) {
try {
const fetch_approve_url = PLGNTLS_data.fetch_url + "/cipf_plugin/api/v1/orders/" + data.orderID + "/capture";
const response = await PLGNTLS_fetch('/cipf_plugin/api/v1/orders/' + data.orderID + '/capture', {
method: "POST",
headers: {
"Content-Type": "application/json",
},
});
const orderData = await response.json();
// Three cases to handle:
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
// (2) Other non-recoverable errors -> Show a failure message
// (3) Successful transaction -> Show confirmation or thank you message
const errorDetail = orderData?.details?.[0];
if (errorDetail?.issue === "INSTRUMENT_DECLINED") {
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
// recoverable state, per https://developer.paypal.com/docs/checkout/standard/customize/handle-funding-failures/
return actions.restart();
}
else if (errorDetail) {
// (2) Other non-recoverable errors -> Show a failure message
throw new Error(`${errorDetail.description} (${orderData.debug_id})`);
}
else if (!orderData.purchase_units) {
throw new Error(JSON.stringify(orderData));
}
else {
// (3) Successful transaction -> Show confirmation or thank you message
// Or go to another URL: actions.redirect('thank_you.html');
const transaction =
orderData?.purchase_units?.[0]?.payments?.captures?.[0] ||
orderData?.purchase_units?.[0]?.payments?.authorizations?.[0];
// to show a message on page
//resultMessage(`Transaction ${transaction.status}: ${transaction.id}<br><br>See console for all available details`);
resultMessage(eval(PLGNTLS_data.paypal_message_success));
actions.redirect(PLGNTLS_data.paypal_redirection_success);
}
} catch (error) {
console.error(error);
//resultMessage(`Sorry, your transaction could not be processed...<br><br>${error}`);
resultMessage(eval(PLGNTLS_data.paypal_message_failure));
actions.redirect(PLGNTLS_data.paypal_redirection_failure);
}
}

View File

@@ -2,6 +2,8 @@
// Example function to show a result to the user. Your site's UI library can be used instead. // Example function to show a result to the user. Your site's UI library can be used instead.
//function resultMessage(message) { //function resultMessage(message) {
export function resultMessage(message) { export function resultMessage(message) {
const buttons = document.querySelector("#paypal-button-container");
const container = document.querySelector("#result-message"); const container = document.querySelector("#result-message");
buttons.style.display = 'none';
container.innerHTML = message; container.innerHTML = message;
} }

View File

@@ -1,14 +1,37 @@
<?php <?php
/** /*
* it means someone outside wp is accessing the file, in this case kill it. * it means someone outside wp is accessing the file, in this case kill it.
*/ */
if (!defined('ABSPATH')) { if (!defined('ABSPATH')) {
die('You can not access this file!'); die('You can not access this file!');
} }
function fipfcard_plugin_content() {
$fipfcard = new PLGNTLS_class();
/*
* menu plugin
*/
function cipfcard_plugin_menu() {
PLGNTLS_class::debug_infos();
add_menu_page
(
'cipf_card', // webpage title
'cipf_card', // menu title
'manage_options', // capability
'cipfcard-plugin', // menu_slug
'cipfcard_plugin_content' // callback function to display page content
);
}
add_action('admin_menu', 'cipfcard_plugin_menu');
function cipfcard_plugin_content() {
PLGNTLS_class::debug_infos();
$cipfcard = new PLGNTLS_class();
$my_css = ' $my_css = '
#mytext { #mytext {
@@ -18,7 +41,7 @@ function fipfcard_plugin_content() {
background-color: lightgreen; background-color: lightgreen;
} }
'; ';
echo $fipfcard->add_to_front( array( echo $cipfcard->add_to_front( array(
array("js/menu/example_menu.js", 'type'=>'module'), array("js/menu/example_menu.js", 'type'=>'module'),
"css/menu/menu.css", "css/menu/menu.css",
"PLGNTLS_menu_css" => array('css'=>$my_css), "PLGNTLS_menu_css" => array('css'=>$my_css),
@@ -38,17 +61,17 @@ ajax
- to access the content of the data object properties of the ajax call : - to access the content of the data object properties of the ajax call :
use $_POST['property_name'] use $_POST['property_name']
*/ */
function fipfcard_menu_fetch_handler() function cipfcard_menu_fetch_handler() {
{ PLGNTLS_class::debug_infos();
return new WP_REST_Response('hello', 200); return new WP_REST_Response('hello', 200);
} }
function fipfcard_menu_endpoint() function cipfcard_menu_endpoint() {
{ PLGNTLS_class::debug_infos();
register_rest_route('plgntls', '/get_data', array( register_rest_route('plgntls', '/get_data', array(
'methods' => 'POST', 'methods' => 'POST',
'callback' => 'fipfcard_menu_fetch_handler', 'callback' => 'cipfcard_menu_fetch_handler',
)); ));
}; };
add_action('rest_api_init', 'fipfcard_menu_endpoint'); add_action('rest_api_init', 'cipfcard_menu_endpoint');
?> ?>

View File

@@ -0,0 +1,207 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
* custom action in php on custom form submission
* custom forms are not processed by divi form builder
* so they don't change between hooks before and after process
*
*/
function admin_validate_prof_CIPF() {
PLGNTLS_class::debug_infos();
}
/*
* calling the action to validate from the FormBuilder hook
*
*/
function custom_form_admin_validate_prof_CIPF($form_id, $post_array, $form_type) {
PLGNTLS_class::debug_infos();
$admin_validate_prof_field = PLGNTLS_class::ADMIN_VALIDATE_PROF_FIELD;
if ($form_type !== 'custom')
return;
error_log("---");
error_log("in test_form_CIPF");
// error_log("form_id");
// error_log(json_encode($form_id));
// error_log("post_array");
// error_log(json_encode($post_array));
// error_log("form_type");
// error_log(json_encode($form_type));
$field_id = $post_array['field_id'];
$contains_id = in_array($admin_validate_prof_field, $field_id);
if ($contains_id === false)
return;
admin_validate_prof_CIPF();
}
add_action('df_before_process', 'custom_form_admin_validate_prof_CIPF', 10, 3);
/*
* calling the action to validate from the
*
function custom_link_intercept() {
PLGNTLS_class::debug_infos();
$query_page_redirection = PLGNTLS_class::QUERY_REDIRECTION_PROFIL;
// Check if the request contains ?QUERY_REDIRECTION_PROFIL
if(isset($_GET[$query_page_redirection])) {
admin_validate_prof_CIPF();
}
}
add_action('init', 'custom_link_intercept');
*/
/*
before :
in test_form_CIPF
form_id
""
post_array
{"field_title":["\u00c9tat du compte"],"field_name":["de_fb_compte-actif"],"field_id":["de_fb_field_1"],"form_type_confirm":""}
form_type
"custom"
---
after :
in test_form_CIPF
form_id
""
post_array
{"field_title":["\u00c9tat du compte"],"field_name":["de_fb_compte-actif"],"field_id":["de_fb_field_1"],"form_type_confirm":""}
form_type
"custom"
---
exploded view :
{
"field_title":["\u00c9tat du compte"],
"field_name":["de_fb_compte-actif"],
"field_id":["de_fb_field_1"],
"form_type_confirm":""
}
{
"field_title":["\u00c9tat du compte"],
"field_name":["de_fb_compte-actif"],
"field_id":["de_fb_field_1"],
"compte-actif":"Actif",
"form_type_confirm":""
}
CIPF_admin_activation_prof
{
"field_title":["\u00c9tat du compte"],
"field_name":["compte-actif"],
"field_id":["cipf_admin_activation_prof"],
"compte-actif":"Inactif",
"form_type_confirm":""
}
--- with field test :
{
"field_title":["\u00c9tat du compte","test"],
"field_name":["compte-actif","de_fb_field_3"],
"field_id":["cipf_admin_activation_prof","de_fb_field_3"],
"field_3":"",
"form_type_confirm":""
}
*/
/*
* ABORTED
* tried to receive the form in ajax from front with wp REST API
* but I cannot verify if the user is logged in
* so it does not work
*
function admin_validate_prof_form_CIPF($request) {
PLGNTLS_class::debug_infos();
$slug_page_redirection = PLGNTLS_class::SLUG_PAGE_REDIRECTION;
error_log("-----");
error_log("inside admin_validate_prof_form_CIPF");
error_log("request");
error_log(json_encode($request));
error_log("_POST");
error_log(json_encode($_POST));
// _POST : {"field_title":["\u00c9tat du compte"],"field_name":["compte-actif"],"field_id":["cipf_admin_activate_prof"],"form_key":"40781-1","unique_id":"91eed9aa-2b92-4da7-a0b4-e94f24515223","form_type":"custom","divi-form-submit":"yes","form_id":"","form_type_confirm":""}
// Set up nocache headers before redirecting : https://developer.wordpress.org/reference/functions/wp_safe_redirect/#user-contributed-notes
nocache_headers();
$redirect_url = home_url() . '/' . $slug_page_redirection;
wp_redirect($redirect_url, 301);
exit;
}
function endpoint_form_admin_activate_prof_CIPF() {
PLGNTLS_class::debug_infos();
$base_rest_route = PLGNTLS_class::URL_BASE_REST_ROUTE;
register_rest_route($base_rest_route, '/admin_prof_activate_form', array(
'methods' => 'POST',
'callback' => 'admin_validate_prof_form_CIPF',
));
};
add_action('rest_api_init', 'endpoint_form_admin_activate_prof_CIPF');
*/
/*
* ABORTED
* enqueue script that should prevent the form to submit, but does not work
*
function admin_validate_prof_prevent_CIPF() {
PLGNTLS_class::debug_infos();
$handle = 'admin_prevent_submit';
$url = PLGNTLS_class::root_url() . 'js/admin_prevent_submit.js';
$dependencies = array();
$version = null;
$defer = true;
wp_enqueue_script($handle, $url, $dependencies, $version, $defer);
}
add_action('wp_enqueue_scripts', 'admin_validate_prof_prevent_CIPF');
*/
?>

View File

@@ -0,0 +1,54 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
function restrict_author_page_CIPF() {
PLGNTLS_class::debug_infos();
$role_fipf = PLGNTLS_class::ROLE_FIPF;
$role_admin = PLGNTLS_class::ROLE_ADMIN;
if (!is_author())
return;
$current_user = wp_get_current_user();
/*
* check multiple user roles
* https://developer.wordpress.org/reference/functions/current_user_can/#div-comment-4083
* if user->role is found in array of allowed role, no redirection needed
*
*/
$allowed_roles = array($role_admin, $role_fipf);
if (array_intersect($allowed_roles, $current_user->roles))
return;
/*
* get_queried_object_id() would work too
* here get_the_author_meta works and is more explicit
*
$author_id = get_queried_object_id();
*/
$author_id = get_the_author_meta( 'ID' );
$current_user_id = get_current_user_id();
if ($current_user_id != $author_id) {
// Set up nocache headers before redirecting : https://developer.wordpress.org/reference/functions/wp_safe_redirect/#user-contributed-notes
nocache_headers();
wp_redirect(home_url(), 301);
exit;
}
}
add_action('template_redirect', 'restrict_author_page_CIPF', 10);
?>

View File

@@ -0,0 +1,140 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
include_once(PLGNTLS_class::root_path() . 'php/format_user_infos.php');
/*
* callback to provide the user info corresponding to the $$key_word$$
*
*/
function replace_words_CIPF($matches, $user_id = null) {
PLGNTLS_class::debug_infos();
if ($user_id !== null) {
$current_user = get_user_by('id', $user_id);
}
else if (is_user_logged_in()) {
$current_user = wp_get_current_user();
$user_id = get_current_user_id();
}
else {
return "";
}
if ($current_user === false)
return "";
$query = $matches[1];
$result = format_user_info_CIPF($query, $current_user, $user_id);
/*
* if result is array, take the first element (not ideal)
*
*/
if (is_array($result))
$result = reset($result);
/*
* if is special query __author_page__
* return author page url
*
*/
if ($query === '__author_page__') {
$current_user_id = get_current_user_id();
$result = get_author_posts_url($current_user_id);
}
/*
* if no match, return $$<query>$$
*
*/
if (empty($result))
return $matches[0];
return $result;
}
/*
* filter emails in the form-builder hook, before the wp_mail hook
* it receives the id of the user, no need to have the user still logged-in
*
*/
function filter_email_fb_CIPF($reply_body, $post_array) {
PLGNTLS_class::debug_infos();
$id = $post_array['ID'];
// pattern : anything surrounded by '$$', ex : $$value$$
$pattern = '/\$\$(.*?)\$\$/';
// inline callback, with 'use' to get the id
$new_body = preg_replace_callback($pattern, function($matches) use ($id) {
return replace_words_CIPF($matches, $id);
}, $reply_body);
return $new_body;
}
add_filter('df_confirmation_body', 'filter_email_fb_CIPF', 10, 2); // the receive an email
add_filter('df_notification_body', 'filter_email_fb_CIPF', 10, 2); // the admin receive a notification
/*
* filter emails at the final point : the wp_mail hook
* it uses a callback that rely on the logged-in user
* it will works well most of the time, but it's possible
* that a user logged out before the email is sent
* or event that a different user has already logged in
*/
function filter_email_wp_CIPF($args) {
PLGNTLS_class::debug_infos();
// pattern : anything surrounded by '$$', ex : $$value$$
$pattern = '/\$\$(.*?)\$\$/';
$old_body = $args['message'];
$new_body = preg_replace_callback($pattern, 'replace_words_CIPF', $old_body);
$args['message'] = $new_body;
return $args;
}
add_filter('wp_mail', 'filter_email_wp_CIPF', 10, 1);
/*
all filters in form_builder :
1 $body = apply_filters( 'df_notification_body', $body, $post_array );
2 $email = apply_filters( 'df_notifcation_recipient', $email, $form_id, $post_array );
3 $title = apply_filters( 'wpml_translate_single_string', $title_get, 'divi-form-builder', 'Edit Post Button Title Text' );
4 $body = apply_filters( 'df_contact_body', $body, $post_array );
5 $body = apply_filters( 'df_contact_body', $body, $post_array );
6 $email = apply_filters( 'df_contact_recipient', $email, $form_id, $post_array );
7 $email = apply_filters( 'df_contact_recipient', $email, $form_id, $processed_post_array );
8 $reply_body = apply_filters( 'df_confirmation_body', $reply_body, $post_array );
9 $reply_body = apply_filters( 'df_confirmation_body', $reply_body, $post_array );
10 $reply_body = apply_filters( 'df_confirmation_body', $reply_body, $post_array );
11 $reply_body = apply_filters( 'df_confirmation_body', $reply_body, $post_array );
12 $message_content = apply_filters( 'the_content', get_post_field( 'post_content', $message_array['layout'] ) );
13 $content = apply_filters( 'the_content', get_post_field( 'post_content', $message_array['layout'] ) );
14 $content = apply_filters( 'the_content', get_post_field( 'post_content', $html_content_divi_layout) );
*/
?>

View File

@@ -0,0 +1,27 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
*/
function add_form_calculation_patch_CIPF() {
PLGNTLS_class::debug_infos();
$handle = 'form_calculation_patch';
$url = PLGNTLS_class::root_url() . 'js/form_builder_patch/form_calculation.js';
$dependencies = array('de_fb_calc');
$version = null;
$defer = true;
wp_enqueue_script( $handle, $url, $dependencies, $version, $defer);
}
add_action('wp_enqueue_scripts', 'add_form_calculation_patch_CIPF', 999);
?>

View File

@@ -0,0 +1,24 @@
<?php
/**
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
function test_modal_PLGNTLS() {
PLGNTLS_class::debug_infos();
$cipf_modal = new PLGNTLS_class();
$cipf_modal->add_to_front(
array(
'js/form_builder_patch/multiple_modals.js',
));
}
add_shortcode('test_modal', 'test_modal_PLGNTLS');
?>

View File

@@ -1,12 +1,13 @@
<?php <?php
/*
Plugin Name: formbuilder url patch /**
Plugin URI: * it means someone outside wp is accessing the file, in this case kill it.
Description: */
Author: hugogogo if (!defined('ABSPATH')) {
Version: 1.1.0 die('You can not access this file!');
Author URI: }
*/
/** /**
* in `wp-content/plugins/divi-form-builder/includes/DiviFormBuilder.php` * in `wp-content/plugins/divi-form-builder/includes/DiviFormBuilder.php`
@@ -14,15 +15,17 @@ Author URI:
* - Undefined variable: min_length in /var/www/html/wp-content/plugins/divi-form-builder/includes/modules/FormField/FormField.php on line 5933 * - Undefined variable: min_length in /var/www/html/wp-content/plugins/divi-form-builder/includes/modules/FormField/FormField.php on line 5933
* - Undefined variable: use_icon in /var/www/html/wp-content/plugins/divi-form-builder/includes/modules/FormField/FormField.php on line 5984 * - Undefined variable: use_icon in /var/www/html/wp-content/plugins/divi-form-builder/includes/modules/FormField/FormField.php on line 5984
*/ */
function add_my_jquery_patch() function add_my_jquery_patch() {
{ PLGNTLS_class::debug_infos();
$handle = 'jquery_validator_url_patch'; $handle = 'jquery_validator_url_patch';
$url = plugin_dir_url(__FILE__) . 'jquery_validator_url_patch.js'; $url = PLGNTLS_class::root_url() . 'js/form_builder_patch/url_validation.js';
$dependencies = array('de_fb_validate'); $dependencies = array('de_fb_validate');
$version = ''; $version = null;
$defer = true; $defer = true;
wp_enqueue_script( $handle, $url, $dependencies, $version, $defer); wp_enqueue_script( $handle, $url, $dependencies, $version, $defer);
} }
add_action('wp_enqueue_scripts', 'add_my_jquery_patch'); add_action('wp_enqueue_scripts', 'add_my_jquery_patch');
?> ?>

View File

@@ -0,0 +1,92 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
function format_user_info_CIPF($query, &$current_user, $user_id) {
PLGNTLS_class::debug_infos();
$output_date_format = PLGNTLS_class::USER_INFO_DATE_FORMAT;
$is_acf = false;
$is_date = false;
/*
* check if it's an acf field
* first method : check if _field exist
*
$_acf_field = '_'.$query;
$acf_field = $current_user->$_acf_field;
if (!empty($acf_field))
$is_acf = true;
*/
/*
* check if it's an acf field, and a date
* second method : check what get_field_object() returns
*
*/
$acf_id = 'user_'.$user_id;
$acf_object = get_field_object($query, $acf_id);
if ($acf_object !== false)
$is_acf = true;
/*
* if is acf, use the acf return format
* otherwise, use the default wordpress value
*
*/
if ($is_acf)
$output = get_field($query, $acf_id);
else
$output = $current_user->$query;
/*
* check if is date
*
*/
if ($is_acf) {
$acf_type = $acf_object['type'];
if ($acf_type && $acf_type === "date_picker")
$is_date = true;
}
/*
* if is date, transform format
*
*/
if ($is_date) {
$acf_date_string = $acf_object['value'];
$acf_date_format = $acf_object['return_format'];
$date = date_create_from_format($acf_date_format, $acf_date_string);
$output = $date->format($output_date_format);
}
/*
* return the result
*
*/
while (is_array($output) && count($output) === 1)
$output = reset($output);
if (is_array($output) && count($output) === 0)
$output = '';
if (!is_string($output))
$output = json_encode($output, JSON_UNESCAPED_SLASHES);
return esc_html($output);
}
?>

View File

@@ -0,0 +1,28 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
* hide admin bar if access a front page and is not an admin
*/
function hide_admin_bar_CIPF() {
PLGNTLS_class::debug_infos();
$role_admin = PLGNTLS_class::ROLE_ADMIN;
if (!current_user_can($role_admin) && !is_admin()) {
show_admin_bar(false);
}
}
add_action('after_setup_theme', 'hide_admin_bar_CIPF');
?>

View File

@@ -0,0 +1,44 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
* menu deconnexion
* 1. il faut creer un menu personalisé dans Apparence > Menus
* 2. dans le code ci-dessous, changer la valeur de $menu_title pour correspondre au titre du menu
* 3. et si besoin changer la valeur de $menu_redirect pour choisir la page de redirection :
* - si laissée vide, la redirection se fera sur la page de connexion de wordpress
* - avec $current_url la redirection se fera sur la page actuelle
* - avec $base_url on redirige vers la page d'accueil du site (l'url sans chemin supplementaire)
* cette variable $base_url peut etre utilisee pour construire une autre url :
* - $menu_redirect = $base_url -> https://le_site_actuel.com/
* - $menu_redirect = $base_url . 'contact' -> https://le_site_actuel.com/contact
* - $menu_redirect = $current_url -> https://le_site_actuel.com/la_meme_page
* - $menu_redirect = 'www.un_autre_site.net/contact' -> https://www.un_autre_site.net/contact
*/
function change_menu_logout($items){
PLGNTLS_class::debug_infos();
$menu_title = 'special logout';
// quelques urls utiles :
$base_url = home_url();
$current_url = home_url( $_SERVER['REQUEST_URI'] );
$menu_redirect = '';
foreach($items as $item){
if( $item->title === $menu_title){
$item->url = wp_nonce_url( wp_logout_url( $menu_redirect ), 'log-out' );
}
}
return $items;
}
add_filter('wp_nav_menu_objects', 'change_menu_logout');
?>

View File

@@ -0,0 +1,125 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
* series of actions to do before printing a partner author page
*
function check_partner_page_CIPF() {
PLGNTLS_class::debug_infos();
// the way to find the id of the author of an author_page
$author_id = get_queried_object_id();
}
add_action('template_redirect', 'check_partner_page_CIPF', 11);
*/
/*
in test_partner_CIPF
form_id
"crea_partenaire"
post_array
{
"post_status":"publish",
"field_title":[
"Nom commercial",
"Votre site Internet",
"Dans quelle rubrique devez-vous para\u00eetre ? ",
"L\\'accroche en t\u00eate de page",
"Pr\u00e9sentez-vous",
"Votre logo ",
"Image principale",
"Voulez-vous afficher cette offre ?",
"Titre",
"Texte de l\\'offre",
"Image (facultatif)",
"Voulez-vous ajouter une offre ?",
"Voulez-vous afficher cette offre ?",
"Titre",
"Texte de l\\'offre",
"Image (facultatif)",
"Voulez-vous ajouter une offre ?",
"Voulez-vous afficher l\\'offre ?",
"Titre",
"Texte de l\\'offre",
"Image (facultatif)",
"slug"
],
"post_title":"test page partner",
"meta_input":[
"de_fb_url_partenaire",
"de_fb_logo_partenaire",
"de_fb_afficher_offre_1",
"de_fb_offre_1_titre",
"de_fb_offre_1_txt",
"de_fb_offre_1_image",
"de_fb_ajouter_offre_2",
"de_fb_afficher_offre_2",
"de_fb_offre_2_titre",
"de_fb_offre_2_txt",
"de_fb_offre_2_image",
"de_fb_ajouter_offre_3",
"de_fb_afficher_offre_3",
"de_fb_offre_3_titre",
"de_fb_offre_3_txt",
"de_fb_offre_3_image"
],
"url_partenaire":"",
"tax_input":["de_fb_category"],
"category":"autres",
"post_excerpt":"accroche test page partner",
"post_content":"presentation test page partner",
"_ajax_linking_nonce":"2088c0ea4f",
"logo_partenaire":"40763",
"post_thumbnail":"40764",
"afficher_offre_1":"Afficher",
"offre_1_titre":"titre offre 1",
"offre_1_txt":"text offre 1",
"offre_1_image":"",
"ajouter_offre_2":"Oui",
"afficher_offre_2":"Masquer",
"offre_2_titre":"titre offre 2",
"offre_2_txt":"text offre 2",
"offre_2_image":"",
"ajouter_offre_3":"Oui",
"afficher_offre_3":"Afficher",
"offre_3_titre":"titre offre 3",
"offre_3_txt":"text offre 3",
"offre_3_image":"",
"post_name":"test-page-partner",
"ID":"40765",
"form_type_confirm":""
}
form_type
"post"
function test_partner_CIPF($form_id, $post_array) {
error_log("---");
error_log("in test_partner_CIPF");
error_log("form_id");
error_log(json_encode($form_id));
error_log("post_array");
error_log(json_encode($post_array));
}
add_action( 'df_before_process', 'test_partner_CIPF', 10, 2);
add_action( 'df_after_process', 'test_partner_CIPF', 10, 2);
*/
?>

View File

@@ -0,0 +1,26 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
include_once(PLGNTLS_class::root_path() . '/php/utils/http_errors.php');
include_once(PLGNTLS_class::root_path() . '/php/paypal/route_api_utils.php');
include_once(PLGNTLS_class::root_path() . '/php/paypal/user_can_pay.php');
include_once(PLGNTLS_class::root_path() . '/php/paypal/update_user_payment.php');
include_once(PLGNTLS_class::root_path() . '/php/paypal/shortcode.php');
include_once(PLGNTLS_class::root_path() . '/php/paypal/route_api_orders.php');
include_once(PLGNTLS_class::root_path() . '/php/paypal/route_api_orders_capture.php');
include_once(PLGNTLS_class::root_path() . '/php/paypal/routes.php');
?>

View File

@@ -0,0 +1,147 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
* this function runs before the paiement, it initiate the order
* @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend
*
* in this function and the insides functions,
* explicit errors are thrown with HttpException,
* otherwise it's an unexpected error to catch with Exception
*
*/
function handle_orders_request_CIPF($request_data) {
PLGNTLS_class::debug_infos();
// declaring outside the try..catch scope
$order_response = array();
/*
* - check if user can pay, according to conditions
* - process the order and get the response
* if it fails here : the order was not created
*
*/
try {
$can_pay = check_can_pay_CIPF();
if (is_wp_error($can_pay))
throw new HttpException('not allowed to pay : ' . $can_pay->get_error_message(), 403);
$order_response = create_order_CIPF();
$json_response = $order_response['json_response'];
$http_status_code = $order_response['http_status_code'];
}
catch (HttpException $error) {
$status_code = $error->getStatusCode();
$message = 'Failed to create order in server :' . $error->getMessage();
return new WP_REST_Response($message, $status_code);
}
catch (Exception $error) {
$message = 'Failed to create order in server :' . $error->getMessage();
return new WP_REST_Response($message, 500);
}
/*
* - add infos of the initiated order into user profil
* - return the created order to the front
* if it fails here : the order was created in paypal
* but a pbm occured in treating it with the user
*
*/
try {
update_user_pre_order_CIPF($json_response, 'start');
/*
* https://developer.wordpress.org/reference/classes/wp_rest_response/
* extends from https://developer.wordpress.org/reference/classes/wp_http_response/
* __construct( $data = null, $status = 200, $headers = array() )
*
*/
return new WP_REST_Response($json_response, $http_status_code);
}
catch (HttpException $error) {
$status_code = $error->getStatusCode();
$message = 'Order created, but failed in treatment :' . $error->getMessage();
return new WP_REST_Response($message, $status_code);
}
catch (Exception $error) {
$message = 'Order created, but failed in treatment :' . $error->getMessage();
return new WP_REST_Response($message, 500);
}
}
/*
* Create an order to start the transaction.
* @see https://developer.paypal.com/docs/api/orders/v2/#orders_create
*
*/
function create_order_CIPF() {
PLGNTLS_class::debug_infos();
$paypal_api_base_url = PLGNTLS_class::PAYPAL_API_BASE_URL;
$access_token = generate_access_token_CIPF();
$user_id = get_current_user_id();
$acf_id = 'user_' . $user_id;
$price = get_field('somme_a_regler', $acf_id);
$url = $paypal_api_base_url . '/v2/checkout/orders';
$payload = array(
'intent' => "CAPTURE",
'purchase_units' => array(
array(
'amount' => array(
'currency_code' => "EUR",
'value' => $price,
),
),
),
);
$headers = array(
"Content-Type: application/json",
"Authorization: Bearer " . $access_token
// Uncomment one of these to force an error for negative testing (in sandbox mode only). Documentation:
// https://developer.paypal.com/tools/sandbox/negative-testing/request-headers/
// "PayPal-Mock-Response": '{"mock_application_codes": "MISSING_REQUIRED_PARAMETER"}'
// "PayPal-Mock-Response": '{"mock_application_codes": "PERMISSION_DENIED"}'
// "PayPal-Mock-Response": '{"mock_application_codes": "INTERNAL_SERVER_ERROR"}'
);
// Initialize cURL session
$ch = curl_init();
// Set cURL options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Execute cURL session and get the response
$response_json = curl_exec($ch);
// in utils
$response = handle_json_response_CIPF($response_json, $ch);
// Close cURL session
curl_close($ch);
return $response;
};
?>

View File

@@ -0,0 +1,114 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
function handle_orders_capture_request_CIPF($request) {
PLGNTLS_class::debug_infos();
$order_id = $request['orderID'];
// declaring outside the try..catch scope
$response_json = array();
/*
* ask paypal about the finished order
*
*/
try {
$response_json = capture_order_cipf($order_id);
$http_status_code = $response_json['http_status_code'];
$json_response = $response_json['json_response'];
}
catch (HttpException $error) {
$status_code = $error->getStatusCode();
$message = 'Failed to capture order in server :' . $error->getMessage();
return new WP_REST_Response($message, $status_code);
}
catch (Exception $error) {
$message = 'Failed to capture order in server : ' . $error->getMessage();
return new WP_REST_Response($message, 500);
}
/*
* update the client situation
* and return the response of paypal
*
* capture status : https://developer.paypal.com/docs/api/orders/v2/#definition-order_status
* - COMPLETED
* - DECLINED
* - PARTIALLY_REFUNDED
* - PENDING
* - REFUNDED
* - FAILED
*
*/
try {
update_user_post_capture_CIPF($json_response, 'end');
return new WP_REST_Response($json_response, $http_status_code);
}
catch (HttpException $error) {
$status_code = $error->getStatusCode();
$message = 'Failed to handle order after capture in server :' . $error->getMessage();
return new WP_REST_Response($message, $status_code);
}
catch (Exception $error) {
$message = 'Failed to handle order after capture in server :' . $error->getMessage();
return new WP_REST_Response($message, 500);
}
}
/**
* Capture payment for the created order to complete the transaction.
* @see https://developer.paypal.com/docs/api/orders/v2/#orders_capture
*/
function capture_order_CIPF($order_id) {
PLGNTLS_class::debug_infos();
$paypal_api_base_url = PLGNTLS_class::PAYPAL_API_BASE_URL;
$access_token = generate_access_token_CIPF();
$url = $paypal_api_base_url . '/v2/checkout/orders/' . $order_id . '/capture';
$headers = array(
"Content-Type: application/json",
"Authorization: Bearer " . $access_token
// Uncomment one of these to force an error for negative testing (in sandbox mode only). Documentation:
// https://developer.paypal.com/tools/sandbox/negative-testing/request-headers/
// 'PayPal-Mock-Response: {"mock_application_codes": "INSTRUMENT_DECLINED"}',
// 'PayPal-Mock-Response: {"mock_application_codes": "TRANSACTION_REFUSED"}',
// 'PayPal-Mock-Response: {"mock_application_codes": "INTERNAL_SERVER_ERROR"}'
);
// Initialize cURL session
$ch = curl_init();
// Set cURL options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Execute cURL session and get the response
$response_json = curl_exec($ch);
// in utils
$response = handle_json_response_CIPF($response_json, $ch);
// Close cURL session
curl_close($ch);
return $response;
};
?>

View File

@@ -0,0 +1,129 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
* @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend
*
*/
function handle_json_response_CIPF($response, $ch) {
PLGNTLS_class::debug_infos();
if ($response === false)
throw new HttpException('cURL error: ' . curl_error($ch), 502);
// Decode JSON response
$json_response = json_decode($response);
// https://stackoverflow.com/questions/2348152/detect-bad-json-data-in-php-json-decode
if ($json_response === null && json_last_error() !== JSON_ERROR_NONE) {
throw new HttpException('JSON decoding error: ' . json_last_error_msg(), 502);
}
// Return response data along with HTTP status code
return array(
'json_response' => $json_response,
'http_status_code' => curl_getinfo($ch, CURLINFO_HTTP_CODE),
);
}
function handle_response_CIPF($response) {
PLGNTLS_class::debug_infos();
try
{
// Decode JSON response
$json_response = json_decode($response);
return array(
'json_response' => $json_response,
'http_status_code' => http_response_code()
);
}
catch (Exception $err)
{
// Get error message from response
$error_message = $response->text();
throw new Exception($error_message);
}
}
/**
* Generate an OAuth 2.0 access token for authenticating with PayPal REST APIs.
* @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend
* @see https://developer.paypal.com/api/rest/authentication/
*/
function generate_access_token_CIPF() {
PLGNTLS_class::debug_infos();
$paypal_client_id = PLGNTLS_class::PAYPAL_CLIENT_ID;
$paypal_client_secret = PLGNTLS_class::PAYPAL_CLIENT_SECRET;
$paypal_api_base_url = PLGNTLS_class::PAYPAL_API_BASE_URL;
/*
try
{
*/
if ( !$paypal_client_id || !$paypal_client_secret ) {
throw new HttpException("MISSING_API_CREDENTIALS", 403);
}
$credentials = $paypal_client_id . ":" . $paypal_client_secret;
$auth = base64_encode($credentials);
$url = $paypal_api_base_url . '/v1/oauth2/token';
$body = http_build_query(array('grant_type' => 'client_credentials'));
// Initialize curl
$ch = curl_init();
// Set curl options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: Basic ' . $auth,
));
/********************/
// Execute cURL session and get the response
$data_json = curl_exec($ch);
// in utils
$data = handle_json_response_CIPF($data_json, $ch);
// Close cURL session
curl_close($ch);
return $data['json_response']->access_token;
/********************/
/*
// Execute curl and get the response
$data_json = curl_exec($ch);
if ( $data_json === false)
throw new Exception('cURL error: ' . curl_error($ch));
// Close curl
curl_close($ch);
$data = json_decode($data_json);
return $data->access_token;
}
catch (Exception $error)
{
error_log("Failed to generate Access Token:");
error_log($error->getMessage());
}
*/
};
?>

View File

@@ -0,0 +1,31 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
// handling routes and endpoints
// diff routes and endpoints : https://stackoverflow.com/q/56075017/9497573
function routes_endpoints_CIPF() {
PLGNTLS_class::debug_infos();
$base_rest_route = PLGNTLS_class::URL_BASE_REST_ROUTE;
register_rest_route($base_rest_route, '/orders', array(
'methods' => 'POST',
'callback' => 'handle_orders_request_CIPF',
));
register_rest_route($base_rest_route, '/orders/(?P<orderID>[a-zA-Z0-9]+)/capture', array(
'methods' => 'POST',
'callback' => 'handle_orders_capture_request_CIPF',
));
};
add_action('rest_api_init', 'routes_endpoints_CIPF');
?>

View File

@@ -0,0 +1,64 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/**
* call to paypal_shortcode_content()
*/
function paypal_shortcode_content_CIPF() {
PLGNTLS_class::debug_infos();
$slug_paypal_redirection_success = PLGNTLS_class::SLUG_PAYPAL_REDIRECTION_SUCCESS;
$slug_paypal_redirection_failure = PLGNTLS_class::SLUG_PAYPAL_REDIRECTION_FAILURE;
$paypal_client_id = PLGNTLS_class::PAYPAL_CLIENT_ID;
$paypal_message_success = PLGNTLS_class::PAYPAL_MESSAGE_SUCCESS;
$paypal_message_failure = PLGNTLS_class::PAYPAL_MESSAGE_FAILURE;
// if (!can_pay_now_CIPF())
// return no_payment_CIPF();
$cipfcard_paypal = new PLGNTLS_class();
$pp_client_id = $paypal_client_id;
$pp_sdk_currency = "EUR";
$pp_sdk_base_url = "https://www.paypal.com";
$pp_sdk_url = "{$pp_sdk_base_url}/sdk/js?client-id={$pp_client_id}&currency={$pp_sdk_currency}";
$paypal_redirection_success = home_url() . '/' . $slug_paypal_redirection_success;
$paypal_redirection_failure = home_url() . '/' . $slug_paypal_redirection_failure;
$added_to_front = $cipfcard_paypal->add_to_front(
array(
$pp_sdk_url,
array("js/paypal/paypal.js", 'type'=>'module'),
"html/paypal/paypal.html",
),
compact (
'paypal_redirection_success',
'paypal_redirection_failure',
'paypal_message_success',
'paypal_message_failure',
),
);
return $added_to_front;
}
add_shortcode('cipf_paypal_shortcode', 'paypal_shortcode_content_CIPF');
function no_payment_CIPF() {
PLGNTLS_class::debug_infos();
return;
}
?>

View File

@@ -0,0 +1,383 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
* see documentation in private 'paypal.md'
* basically it check if the user who initiate the transaction
* is the same that finish it
*
* add_user_meta('user_id', 'cipf_order_id', 'aaaaaa');
* ['aaaaaa']
* add_user_meta('user_id', 'cipf_order_id', 'bbbbbb');
* ['aaaaaa', 'bbbbbb']
* add_user_meta('user_id', 'cipf_order_id', 'bbbbbb');
* ['aaaaaa', 'bbbbbb', 'bbbbbb']
* get_user_meta('user_id', 'cipf_order_id');
* ['aaaaaa', 'bbbbbb', 'bbbbbb']
* $del_ret = delete_user_meta('user_id', 'cipf_order_id', 'bbbbbb');
* ['aaaaaa'] - $del_ret === true
* $del_ret = delete_user_meta('user_id', 'cipf_order_id', 'bbbbbb');
* ['aaaaaa'] - $del_ret === false
*
*/
/*
*
*
*/
function update_user_pre_order_CIPF($message) {
PLGNTLS_class::debug_infos();
$acf_payment_status = PLGNTLS_class::ACF_CARD_PAYMENT_STATE;
$meta_order_id = PLGNTLS_class::META_ORDER_ID;
$order_id = $message->id;
$user_id = get_current_user_id();
$acf_id = 'user_'.$user_id;
/*
* - delete previous order ids
* ->if we are here it's because a new order will try to be created
* - addind order_id to cipf_order_id meta field
*
*/
delete_user_meta($user_id, $meta_order_id);
add_user_meta($user_id, $meta_order_id, $order_id);
/*
* create a meta field to check states of payements on prof author page :
* - 'started' -> at order creation
* - 'success' -> at capture success (on author page, it means success, then make it empty)
* - 'failure' -> at capture failure (on author page, it means failure, then make it empty)
* - 'nothing' -> output nothing on author page
*
*/
update_field($acf_payment_status['_name'], $acf_payment_status['started'], $acf_id);
}
/*
*
*
*/
function update_user_post_capture_CIPF($message) {
PLGNTLS_class::debug_infos();
$order_id = $message->id;
$user_id = get_current_user_id();
$status = null;
if (is_object($message) && isset($message->status))
$status = $message->status;
/*
* capture status : https://developer.paypal.com/docs/api/orders/v2/#definition-order_status
* - COMPLETED
* - DECLINED
* - PARTIALLY_REFUNDED
* - PENDING
* - REFUNDED
* - FAILED
*/
/*
* delete order_id and update user
* -> is it necessary to delete order_id since we delete it when creating a new order ?
* -> it is at least necessary to find the user who did the purchase
*
*/
// find the user containing the order_id and delete this order_id
$user_id_to_update = find_user_with_order_id_CIPF($user_id, $order_id);
if ($user_id_to_update === false)
throw new HttpException('cannot find user with this order_id', 502);
if ($status === 'COMPLETED') {
// proceed to validate payment for user
validate_payment_for_user_CIPF($user_id_to_update, $order_id);
}
else if ($status === 'PENDING') {
// i don't know what to do yet, maybe make more checks and output a message to contact diego ?
// https://developer.paypal.com/docs/api/orders/v2/#definition-capture_status_details
}
else {
failure_payment_for_user_CIPF($user_id_to_update, $order_id, $status);
}
}
/*
* things to do when a payment has failed
* failed payement means order status is not COMPLETED or PENDING
* it can be :
* - DECLINED
* - PARTIALLY_REFUNDED
* - REFUNDED
* - FAILED
* -> capture status : https://developer.paypal.com/docs/api/orders/v2/#definition-order_status
* in any cases, the price was not paid
*
*/
function failure_payment_for_user_CIPF($user_id, $order_id, $status) {
PLGNTLS_class::debug_infos();
$acf_card_state = PLGNTLS_class::ACF_CARD_STATE;
$acf_card_expiration = PLGNTLS_class::ACF_CARD_EXPIRATION;
$card_duration = PLGNTLS_class::CARD_VALIDITY_TIME;
$prof_is_activ = PLGNTLS_class::ACF_PROF_IS_ACTIV;
$acf_payment_status = PLGNTLS_class::ACF_CARD_PAYMENT_STATE;
$meta_order_id = PLGNTLS_class::META_ORDER_ID;
$acf_id = 'user_'.$user_id;
/*
* remove the order_id from user meta
*
*/
delete_user_meta($user_id, $meta_order_id, $order_id);
/*
* change payement status to failed
* - 'started' -> at order creation
* - 'success' -> at capture success (on author page, it means success, then mark it 'nothing')
* - 'failure' -> at capture failure (on author page, it means failure, then mark it 'nothing')
* - 'nothing' -> output nothing on author page
*
*/
update_field($acf_payment_status['_name'], $acf_payment_status['failure'], $acf_id);
/*
* other changes on user :
* - pofil is inactive
*
*/
update_field($prof_is_activ['_name'], $prof_is_activ['inactiv'], $acf_id);
}
/*
* things to do when a payment is a success
*
*/
function validate_payment_for_user_CIPF($user_id, $order_id) {
PLGNTLS_class::debug_infos();
$acf_card_state = PLGNTLS_class::ACF_CARD_STATE;
$acf_card_expiration = PLGNTLS_class::ACF_CARD_EXPIRATION;
$acf_card_number = PLGNTLS_class::ACF_CARD_NUMBER;
$card_duration = PLGNTLS_class::CARD_VALIDITY_TIME;
$prof_is_activ = PLGNTLS_class::ACF_PROF_IS_ACTIV;
$acf_payment_status = PLGNTLS_class::ACF_CARD_PAYMENT_STATE;
$meta_order_id = PLGNTLS_class::META_ORDER_ID;
/*
$acf_cgv = PLGNTLS_class::ACF_PROF_CGV;
$acf_payement = PLGNTLS_class::ACF_CARD_PAYMENT_METHOD;
$acf_delivery = PLGNTLS_class::ACF_CARD_PRICE_DELIVERY;
$acf_price = PLGNTLS_class::ACF_CARD_PRICE_CHOICE;
*/
$acf_id = 'user_'.$user_id;
/*
* remove the order_id from user meta
*
*/
delete_user_meta($user_id, $meta_order_id, $order_id);
/*
* acf uses 'Y-m-d H:i:s' format : https://www.advancedcustomfields.com/resources/date-time-picker/
*
*/
$acf_date_format = 'Y-m-d H:i:s';
$acf_id = 'user_'.$user_id;
$date_now = date_create('today');
/*
* get current date limit
* if no date, use now
* if paste date, use now
*
*/
$current_date_limit_object = get_field_object($acf_card_expiration['_name'], $acf_id);
if ($current_date_limit_object === false) {
$current_date_limit = $date_now;
}
else if (empty($current_date_limit_object['value'])) {
$current_date_limit = $date_now;
}
else
{
$current_date_limit_string = $current_date_limit_object['value'];
$current_format_field = $current_date_limit_object['return_format'];
// compare 2 dates : https://stackoverflow.com/q/8722806/9497573
// also I dont use strtotime to compare 2 ints,
// because i don't know if it will fail one day (2000 bug alike)
$current_date_limit = date_create_from_format($current_format_field, $current_date_limit_string);
$date_diff = date_diff($date_now, $current_date_limit);
$date_is_in_past = $date_diff->format('%R%a') < 0;
if ($date_is_in_past)
$current_date_limit = $date_now;
}
/*
* update date limit validity to add 1 year
*
*/
$date_plus_one_year = $current_date_limit->add(date_interval_create_from_date_string('+'.$card_duration));
update_field($acf_card_expiration['_name'], $date_plus_one_year->format($acf_date_format), $acf_id);
/*
* - if card status is command, create card id
* - make card status to renewal
*/
$card_status = get_field($acf_card_state['_name'], $acf_id);
if ($card_status === $acf_card_state['new']) {
$card_id = $date_now->format('Ymd') . $user_id;
error_log("-------");
error_log("card_id");
error_log($card_id);
update_field($acf_card_number['_name'], $card_id, $acf_id);
}
update_field($acf_card_state['_name'], $acf_card_state['renew'], $acf_id);
/*
* change user :
* - profile is active
* - card state is renewal
* - payement status is success
*
*/
update_field($prof_is_activ['_name'], $prof_is_activ['activ'], $acf_id);
update_field($acf_payment_status['_name'], $acf_payment_status['success'], $acf_id);
/*
* reset some fields for the form to buy the card
* - cgv
* - paiement
* - livraison
* - tarif
*
* could make sense to put it here,
* but actually it needs to be put at begining of form
*
update_field($acf_cgv['_name'] , array(""), 'user_'.$user_id);
update_field($acf_payement['_name'], array(""), 'user_'.$user_id);
update_field($acf_delivery['_name'], array(""), 'user_'.$user_id);
update_field($acf_price['_name'] , array(""), 'user_'.$user_id);
*/
}
/*
* add a schedule event to delete this order_id
* after 3 days ?
* time() + 60 = one minute from now
* time() + MINUTE_IN_SECONDS = one minute from now
* -> https://codex.wordpress.org/Easier_Expression_of_Time_Constants
* -> also strtotime : https://www.php.net/manual/en/function.strtotime.php
*
function schedule_delete_orderid_CIPF($user_id, $order_id)
{
$delay = time() + MINUTE_IN_SECONDS;
wp_schedule_single_event($delay, 'orderid_deletion_event_CIPF', array($user_id, $order_id));
}
*/
/*
* action hook for the scheduled event
* TODO: ne marche pas je ne sais pas pourquoi, pas urgent a resoudre
*
function delete_order_id_later_CIPF($user_id, $order_id)
{
delete_user_meta($user_id, 'cipf_order_id', $order_id);
}
add_action('orderid_deletion_event_CIPF', 'delete_order_id_later_CIPF', 5, 2);
*/
/*
* @return mixed num - user_id
* bool false - if no match found
*
*/
function find_user_with_order_id_CIPF($current_user_id, $order_id) {
PLGNTLS_class::debug_infos();
$meta_order_id = PLGNTLS_class::META_ORDER_ID;
$role_prof = PLGNTLS_class::ROLE_PROF;
$user_metas = get_user_meta($current_user_id, $meta_order_id, false);
if (in_array($order_id, $user_metas)) {
return $current_user_id;
}
/*
* it means the current user didn't have this order_id
* so we look for another user
* https://developer.wordpress.org/reference/classes/WP_User_Query/prepare_query/
*
*/
$users = get_users(array(
'role' => $role_prof,
'meta_key' => $meta_order_id,
'meta_value' => $order_id,
'fields' => 'ID',
));
if (count($users) > 1)
throw new HttpException('multiple users with same order_id', 502);
else if (count($users) === 1)
return reset($users);
return false;
}
/*
* @return mixed num - user_id
* bool false - if no match found
*
*/
function delete_order_id_on_success_CIPF($current_user_id, $order_id) {
PLGNTLS_class::debug_infos();
$meta_order_id = PLGNTLS_class::META_ORDER_ID;
$del_ret = delete_user_meta($current_user_id, $meta_order_id, $order_id);
if ($del_ret === true)
return $current_user_id;
// it means the current user didn't have this order_id
// so we look for another user
$users = get_users();
foreach ($users as $user) {
$user_id = $user->ID;
$del_ret = delete_user_meta($user_id, $meta_order_id, $order_id);
if ($del_ret === true)
return $user_id;
}
return false;
}
?>

View File

@@ -0,0 +1,105 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
* can pay in certain conditions
* @return true / wp_error
*
*/
function check_can_pay_CIPF() {
PLGNTLS_class::debug_infos();
$acf_card_payment_method = PLGNTLS_class::ACF_CARD_PAYMENT_METHOD;
$acf_card_price_choice = PLGNTLS_class::ACF_CARD_PRICE_CHOICE;
$acf_card_price_delivery = PLGNTLS_class::ACF_CARD_PRICE_DELIVERY;
$acf_card_price_total = PLGNTLS_class::ACF_CARD_PRICE_TOTAL;
$acf_card_expiration = PLGNTLS_class::ACF_CARD_EXPIRATION;
$card_renew_period = PLGNTLS_class::CARD_RENEW_PERIOD;
$current_user = wp_get_current_user();
$user_id = get_current_user_id();
$acf_id = 'user_' . $user_id;
/*
* check if payment is virement or immediat
*
$payement = get_field($acf_card_payment_method['_name'], $acf_id);
if (strtolower($payement) === 'virement') {
return false;
}
*/
/*
* calculate price
* update the price even if form builder already did it
* in case it was changed from admin pannel
*
*/
$tarif = (int)get_field($acf_card_price_choice['_name'], $acf_id);
$livraison = (int)get_field($acf_card_price_delivery['_name'], $acf_id);
$price = $tarif + $livraison;
update_field($acf_card_price_total['_name'], $price, $acf_id);
/*
* price is not empty or 0
*
*/
$price = get_field($acf_card_price_total['_name'], $acf_id);
if (empty($price)) {
return new WP_Error('cannot_purchase', "no price selected");
}
if ($price === 0) {
return new WP_Error('cannot_purchase', "price is 0, nothing to purchase");
}
/*
* date validity is empty
* or is paste
* or is less than 1 month
*
$validity_field = get_field_object($acf_card_expiration, $acf_id);
if ($validity_field === false)
return true;
$validity = $validity_field['value'];
$format_field = $validity_field['return_format'];
if (empty($validity))
return true;
$date_validity = date_create_from_format($format_field, $validity);
$date_now = date_create('today');
$diff = date_diff($date_now, $date_validity)->format('%R%a');
if ((int)$diff <= 0) {
// date end of validity in the past
return true;
}
else if ((int)$diff <= $card_renew_period) {
// date expiration is in less that renew period time (ex: 30 days)
return true;
}
else {
// date end of validity is in more than renew perdio (ex: 3 month)
return new WP_Error('cannot_purchase', "it's too soon to renew your card");
}
*/
return true;
}
?>

View File

@@ -0,0 +1,134 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
function handle_prof_is_activ_CIPF($author_id) {
PLGNTLS_class::debug_infos();
$acf_prof_is_activ = PLGNTLS_class::ACF_PROF_IS_ACTIV;
$slug_wait_activation = PLGNTLS_class::SLUG_PROF_INACTIV;
$acf_id = 'user_' . $author_id;
/*
* if prof is activ, do nothing more
*
*/
$is_activ = get_field($acf_prof_is_activ['_name'], $acf_id);
if ($is_activ === $acf_prof_is_activ['activ'])
return;
/*
* else if prof inactiv
* if is admin or other allowed roles, see the page anyway
* no need to handle allowed roles, it's already
* taken care by author_restriction.php
*
*/
$user_id = get_current_user_id();
if ($user_id !== $author_id)
return;
/*
* if prof is activ
* redirect to waiting page
*
*/
$redirection_prof_inactiv = home_url() . '/' . $slug_wait_activation;
// Set up nocache headers before redirecting : https://developer.wordpress.org/reference/functions/wp_safe_redirect/#user-contributed-notes
nocache_headers();
wp_redirect($redirection_prof_inactiv, 301);
exit;
}
/*
* check acf field payment_status
* if field value is 'success'
* - show block 'failure'
* - and update field to 'nothing', so it will not show next time
* if field value is 'failure'
* - show bloc success
* - and update field to 'nothing', so it will not show next time
* if field value is 'nothing'
* - do nothing (keep blocs hidden)
* if field value is 'started'
* - do nothing (keep blocs hidden)
*
* .cipf_prof_paiement_message -> on row, added display none in page css
* #cipf_prof_paiement_reussi -> on row
* #cipf_prof_paiement_echoue -> on row
*
*/
function show_prof_paiement_messages_CIPF($user_id) {
PLGNTLS_class::debug_infos();
$acf_prof_is_activ = PLGNTLS_class::ACF_PROF_IS_ACTIV;
$acf_payment_status = PLGNTLS_class::ACF_CARD_PAYMENT_STATE;
$acf_id = 'user_' . $user_id;
/*
* if prof is inactive, do nothing more
*
*/
$is_activ = get_field($acf_prof_is_activ['_name'], $acf_id);
if (is_null($is_activ))
return;
if (empty($is_activ))
return;
if ($is_activ === $acf_prof_is_activ['activ'])
return;
$cipf_prof_payement = new PLGNTLS_class();
$payement_status = get_field($acf_payment_status['_name'], $acf_id);
if ($payement_status === $acf_payment_status['success']) {
$cipf_prof_payement->add_to_front(array(
array( 'css' => '.cipf_prof_paiement_message#cipf_prof_paiement_reussi {display: block;}' )
));
}
else if ($payement_status === $acf_payment_status['failure']) {
$cipf_prof_payement->add_to_front(array(
array( 'css' => '.cipf_prof_paiement_message#cipf_prof_paiement_echoue {display: block;}' )
));
}
update_field($acf_payment_status['_name'], $acf_payment_status['nothing'], $acf_id);
}
/*
* series of check to do before printing a prof author page
*
*/
function check_prof_page_CIPF() {
PLGNTLS_class::debug_infos();
// is an author page
if (!is_author())
return;
// the way to find the id of the author of an author_page
$author_id = get_queried_object_id();
handle_prof_is_activ_CIPF($author_id);
show_prof_paiement_messages_CIPF($author_id);
}
add_action('template_redirect', 'check_prof_page_CIPF', 11);
?>

View File

@@ -0,0 +1,127 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
* redirect users to profil
* if prof -> author page
* if partenaire -> post page || home page
*/
function redirection_profil_page_CIPF(){
PLGNTLS_class::debug_infos();
$role_prof = PLGNTLS_class::ROLE_PROF;
$role_partner = PLGNTLS_class::ROLE_PARTNER;
$base_url = home_url();
$current_user_id = get_current_user_id();
// Set up nocache headers before redirecting : https://developer.wordpress.org/reference/functions/wp_safe_redirect/#user-contributed-notes
nocache_headers();
if (!is_user_logged_in()) {
wp_redirect($base_url, 301);
exit;
}
if (current_user_can($role_prof)) {
$user_page = get_author_posts_url($current_user_id);
wp_redirect($user_page, 301);
exit;
}
else if (current_user_can($role_partner)) {
$args = array(
'post_type' => 'post',
'author' => $current_user_id,
'posts_per_page' => 1,
);
$posts = get_posts($args);
if (empty($posts))
$redirect_url = $base_url;
else {
$query = reset($posts);
$post_id = $query->ID;
$redirect_url = get_permalink($query->ID);
}
wp_redirect($redirect_url, 301);
exit;
}
else {
wp_redirect($base_url, 301);
exit;
}
exit;
}
/*
* redirects when someone reaches the page with slug defined in SLUG_PAGE_REDIRECTION
*
*/
function redirection_page_CIPF(){
PLGNTLS_class::debug_infos();
$slug_page_redirection = PLGNTLS_class::SLUG_PAGE_REDIRECTION;
if (!is_page($slug_page_redirection))
return;
redirection_profil_page_CIPF();
}
add_action('template_redirect', 'redirection_page_CIPF');
/*
* redirects when someone reaches the page with query ?QUERY_REDIRECTION_PROFIL
*
*/
function redirection_query_CIPF() {
PLGNTLS_class::debug_infos();
$query_redirection = PLGNTLS_class::QUERY_REDIRECTION_PROFIL;
// Check if the request contains ?QUERY_REDIRECTION_PROFIL
if(isset($_GET[$query_redirection])) {
redirection_profil_page_CIPF();
}
}
add_action('init', 'redirection_query_CIPF');
/*
* DOES NOT WORK so far
* because to use is_user_logged_in() in redirection_profil_page_CIPF
* the request should include the X-WP-Nonce header, but it does not
* redirects when someone enter the url or redirection
* /wp-json/cipf_plugin/api/v1/redirection_cipf
*
function endpoint_for_redirection_CIPF() {
PLGNTLS_class::debug_infos();
$slug_page_redirection = PLGNTLS_class::SLUG_PAGE_REDIRECTION;
$base_rest_route = PLGNTLS_class::URL_BASE_REST_ROUTE;
register_rest_route($base_rest_route, '/' . $slug_page_redirection, array(
'methods' => 'GET',
'callback' => 'redirection_profil_page_CIPF',
));
};
add_action('rest_api_init', 'endpoint_for_redirection_CIPF');
*/
?>

View File

@@ -0,0 +1,98 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
* at registration, add role 'partenaire' when page url has path 'creation-du-compte-partenaire'
*
*/
function add_partenaires_CIPF($customer_data){
PLGNTLS_class::debug_infos();
$role_partner = PLGNTLS_class::ROLE_PARTNER;
error_log("----");
error_log("in add_partenaires");
error_log("_POST");
error_log(json_encode($_POST));
error_log("_SERVER");
error_log(json_encode($_SERVER));
$current_url = $_SERVER['HTTP_REFERER']; // not reliable to use referer, TODO: find another solution
$path_brut = parse_url($current_url, PHP_URL_PATH);
$path = trim($path_brut, '/');
if ($path === 'creation-du-compte-partenaire')
$customer_data['role'] = $role_partner;
return $customer_data;
}
add_filter( 'xoo_el_register_new_customer_data', 'add_partenaires_CIPF', 10, 1 );
/*
in add_partenaires
_POST
{
"xoo_el_reg_username":"tistilarde",
"xoo_el_reg_email":"tistilarde@gufum.com",
"xoo_el_reg_pass":"pouetpouet",
"_xoo_el_form":"register",
"xoo_el_redirect":"\/creation-du-compte-partenaire\/",
"action":"xoo_el_form_action",
"display":"popup"
}
_SERVER
{
"SERVER_SOFTWARE":"nginx\/1.20.2",
"REQUEST_URI":"\/wp-admin\/admin-ajax.php",
"USER":"www-data",
"HOME":"\/home\/www-data",
"HTTP_SEC_FETCH_SITE":"same-origin",
"HTTP_SEC_FETCH_MODE":"cors",
"HTTP_SEC_FETCH_DEST":"empty",
"HTTP_COOKIE":"wordpress_test_cookie=WP%20Cookie%20check; wp-postpass_351da2be51e3820c1ef099eec9d2e669=%24P%24BjEiJgHo.cgrpONdnfmxwpIYzraFCP.; mjx.menu=renderer%3ANativeMML%26%3Bsemantics%3Atrue%26%3Bcontext%3ABrowser%26%3Bzoom%3ANone",
"HTTP_REFERER":"https:\/\/local-cipf-plugin.com\/creation-du-compte-partenaire\/",
"HTTP_CONNECTION":"keep-alive",
"HTTP_SEC_GPC":"1",
"HTTP_DNT":"1",
"HTTP_ORIGIN":"https:\/\/local-cipf-plugin.com",
"HTTP_CONTENT_LENGTH":"211",
"HTTP_X_REQUESTED_WITH":"XMLHttpRequest",
"HTTP_CONTENT_TYPE":"application\/x-www-form-urlencoded; charset=UTF-8",
"HTTP_ACCEPT_ENCODING":"gzip, deflate, br",
"HTTP_ACCEPT_LANGUAGE":"en-US,en;q=0.5",
"HTTP_ACCEPT":"*\/*",
"HTTP_USER_AGENT":"Mozilla\/5.0 (X11; Ubuntu; Linux x86_64; rv:123.0) Gecko\/20100101 Firefox\/123.0",
"HTTP_HOST":"local-cipf-plugin.com",
"REDIRECT_STATUS":"200",
"SERVER_NAME":"local-cipf-plugin.com",
"SERVER_PORT":"443",
"SERVER_ADDR":"172.20.0.4",
"REMOTE_PORT":"58976",
"REMOTE_ADDR":"172.20.0.1",
"GATEWAY_INTERFACE":"CGI\/1.1",
"HTTPS":"on",
"REQUEST_SCHEME":"https",
"SERVER_PROTOCOL":"HTTP\/1.1",
"DOCUMENT_ROOT":"\/var\/www\/html",
"DOCUMENT_URI":"\/wp-admin\/admin-ajax.php",
"SCRIPT_NAME":"\/wp-admin\/admin-ajax.php",
"CONTENT_LENGTH":"211",
"CONTENT_TYPE":"application\/x-www-form-urlencoded; charset=UTF-8",
"REQUEST_METHOD":"POST",
"QUERY_STRING":"",
"SCRIPT_FILENAME":"\/var\/www\/html\/wp-admin\/admin-ajax.php",
"FCGI_ROLE":"RESPONDER",
"PHP_SELF":"\/wp-admin\/admin-ajax.php",
"REQUEST_TIME_FLOAT":1710328883.257681,
"REQUEST_TIME":1710328883
}
*/
?>

View File

@@ -0,0 +1,125 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
* on renew page :
* - check restrictions
* - change some acf fields (if access granted)
*
* prevent users to fill the renew form if :
* - they are not prof and logged in,
* - and if their card is not in renewable state
* - except admins and editor
*
*/
function renew_page_restrictions_CIPF(){
PLGNTLS_class::debug_infos();
$slug_renew_card = PLGNTLS_class::SLUG_RENEW_CARD;
$slug_page_redirection = PLGNTLS_class::SLUG_PAGE_REDIRECTION;
$role_prof = PLGNTLS_class::ROLE_PROF;
$role_fipf = PLGNTLS_class::ROLE_FIPF;
$role_admin = PLGNTLS_class::ROLE_ADMIN;
$base_url = home_url();
wp_reset_query();
if (!is_page('commande'))
return;
/*
* is it good ?
* -> dont' redirect if user not logged in, because new users need to acces this page
*
if (!is_user_logged_in()) {
// Set up nocache headers before redirecting : https://developer.wordpress.org/reference/functions/wp_safe_redirect/#user-contributed-notes
nocache_headers();
wp_redirect($base_url, 301);
exit;
}
*/
$current_user_id = get_current_user_id();
$current_user = wp_get_current_user();
$acf_id = 'user_'.$current_user_id;
/*
* check multiple user roles
* https://developer.wordpress.org/reference/functions/current_user_can/#div-comment-4083
*
$allowed_roles = array($role_admin, $role_fipf, $role_prof);
if (!array_intersect($allowed_roles, $current_user->roles))
return;
*/
/*
* if prof, check card state
* if cannot renew, redirect
*
if (current_user_can($role_prof)) {
$can_renew = get_field($acf_prof_can_renew['_name'], $acf_id);
if ($can_renew === false) {
// Set up nocache headers before redirecting : https://developer.wordpress.org/reference/functions/wp_safe_redirect/#user-contributed-notes
nocache_headers();
$redirect_url = home_url() . '/' . $slug_page_redirection;
wp_redirect($redirect_url, 301);
exit;
}
}
*/
}
add_action('template_redirect', 'renew_page_restrictions_CIPF');
/*
* on the renew card page for prof
* output the right message, depending of the status of the card
* 'renouveler' or 'commander'
*
* #cipf_prof_carte_commande -> default display: block;
* #cipf_prof_carte_renouvellement -> default display: none;
*
*/
function renew_page_filter_message_CIPF(){
PLGNTLS_class::debug_infos();
$slug_renew_card = PLGNTLS_class::SLUG_RENEW_CARD;
$acf_card_state = PLGNTLS_class::ACF_CARD_STATE;
if (!is_page($slug_renew_card))
return;
$user_id = get_current_user_id();
$acf_id = 'user_'.$user_id;
$cipf_renew = new PLGNTLS_class();
$card_state = get_field($acf_card_state['_name'], $acf_id);
if ($card_state === 'Renouvellement') {
$cipf_renew->add_to_front(array(
array( 'css' => 'div#cipf_prof_carte_renouvellement {display: block;}' ),
array( 'css' => 'div#cipf_prof_carte_commande {display: none;}' ),
));
}
}
add_action('wp_enqueue_scripts', 'renew_page_filter_message_CIPF');
?>

View File

@@ -0,0 +1,49 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
*
* NOT USEFUL ANYMORE :
* it was to fix pbms in formbuilder with calculation field
* but I made 2 better fixes (css and js)
*
* reset some fields for the form to buy the card
* - cgv
* - paiement
* - livraison
* - tarif
* this action is called after redirection hook
*
*/
function reset_some_fields_CIPF() {
PLGNTLS_class::debug_infos();
$slug_renew_card = PLGNTLS_class::SLUG_RENEW_CARD;
$acf_cgv = PLGNTLS_class::ACF_PROF_CGV;
$acf_payement = PLGNTLS_class::ACF_CARD_PAYMENT_METHOD;
$acf_delivery = PLGNTLS_class::ACF_CARD_PRICE_DELIVERY;
$acf_price = PLGNTLS_class::ACF_CARD_PRICE_CHOICE;
if (!is_page($slug_renew_card))
return;
$user_id = get_current_user_id();
update_field($acf_cgv['_name'] , array(""), 'user_'.$user_id);
update_field($acf_payement['_name'], array(""), 'user_'.$user_id);
update_field($acf_delivery['_name'], array(""), 'user_'.$user_id);
update_field($acf_price['_name'] , array(""), 'user_'.$user_id);
}
add_action('wp', 'reset_some_fields_CIPF');
?>

View File

@@ -0,0 +1,170 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
include_once(PLGNTLS_class::root_path() . 'php/format_user_infos.php');
function extract_if_array_size_one_CIPF($value) {
PLGNTLS_class::debug_infos();
if (is_array($value) && count($value) === 1)
return reset($value);
return $value;
}
function merge_two_arrays_CIPF($array1, $array2) {
PLGNTLS_class::debug_infos();
$new_array = $array1;
foreach ($array2 as $key2 => $value2) {
$value = extract_if_array_size_one_CIPF($value2);
// if key was not in first array, add the new element to it
if (!isset($new_array[$key2])) {
$new_array[$key2] = $value2;
continue;
}
// if key was in first array, add both in an array
$value1 = extract_if_array_size_one_CIPF($new_array[$key2]);
if (empty($value1))
$new_array[$key2] = $value2;
else if (empty($value2))
$new_array[$key2] = $value1;
else {
$new_value = array($value1, $value2);
$new_array[$key] = $new_value;
}
}
return $new_array;
}
function output_list_front_CIPF($array, $current_user, $user_id) {
PLGNTLS_class::debug_infos();
$output = '<ul>';
foreach ($array as $key => $value) {
if (str_starts_with($key, '_'))
continue ;
$value = format_user_info_CIPF($key, $current_user, $user_id);
$output .= '<li>';
$output .= '<span>';
$output .= $key;
$output .= ' : ';
$output .= $value;
$output .= '</span>';
$output .= '</li>';
}
$output .= '</ul>';
return $output;
}
/*
* shortcode to write user info of post author
* 0 or 1 argument, usage :
* - [cipf_user_info] -> list of all availables infos
* - [cipf_user_info user_email] -> display the email
* - [cipf_user_info user_email user_login] -> display the email
* - [cipf_user_info user_email author='logged_in'] -> display the email of the connected user
* - [cipf_user_info user_email author='post_creator'] -> display the email of the creator of the page/post
*
*/
function current_user_infos_CIPF($atts) {
PLGNTLS_class::debug_infos();
if (!is_user_logged_in())
return ;
/*
* choose the default id target : logged in user, or post creator ?
*
$author_is = 'logged_in'; // logged in user
*/
$author_is = 'post_creator'; // creator of post (also for author pages)
/*
* has parameter 'author' ?
* if yes, removes it from $atts
*
*/
if (is_array($atts)) {
if (isset($atts['author'])) {
$author_is = $atts['author'];
unset($atts['author']);
}
}
/*
* should output all or a specific parameter ?
*
*/
$output_all = false;
if (empty($atts))
$output_all = true;
else if (count($atts) === 0)
$output_all = true;
/*
* get author id outside loop and outside singular page : https://wordpress.stackexchange.com/q/65548
*
*/
if ($author_is === 'logged_in') {
$current_user = wp_get_current_user();
$user_id = get_current_user_id();
}
else {
if (is_author()) {
$user_id = get_queried_object_id();
}
else if (in_the_loop()) {
$user_id = get_the_author_meta('ID');
}
else if (is_singular()) {
$user_id = get_queried_object()->post_author;
}
else {
global $wp_query;
if (!empty($wp_query->posts))
$user_id = $wp_query->posts[0]->post_author;
}
//$current_user = new WP_User($user_id);
$current_user = get_user_by('id', $user_id);
}
/*
* output all the available parameters (for help)
*
*/
if ($output_all) {
$user_properties = (array) get_userdata($user_id)->data;
$user_metas = get_user_meta($user_id);
$user_infos = merge_two_arrays_CIPF($user_metas, $user_properties);
return output_list_front_CIPF($user_infos, $current_user, $user_id);
}
/*
* real purpose of this shortcode :
* only return the first argument (that is not 'author')
*
*/
if (is_array($atts))
$query = $atts[0];
else if (is_string($atts))
$query = $atts;
else
return '';
// $output = $current_user->$query;
return format_user_info_CIPF($query, $current_user, $user_id);
}
add_shortcode('cipf_user_info', 'current_user_infos_CIPF');
?>

View File

@@ -0,0 +1,68 @@
<?php
/**
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
* globals variables
* const vs define : https://stackoverflow.com/questions/2447791/php-define-vs-const
*/
/* switch console_log
const CONSOLE_OFF = true;
*/
const CIPF_CONSOLE_OFF = false;
/*
* paypal credentials
*
* LIVE :
*
* const PAYPAL_CLIENT_ID = "Aedn5e8z__hPBvKirqw5bwlhI9ChG8_N6c1xbgybYyBr4B4oP8uVzmVdH1QVKdPQKf6bWg7orPV4PDrO";
* const PAYPAL_CLIENT_SECRET = "EGeGwfHGxHxsjnC-tH8W0IL4nN3_xlc3sXFRPCQOw5uUoWae3eOgghuDKMnZc5DVGTbP6yIjVJ1BaAra";
*
* SANBOX :
*
* const PAYPAL_CLIENT_ID = "AfcmwxIXlG2ZxaMdjazX57I70BXz__aEqNWaTnqfSCI34a0V7nMbytswx7EViUjlpHs7opyrRwaH9YLl";
* const PAYPAL_CLIENT_SECRET = "EGunIhGRjPvn0Z8wXO0JsdhET30OStTAH_IyRsmhimEN23_qiRSFD-ql4tvnulKJw6TitZ-vU-ytc4A-";
*
const PAYPAL_CLIENT_ID = "AfcmwxIXlG2ZxaMdjazX57I70BXz__aEqNWaTnqfSCI34a0V7nMbytswx7EViUjlpHs7opyrRwaH9YLl";
const PAYPAL_CLIENT_SECRET = "EGunIhGRjPvn0Z8wXO0JsdhET30OStTAH_IyRsmhimEN23_qiRSFD-ql4tvnulKJw6TitZ-vU-ytc4A-";
*/
/*
* paypal api base url
const PAYPAL_API_BASE_URL = "https://api-m.sandbox.paypal.com";
*/
/*
* paypal messages
* put the message betweeen backticks `message` and then between single quotes '`message`'
* because it will be evaluated in front by js, so it need something to evaluate, in ``
* you can then use variables available in the context of execution : '`Transaction ${transaction.status}`'
* is it good strategy ? idk
const PAYPAL_MESSAGE_SUCCESS = '`Transaction ${transaction.status}: ${transaction.id}<br><br>See console for all available details`';
const PAYPAL_MESSAGE_FAILURE = '`Sorry, your transaction could not be processed...<br><br>${error}`';
const PAYPAL_MESSAGE_SUCCESS = '`paiement reussi`';
const PAYPAL_MESSAGE_FAILURE = '`paiement raté`';
*/
/*
* acf fields for card :
* - card_is_valid : has valid card
* - card_date_purchase : date of purchase
* - card_date_validity : date end of validity
const CARD_IS_VALID = 'carte_est_valide';
const CARD_DATE_PURCHASE = 'date_d_achat';
const CARD_DATE_VALIDITY = 'date_fin_validite';
*/
?>

View File

@@ -0,0 +1,30 @@
<?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
// Define a custom exception class for HTTP errors
class HttpException extends Exception {
// HTTP status code
private $statusCode;
public function __construct($message, $statusCode) {
parent::__construct($message);
$this->statusCode = $statusCode;
}
public function getStatusCode() {
return $this->statusCode;
}
}
?>

View File

@@ -12,7 +12,8 @@ if (!defined('ABSPATH')) {
https://stackify.com/how-to-log-to-console-in-php/ https://stackify.com/how-to-log-to-console-in-php/
*/ */
function console_log(...$outputs) { function console_log(...$outputs) {
if (FIPFCARD_CONSOLE_OFF) PLGNTLS_class::debug_infos();
if (CIPF_CONSOLE_OFF)
return; return;
foreach($outputs as $output) foreach($outputs as $output)
{ {

View File

@@ -1,5 +1,13 @@
<?php <?php
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/** /**
* include those two lines at the top of the main plugin file * include those two lines at the top of the main plugin file
* *
@@ -22,9 +30,9 @@
* array( // files added in order by types * array( // files added in order by types
* 'path/to/style1.css', // * 'path/to/style1.css', //
* 'path/to/script1.js', // * 'path/to/script1.js', //
* 'path/to/style2.css', // -> depends on style1.css * 'style1_css' => 'path/to/style2.css', // -> depends on style1.css
* 'http://my_url1.com', // * 'http://my_url1.com', //
* 'path/to/script2.js', // -> depends on script1.js * 'script1_js' => 'path/to/script2.js', // -> depends on script1.js
* 'path/to/file1.html', // | will be returned * 'path/to/file1.html', // | will be returned
* 'path/to/file2.html', // -> | as expanded html * 'path/to/file2.html', // -> | as expanded html
* 'path/to/file3.html', // | in the order included * 'path/to/file3.html', // | in the order included
@@ -48,6 +56,64 @@
class PLGNTLS_class class PLGNTLS_class
{ {
/*
* const declarations
*
*/
// ACF
const ACF_CARD_STATE = ['_name'=>'etat_carte', 'new'=>'Commande', 'renew'=>'Renouvellement']; // radio button
const ACF_CARD_PAYMENT_METHOD = ['_name'=>'paiement', 'paypal'=>'Paypal', 'transfert'=>'Virement']; // radio button
const ACF_CARD_PRICE_CHOICE = ['_name'=>'tarif', 'low'=>'10', 'high'=>'15']; // radio button
const ACF_CARD_PRICE_DELIVERY = ['_name'=>'livraison', 'pdf'=>'PDF', 'post'=>'Fabrication']; // radio button
const ACF_PROF_IS_ACTIV = ['_name'=>'compte-actif', 'activ'=>'Actif', 'inactiv'=>'Inactif']; // radio button
const ACF_PROF_CGV = ['_name'=>'cgv', 'cgv'=>'cgv']; // checkbox
const ACF_CARD_PRICE_TOTAL = ['_name'=>'somme_a_regler']; // number
const ACF_CARD_NUMBER = ['_name'=>'numero_de_la_carte']; // number
const ACF_CARD_EXPIRATION = ['_name'=>'fin_de_validite']; // date picker
const ACF_CARD_PAYMENT_STATE = ['_name'=>'etat_paiement', 'started'=>'en_cours', 'success'=>'reussi', 'failure'=>'echec', 'nothing'=>'aucun']; // radio button
// META
const META_PAYEMENT_STATUS = 'cipf_payement_status';
const META_ORDER_ID = 'cipf_order_id';
// SLUG & URL & QUERY
const SLUG_PROF_INACTIV = 'validation-en-cours';
const SLUG_RENEW_CARD = 'commande';
const SLUG_PAGE_REDIRECTION = 'redirection_cipf';
// const SLUG_PAYPAL_REDIRECTION_SUCCESS = self::SLUG_PAGE_REDIRECTION;
// const SLUG_PAYPAL_REDIRECTION_FAILURE = self::SLUG_PAGE_REDIRECTION;
const SLUG_PAYPAL_REDIRECTION_SUCCESS = '?'.self::QUERY_REDIRECTION_PROFIL;
const SLUG_PAYPAL_REDIRECTION_FAILURE = '?'.self::QUERY_REDIRECTION_PROFIL;
const URL_BASE_REST_ROUTE = 'cipf_plugin/api/v1'; // for routes, in php/paypal/routes.php && php/admin_modif_prof.php
const QUERY_REDIRECTION_PROFIL = 'redirection_cipf';
const QUERY_ADMIN_VALIDATE_PROF = 'admin_activate_prof_cipf'; // for admin_modif_prof.php
// PAYPAL
const PAYPAL_CLIENT_ID = "AfcmwxIXlG2ZxaMdjazX57I70BXz__aEqNWaTnqfSCI34a0V7nMbytswx7EViUjlpHs7opyrRwaH9YLl";
const PAYPAL_CLIENT_SECRET = "EGunIhGRjPvn0Z8wXO0JsdhET30OStTAH_IyRsmhimEN23_qiRSFD-ql4tvnulKJw6TitZ-vU-ytc4A-";
const PAYPAL_API_BASE_URL = "https://api-m.sandbox.paypal.com";
const PAYPAL_MESSAGE_SUCCESS = '`paiement reussi`';
const PAYPAL_MESSAGE_FAILURE = '`paiement raté`';
// ROLES
const ROLE_PROF = 'professeur__professeure';
const ROLE_PARTNER = 'partenaire';
const ROLE_FIPF = 'fipf';
const ROLE_ADMIN = 'administrator';
// OTHER
const CARD_RENEW_PERIOD = 31; // int : number of days before expiration when renew card start to be possible
const CARD_VALIDITY_TIME = '1 year'; // string : time of validity of the card (ex: '1 month' or '1 year' or '60 days')
const USER_INFO_DATE_FORMAT = 'd/m/Y'; // for user_infos.php (date format : https://www.php.net/manual/fr/datetime.format.php)
const ADMIN_VALIDATE_PROF_FIELD = 'admin_activate_prof_cipf'; // for admin_modif_prof.php
private static $_DEBUG_INFOS = true;
private static $_plugin_dir_path;
private static $_plugin_name;
private static $_file_dir_path;
private static $_file_name;
private static $_root_path; private static $_root_path;
private static $_root_url; private static $_root_url;
@@ -58,9 +124,11 @@ class PLGNTLS_class
private $_css_dependencies; private $_css_dependencies;
private $_scripts_attributes; private $_scripts_attributes;
/** /*
*/ */
public function __construct() { public function __construct() {
if (!isset(self::$_plugin_name, self::$_file_name, self::$_file_dir_path, self::$_plugin_dir_path))
self::set_root_dir();
$this->_prefix = "PLGNTLS"; $this->_prefix = "PLGNTLS";
$this->_first_script = null; $this->_first_script = null;
$this->_first_style = null; $this->_first_style = null;
@@ -69,31 +137,77 @@ class PLGNTLS_class
$this->_scripts_attributes = array(); $this->_scripts_attributes = array();
} }
/** /*
* can be used before class is instanciated : * ex:
* PLGNTLS_class::set_root_dir( plugin_dir_path(__FILE__), plugin_dir_url(__FILE__) ); * /home/www-data/cipf_plugin/php/test/test2/test3/test.php
* _plugin_dir_path /home/www-data
* _plugin_name cipf_plugin
* _file_dir_path php/test/test2/test3
* _file_name test.php
* _root_path /home/www-data/cipf_plugin/
*
* /home/www-data/cipf_plugin/test.php
* _plugin_dir_path /home/www-data
* _plugin_name cipf_plugin
* _file_dir_path ''
* _file_name test.php
* _root_path /home/www-data/cipf_plugin/
*
*/ */
public static function set_root_dir($path, $url) { private static function set_root_dir() {
if (isset( self::$_root_path )) if (isset(self::$_plugin_name, self::$_file_name, self::$_file_dir_path, self::$_plugin_dir_path))
return ; return ;
if (isset( self::$_root_url )) /*
return ; * it uses exploded_path_path by removing data from the array
self::$_root_path = $path; * so order is important !
self::$_root_url = $url; * plugin_name / path / to / file.php
* exploded [plugin_name, path, to, file.php]
* plugin_name plugin_name [path, to, file.php]
* file_name [path, to] file.php
* file_dir_name path / to
*/
$exploded_plugin_path = explode('/', plugin_basename( __FILE__ ));
self::$_plugin_name = array_shift($exploded_plugin_path);
self::$_file_name = array_pop($exploded_plugin_path);
self::$_file_dir_path = implode('/', $exploded_plugin_path);
self::$_plugin_dir_path = str_replace('/'.plugin_basename(__DIR__).'/', '', plugin_dir_path(__FILE__));
self::$_root_path = self::$_plugin_dir_path.'/'.self::$_plugin_name.'/';
self::$_root_url = plugins_url(self::$_plugin_name.'/');
} }
public static function get_path() { public static function root_path() {
if (!isset(self::$_plugin_name, self::$_file_name, self::$_file_dir_path, self::$_plugin_dir_path))
self::set_root_dir();
return(self::$_root_path); return(self::$_root_path);
} }
public static function get_url() { public static function root_url() {
if (!isset(self::$_plugin_name, self::$_file_name, self::$_file_dir_path, self::$_plugin_dir_path))
self::set_root_dir();
return(self::$_root_url); return(self::$_root_url);
} }
/*
* for debug purposes
*/
public static function debug_infos() {
if (self::$_DEBUG_INFOS === false)
return;
$trace = debug_backtrace();
$function = $trace[1]['function'];
$file = $trace[0]['file'];
$line = $trace[0]['line'];
error_log("-debug: function '".$function."' (in ".$file.", line ".$line .')');
}
public function add_to_front($srcs_arr = null, $vars = null) {
if (!is_array($vars)) public function add_to_front($srcs_arr = array(), $vars = array()) {
$vars = array(); /*
if (!is_null($srcs_arr)) * event if the function is called with no srcs
* add fetch, because it can be used just for that
*/
$this->add_fetch($srcs_arr, $vars); $this->add_fetch($srcs_arr, $vars);
$this->add_default_css($srcs_arr, $vars);
$srcs = array(); $srcs = array();
foreach($srcs_arr as $src_key => $src_value) { foreach($srcs_arr as $src_key => $src_value) {
@@ -129,7 +243,7 @@ class PLGNTLS_class
/** /*
* for fetch, we add the file script that contains the fetch function * for fetch, we add the file script that contains the fetch function
* it is an es6 module with the export keyword * it is an es6 module with the export keyword
* that way, it can also be used by modules scripts * that way, it can also be used by modules scripts
@@ -140,7 +254,7 @@ class PLGNTLS_class
*/ */
private function add_fetch(&$srcs_arr, &$vars) { private function add_fetch(&$srcs_arr, &$vars) {
// add fetch script at beginning of scripts list // add fetch script at beginning of scripts list
array_unshift($srcs_arr, array("utils/plgntls_fetch.js", 'type'=>'module')); array_unshift($srcs_arr, array(self::$_file_dir_path."/plgntls_fetch.js", 'type'=>'module'));
// for the custom endpoints in rest api to work // for the custom endpoints in rest api to work
// they need to have a nonce named 'wp_rest' // they need to have a nonce named 'wp_rest'
// see : https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/ // see : https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/
@@ -150,11 +264,16 @@ class PLGNTLS_class
$vars = array_merge($vars, $fetch_url); $vars = array_merge($vars, $fetch_url);
} }
private function add_default_css(&$srcs_arr, &$vars) {
// add default css file at beginning of style list
array_unshift($srcs_arr, self::$_file_dir_path."/plgntls_default.css");
}
/**
/*
* @param two arguments : * @param two arguments :
* 1. html files to include in front * 1. html files to include in front
* - can be a string of 1 filename * - can be a string of 1 filename
@@ -177,7 +296,7 @@ class PLGNTLS_class
private function create_html($files = null, $vars = null) { private function create_html($files = null, $vars = null) {
if (is_null($files)) if (is_null($files))
return null; return null;
$plgn_dir = $this->get_path(); $plgn_dir = $this->root_path();
if (!is_null($vars)) if (!is_null($vars))
extract($vars); extract($vars);
@@ -191,7 +310,7 @@ class PLGNTLS_class
return $html; return $html;
} }
/** /*
* pass variables to js front as global variables * pass variables to js front as global variables
* @param array : list of key => value * @param array : list of key => value
* with the key being name of the variable, like this : * with the key being name of the variable, like this :
@@ -254,6 +373,8 @@ class PLGNTLS_class
/* /*
* uncomment to print all enqueued files, can be usefull * uncomment to print all enqueued files, can be usefull
*/
/*
global $wp_scripts; global $wp_scripts;
error_log("wp_scripts->queue:"); error_log("wp_scripts->queue:");
error_log(json_encode($wp_scripts->queue)); error_log(json_encode($wp_scripts->queue));
@@ -278,16 +399,15 @@ class PLGNTLS_class
} }
private function add_inline_script($src) { private function add_inline_script($src) {
$handle = $src->depends; $handle = $src->depends;
if ($handle === null) if ($handle === null || empty($handle))
$handle = $this->_first_script; $handle = $this->_first_script;
wp_add_inline_script($src->depends, $src->src, 'before'); wp_add_inline_script($handle, $src->src, 'before');
} }
private function add_inline_style($src) { private function add_inline_style($src) {
error_log("inside add_inline_style");
$handle = $src->depends; $handle = $src->depends;
if ($handle === null) if ($handle === null || empty($handle))
$handle = $this->_first_style; $handle = $this->_first_style;
wp_add_inline_style($src->depends, $src->src); wp_add_inline_style($handle, $src->src);
} }
@@ -371,7 +491,6 @@ class PLGNTLS_class
]; ];
// 7. depends // 7. depends
$src->depends = '';
if (is_string($key)) if (is_string($key))
$src->depends = $key; $src->depends = $key;
@@ -414,8 +533,7 @@ class PLGNTLS_class
// basename handle // basename handle
// https://www.url.com/route -> www.url.com/route -> www_url_com_route // https://www.url.com/route -> www.url.com/route -> www_url_com_route
// path/to/script.js -> script.js -> script_js // path/to/script.js -> script.js -> script_js
if ($src->ext === "url") if ($src->ext === "url") {
{
$url = parse_url($src->src); $url = parse_url($src->src);
$src->basename = $url['host'] . $url['path']; $src->basename = $url['host'] . $url['path'];
} }
@@ -432,8 +550,8 @@ class PLGNTLS_class
$src->version = null; $src->version = null;
} }
else { else {
$src->url = $this->get_url().$src->src; $src->url = $this->root_url().$src->src;
$src->path = $this->get_path().$src->src; $src->path = $this->root_path().$src->src;
$src->version = date("ymd-Gis", filemtime($src->path)); $src->version = date("ymd-Gis", filemtime($src->path));
} }

View File

@@ -0,0 +1,4 @@
/*
* this css file will be automatically added to front by PLGNTLS_class
* no need to write any style here, but you can if you want
*/

View File

@@ -1,7 +1,8 @@
/** /*
* this file is there for scripts that uses modules import * this file is there for scripts that uses modules import
*/ *
*/
export function PLGNTLS_fetch(url, options = {}) { export function PLGNTLS_fetch(url, options = {}) {
console.log("inside PLGNTLS_fetch"); console.log("inside PLGNTLS_fetch");
url = PLGNTLS_data.fetch_url + url; url = PLGNTLS_data.fetch_url + url;
@@ -13,9 +14,10 @@ export function PLGNTLS_fetch(url, options = {}) {
return fetch(url, options); return fetch(url, options);
} }
/** /*
* For non-module scripts, attach to the global scope * For non-module scripts, attach to the global scope
*/ *
*/
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
window.PLGNTLS_fetch = PLGNTLS_fetch; window.PLGNTLS_fetch = PLGNTLS_fetch;
} }

View File

@@ -1,95 +0,0 @@
<?php
/*
Plugin Name: fipfcard_plugin
Plugin URI:
Description:
Author: hugogogo
Version: 1.1.0
Author URI:
*/
/*
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
* plugin dir root
*/
include_once( plugin_dir_path(__FILE__) . '/utils/plgntls_class.php');
PLGNTLS_class::set_root_dir( plugin_dir_path(__FILE__), plugin_dir_url(__FILE__) );
/*
* general inclusions
*/
include_once(PLGNTLS_class::get_path() . '/utils/globals.php');
include_once(PLGNTLS_class::get_path() . '/utils/console_log.php');
include_once(PLGNTLS_class::get_path() . '/php/paypal/paypal.php');
include_once(PLGNTLS_class::get_path() . '/php/register/partenaires.php');
/*
* test the class PLGNTLS
*/
add_shortcode('fipfcard_plugin', 'fipfcard_test_class_tools');
/*
*
function custom_frontend_posting_form() {
$my_image = the_field('image_ratio');
error_log("my_image");
error_log(json_encode($my_image));
return $my_image;
}
add_shortcode('custom_frontend_posting_form', 'custom_frontend_posting_form');
*/
/*
* menu plugin
*/
include_once(PLGNTLS_class::get_path() . '/php/menu/example_menu.php');
function fipfcard_plugin_menu()
{
add_menu_page
(
'fipf_card', // webpage title
'fipf_card', // menu title
'manage_options', // capability
'fipfcard-plugin', // menu_slug
'fipfcard_plugin_content' // callback function to display page content
);
}
add_action('admin_menu', 'fipfcard_plugin_menu');
?>

View File

@@ -1,24 +0,0 @@
<h1>old button :</h1>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_s-xclick" />
<input type="hidden" name="hosted_button_id" value="H876N9DGSCLKS" />
<input type="hidden" name="currency_code" value="EUR" />
<input type="image" src="https://www.paypalobjects.com/fr_XC/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" title="PayPal, votre réflexe sécurité pour payer en ligne." alt="Acheter" />
</form>
<h1>new button :</h1>
<div id="paypal-button-container"></div>
<!--
custom card fields
@see https://developer.paypal.com/docs/checkout/advanced/integrate#link-addpaypalbuttonsandcardfields
<div id="card-name-field-container"></div>
<div id="checkout-form">
<div id="card-number-field-container"></div>
<div id="card-expiry-field-container"></div>
<div id="card-cvv-field-container"></div>
<button id="card-field-submit-button" type="button">
Pay now with Card
</button>
</div>
-->
<p id="result-message"></p>

File diff suppressed because it is too large Load Diff

View File

@@ -1,381 +0,0 @@
console.log("---------------inside image_editor.js--------------");
const edit_image_button = document.getElementById('edit_image');
const image_id_field = document.getElementById('image_id');
const media_editor = document.getElementById('media_editor');
edit_image_button.addEventListener('click', () => {
const image_id = image_id_field.value;
//PLGNTLS_ajax("postid", image_id, 'image-editor')
const data_obj = {
'postid': image_id,
};
PLGNTLS_ajax(data_obj, 'image_editor_PLGNTLS')
.then((response) => response.json())
.then((data) => {
console.log("data: ");
console.log(data);
media_editor.innerHTML = data.data.html;
})
.catch((error) => {
console.log("error: ");
console.log(error);
});
});
/*
open: function (e, t, i) { // t: nonce
this._view = i; // div: #media-editor-114
var a = c('#image-editor-' + e), // e: image id
o = c('#media-head-' + e),
r = c('#imgedit-open-btn-' + e),
s = r.siblings('.spinner');
if (!r.hasClass('button-activated')) return s.addClass('is-active'),
c.ajax({
url: ajaxurl,
type: 'post',
data: {
action: 'image-editor',
_ajax_nonce: t,
postid: e,
do : 'open'},
beforeSend: function () {
r.addClass('button-activated')
}
}).done(
function (t) {
var i;
'-1' === t &&
(
i = n('Could not load the preview image.'),
a.html(
'<div class="notice notice-error" tabindex="-1" role="alert"><p>' + i + '</p></div>'
)
),
t.data &&
t.data.html &&
a.html(t.data.html),
o.fadeOut(
'fast',
function () {
a.fadeIn(
'fast',
function () {
i &&
c(document).trigger('image-editor-ui-ready')
}
),
r.removeClass('button-activated'),
s.removeClass('is-active')
}
),
l.init(e)
}
) },
imgLoaded: function (t) {
var i = c('#image-preview-' + t),
e = c('#imgedit-crop-' + t);
void 0 === this.hold.sizer &&
this.init(t),
this.initCrop(t, i, e),
this.setCropSelection(
t,
{
x1: 0,
y1: 0,
x2: 0,
y2: 0,
width: i.innerWidth(),
height: i.innerHeight()
}
),
this.toggleEditor(t, 0, !0)
},
focusManager: function () {
setTimeout(
function () {
var t = c('.notice[role="alert"]');
(t = t.length ? t : c('.imgedit-wrap').find(':tabbable:first')).attr('tabindex', '-1').trigger('focus')
},
100
)
},
initCrop: function (a, t, i) {
var o = this,
r = c('#imgedit-sel-width-' + a),
s = c('#imgedit-sel-height-' + a),
n = c('#imgedit-start-x-' + a),
d = c('#imgedit-start-y-' + a),
t = c(t);
t.data('imgAreaSelect') ||
(
o.iasapi = t.imgAreaSelect({
parent: i,
instance: !0,
handles: !0,
keys: !0,
minWidth: 3,
minHeight: 3,
onInit: function (t) {
c(t).next().css('position', 'absolute').nextAll('.imgareaselect-outer').css('position', 'absolute'),
i.children().on(
'mousedown, touchstart',
function (t) {
var i,
e = !1;
t.shiftKey &&
(
t = o.iasapi.getSelection(),
i = o.getSelRatio(a),
e = t &&
t.width &&
t.height ? t.width + ':' + t.height : i
),
o.iasapi.setOptions({
aspectRatio: e
})
}
)
},
onSelectStart: function () {
l.setDisabled(c('#imgedit-crop-sel-' + a), 1),
l.setDisabled(c('.imgedit-crop-clear'), 1),
l.setDisabled(c('.imgedit-crop-apply'), 1)
},
onSelectEnd: function (t, i) {
l.setCropSelection(a, i),
c('#imgedit-crop > *').is(':visible') ||
l.toggleControls(c('.imgedit-crop.button'))
},
onSelectChange: function (t, i) {
var e = l.hold.sizer;
r.val(l.round(i.width / e)),
s.val(l.round(i.height / e)),
n.val(l.round(i.x1 / e)),
d.val(l.round(i.y1 / e))
}
})
)
},
setCropSelection: function (t, i) {
if (!(i = i || 0) || i.width < 3 && i.height < 3) return this.setDisabled(c('.imgedit-crop', '#imgedit-panel-' + t), 1),
this.setDisabled(c('#imgedit-crop-sel-' + t), 1),
c('#imgedit-sel-width-' + t).val(''),
c('#imgedit-sel-height-' + t).val(''),
c('#imgedit-start-x-' + t).val('0'),
c('#imgedit-start-y-' + t).val('0'),
c('#imgedit-selection-' + t).val(''),
!1;
i = {
x: i.x1,
y: i.y1,
w: i.width,
h: i.height
},
this.setDisabled(c('.imgedit-crop', '#imgedit-panel-' + t), 1),
c('#imgedit-selection-' + t).val(JSON.stringify(i))
},
close: function (t, i) {
if ((i = i || !1) && this.notsaved(t)) return !1;
this.iasapi = {},
this.hold = {},
this._view ? this._view.back() : c('#image-editor-' + t).fadeOut(
'fast',
function () {
c('#media-head-' + t).fadeIn(
'fast',
function () {
c('#imgedit-open-btn-' + t).trigger('focus')
}
),
c(this).empty()
}
)
},
notsaved: function (t) {
var i = c('#imgedit-history-' + t).val(),
i = '' !== i ? JSON.parse(i) : [];
return this.intval(c('#imgedit-undone-' + t).val()) < i.length &&
!confirm(c('#imgedit-leaving-' + t).text())
},
addStep: function (t, i, e) {
for (
var a = this,
o = c('#imgedit-history-' + i),
r = '' !== o.val() ? JSON.parse(o.val()) : [],
s = c('#imgedit-undone-' + i),
n = a.intval(s.val());
0 < n;
) r.pop(),
n--;
s.val(0),
r.push(t),
o.val(JSON.stringify(r)),
a.refreshEditor(
i,
e,
function () {
a.setDisabled(c('#image-undo-' + i), !0),
a.setDisabled(c('#image-redo-' + i), !1)
}
)
},
rotate: function (t, i, e, a) {
if (c(a).hasClass('disabled')) return !1;
this.closePopup(a),
this.addStep({
r: {
r: t,
fw: this.hold.h,
fh: this.hold.w
}
}, i, e)
},
flip: function (t, i, e, a) {
if (c(a).hasClass('disabled')) return !1;
this.closePopup(a),
this.addStep({
f: {
f: t,
fw: this.hold.w,
fh: this.hold.h
}
}, i, e)
},
crop: function (t, i, e) {
var a = c('#imgedit-selection-' + t).val(),
o = this.intval(c('#imgedit-sel-width-' + t).val()),
r = this.intval(c('#imgedit-sel-height-' + t).val());
if (c(e).hasClass('disabled') || '' === a) return !1;
0 < (a = JSON.parse(a)).w &&
0 < a.h &&
0 < o &&
0 < r &&
(a.fw = o, a.fh = r, this.addStep({
c: a
}, t, i)),
c('#imgedit-sel-width-' + t).val(''),
c('#imgedit-sel-height-' + t).val(''),
c('#imgedit-start-x-' + t).val('0'),
c('#imgedit-start-y-' + t).val('0')
},
undo: function (i, t) {
var e = this,
a = c('#image-undo-' + i),
o = c('#imgedit-undone-' + i),
r = e.intval(o.val()) + 1;
a.hasClass('disabled') ||
(
o.val(r),
e.refreshEditor(
i,
t,
function () {
var t = c('#imgedit-history-' + i),
t = '' !== t.val() ? JSON.parse(t.val()) : [];
e.setDisabled(c('#image-redo-' + i), !0),
e.setDisabled(a, r < t.length),
t.length === r &&
c('#image-redo-' + i).trigger('focus')
}
)
)
},
redo: function (t, i) {
var e = this,
a = c('#image-redo-' + t),
o = c('#imgedit-undone-' + t),
r = e.intval(o.val()) - 1;
a.hasClass('disabled') ||
(
o.val(r),
e.refreshEditor(
t,
i,
function () {
e.setDisabled(c('#image-undo-' + t), !0),
e.setDisabled(a, 0 < r),
0 == r &&
c('#image-undo-' + t).trigger('focus')
}
)
)
},
setNumSelection: function (t, i) {
var e = c('#imgedit-sel-width-' + t),
a = c('#imgedit-sel-height-' + t),
o = c('#imgedit-start-x-' + t),
r = c('#imgedit-start-y-' + t),
o = this.intval(o.val()),
r = this.intval(r.val()),
s = this.intval(e.val()),
n = this.intval(a.val()),
d = c('#image-preview-' + t),
l = d.height(),
d = d.width(),
h = this.hold.sizer,
g = this.iasapi;
if (!1 !== this.validateNumeric(i)) return s < 1 ? (e.val(''), !1) : n < 1 ? (a.val(''), !1) : void (
(s && n || o && r) &&
(i = g.getSelection()) &&
(
s = i.x1 + Math.round(s * h),
n = i.y1 + Math.round(n * h),
o = o === i.x1 ? i.x1 : Math.round(o * h),
i = r === i.y1 ? i.y1 : Math.round(r * h),
d < s &&
(o = 0, s = d, e.val(Math.round(s / h))),
l < n &&
(i = 0, n = l, a.val(Math.round(n / h))),
g.setSelection(o, i, s, n),
g.update(),
this.setCropSelection(t, g.getSelection())
)
)
},
round: function (t) {
var i;
return t = Math.round(t),
0.6 < this.hold.sizer ? t : '1' === (i = t.toString().slice( - 1)) ? t - 1 : '9' === i ? t + 1 : t
},
setRatioSelection: function (t, i, e) {
var a = this.intval(c('#imgedit-crop-width-' + t).val()),
o = this.intval(c('#imgedit-crop-height-' + t).val()),
r = c('#image-preview-' + t).height();
!1 === this.validateNumeric(e) ? this.iasapi.setOptions({
aspectRatio: null
}) : a &&
o &&
(
this.iasapi.setOptions({
aspectRatio: a + ':' + o
}),
e = this.iasapi.getSelection(!0)
) &&
(
r < (a = Math.ceil(e.y1 + (e.x2 - e.x1) / (a / o))) ? (
a = r,
o = n(
'Selected crop ratio exceeds the boundaries of the image. Try a different ratio.'
),
c('#imgedit-crop-' + t).prepend(
'<div class="notice notice-error" tabindex="-1" role="alert"><p>' + o + '</p></div>'
),
wp.a11y.speak(o, 'assertive'),
c(i ? '#imgedit-crop-height-' + t : '#imgedit-crop-width-' + t).val('')
) : void 0 !== (r = c('#imgedit-crop-' + t).find('.notice-error')) &&
r.remove(),
this.iasapi.setSelection(e.x1, e.y1, e.x2, a),
this.iasapi.update()
)
},
validateNumeric: function (t) {
if (!1 === this.intval(c(t).val())) return c(t).val(''),
!1
}
}
}(jQuery);
*/

View File

@@ -1,107 +0,0 @@
import { resultMessage } from './result_message.js';
import { PLGNTLS_fetch } from '../../utils/plgntls_fetch.js';
/**
* @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend
*/
//async function onApprove(data, actions) {
export async function onApprove(data, actions) {
try {
const fetch_approve_url = PLGNTLS_data.fetch_url + "/fipf_plugin/api/v1/orders/" + data.orderID + "/capture";
console.log("fetch_approve_url:", fetch_approve_url);
//const response = await fetch(fetch_approve_url, {
const response = await PLGNTLS_fetch('/fipf_plugin/api/v1/orders/' + data.orderID + '/capture', {
method: "POST",
headers: {
"Content-Type": "application/json",
//"X-WP-Nonce": PLGNTLS_data.rest_nonce,
},
});
const orderData = await response.json();
// Three cases to handle:
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
// (2) Other non-recoverable errors -> Show a failure message
// (3) Successful transaction -> Show confirmation or thank you message
const errorDetail = orderData?.details?.[0];
if (errorDetail?.issue === "INSTRUMENT_DECLINED") {
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
// recoverable state, per https://developer.paypal.com/docs/checkout/standard/customize/handle-funding-failures/
return actions.restart();
} else if (errorDetail) {
// (2) Other non-recoverable errors -> Show a failure message
throw new Error(`${errorDetail.description} (${orderData.debug_id})`);
} else if (!orderData.purchase_units) {
throw new Error(JSON.stringify(orderData));
} else {
// (3) Successful transaction -> Show confirmation or thank you message
// Or go to another URL: actions.redirect('thank_you.html');
const transaction =
orderData?.purchase_units?.[0]?.payments?.captures?.[0] ||
orderData?.purchase_units?.[0]?.payments?.authorizations?.[0];
// to show a message on page
//resultMessage(`Transaction ${transaction.status}: ${transaction.id}<br><br>See console for all available details`,);
console.log(
"Capture result",
orderData,
JSON.stringify(orderData, null, 2),
);
actions.redirect('https://local_fipfcard_plugin.com/');
}
} catch (error) {
console.error(error);
resultMessage(
`Sorry, your transaction could not be processed...<br><br>${error}`,
);
}
}
/**
* @see https://developer.paypal.com/demo/checkout/#/pattern/server
*
// Call your server to finalize the transaction
function onApprove (data, actions) {
const fetch_approve_url = PLGNTLS_data.fetch_url + "/fipf_plugin/api/v1/orders/" + data.orderID + "/capture";
console.log("fetch_approve_url:", fetch_approve_url);
return fetch(fetch_approve_url, {
method: 'post'
}).then(function(res) {
return res.json();
}).then(function(orderData) {
// Three cases to handle:
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
// (2) Other non-recoverable errors -> Show a failure message
// (3) Successful transaction -> Show confirmation or thank you
// This example reads a v2/checkout/orders capture response, propagated from the server
// You could use a different API or structure for your 'orderData'
var errorDetail = Array.isArray(orderData.details) && orderData.details[0];
if (errorDetail && errorDetail.issue === 'INSTRUMENT_DECLINED') {
return actions.restart(); // Recoverable state, per:
// https://developer.paypal.com/docs/checkout/integration-features/funding-failure/
}
if (errorDetail) {
var msg = 'Sorry, your transaction could not be processed.';
if (errorDetail.description) msg += '\n\n' + errorDetail.description;
if (orderData.debug_id) msg += ' (' + orderData.debug_id + ')';
return alert(msg); // Show a failure message (try to avoid alerts in production environments)
}
// Successful capture! For demo purposes:
console.log('Capture result', orderData, JSON.stringify(orderData, null, 2));
var transaction = orderData.purchase_units[0].payments.captures[0];
alert('Transaction '+ transaction.status + ': ' + transaction.id + '\n\nSee console for all available details');
// Replace the above to show a success message within this page, e.g.
// const element = document.getElementById('paypal-button-container');
// element.innerHTML = '';
// element.innerHTML = '<h3>Thank you for your payment!</h3>';
// Or go to another URL: actions.redirect('thank_you.html');
});
}
*/

View File

@@ -1,23 +0,0 @@
<?php acf_form_head(); ?>
<?php get_header(); ?>
<div id="primary">
<div id="content" role="main">
<?php /* The loop */ ?>
<?php while ( have_posts() ) : the_post(); ?>
<h1><?php the_title(); ?></h1>
<?php the_content(); ?>
<p>My custom field: <?php the_field('my_custom_field'); ?></p>
<?php acf_form(); ?>
<?php endwhile; ?>
</div><!-- #content -->
</div><!-- #primary -->
<?php get_footer(); ?>

File diff suppressed because it is too large Load Diff

View File

@@ -1,89 +0,0 @@
<?php
/**
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
function fipfcard_image_editor()
{
// ob_start();
// wp_image_editor('33545');
// return ob_get_clean();
$fipfcard_image_editor = new PLGNTLS_class();
return $fipfcard_image_editor->add_to_front(
array(
"js/image_editor.js",
"html/image_editor.html",
)
);
// if ( ! has_action( "wp_ajax_{$action}" ) ) {
// it returns error 400
}
add_shortcode('fipfcard_image_editor', 'fipfcard_image_editor');
*/
/**
* Handles image editing via AJAX.
* from wp-admin/includes/ajax-action.php
*/
/*
function wp_ajax_image_editor() {
$attachment_id = (int) $_POST['postid'];
// $attachment_id = 33555;
// if ( empty( $attachment_id ) || ! current_user_can( 'edit_post', $attachment_id ) ) {
// wp_die( -1 );
// }
// check_ajax_referer( "image_editor-$attachment_id" );
// require_once ABSPATH . 'wp-admin/includes/image-edit.php';
$msg = false;
switch ( $_POST['do'] ) {
case 'save':
$msg = wp_save_image( $attachment_id );
if ( ! empty( $msg->error ) ) {
wp_send_json_error( $msg );
}
wp_send_json_success( $msg );
break;
case 'scale':
$msg = wp_save_image( $attachment_id );
break;
case 'restore':
$msg = wp_restore_image( $attachment_id );
break;
}
ob_start();
wp_image_editor( $attachment_id, $msg );
$html = ob_get_clean();
if ( ! empty( $msg->error ) ) {
wp_send_json_error(
array(
'message' => $msg,
'html' => $html,
)
);
}
wp_send_json_success(
array(
'message' => $msg,
'html' => $html,
)
);
}
add_action( 'wp_ajax_image_editor', 'wp_ajax_image_editor' );
*/
?>

View File

@@ -1,110 +0,0 @@
<?php
/**
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
include_once(PLGNTLS_class::get_path() . '/php/paypal/route_api_orders.php');
include_once(PLGNTLS_class::get_path() . '/php/paypal/route_api_orders_capture.php');
/*
function check_paypal_request()
{
error_log("----");
if (is_page('test_paypal_payment'))
error_log("on test_paypal_payment");
else if (is_page('test_paypal_ok'))
error_log("on test_paypal_ok");
else if (is_page('test_paypal_infos'))
error_log("on test_paypal_infos");
else
return;
error_log("_GET");
error_log(json_encode($_GET));
error_log("_POST");
error_log(json_encode($_POST));
// error_log("_COOKIE");
// error_log(json_encode($_COOKIE));
}
add_action('template_redirect', 'check_paypal_request');
*/
/**
* call to paypal_shortcode_content()
*/
function fipf_paypal_shortcode_content()
{
$fipfcard_paypal = new PLGNTLS_class();
$pp_sdk_currency = "EUR";
$pp_sdk_debug = "true";
$pp_sdk_base_url="https://sandbox.paypal.com";
$pp_sdk_base_url="https://www.paypal.com";
// $pp_sdk_client_token="abc123xyz==";
$pp_sdk_src="$pp_sdk_base_url/sdk/js?client-id=" . PAYPAL_CLIENT_ID . "&currency=$pp_sdk_currency&debug=$pp_sdk_debug";
$pp_sdk_src="$pp_sdk_base_url/sdk/js?client-id=" . PAYPAL_CLIENT_ID ;
// $pp_sdk_attributes="src='$pp_sdk_src' data-client-token='$pp_sdk_client_token'";
// $pp_sdk_attributes="src='$pp_sdk_src'";
// $pp_sdk_html_script="<script $pp_sdk_attributes></script>";
$added_to_front = $fipfcard_paypal->add_to_front(
array(
$pp_sdk_src,
// 'js/paypal/result_message.js',
// 'js/paypal/create_order.js',
// 'js/paypal/on_approve.js',
//"js/paypal/paypal.js",
array("js/paypal/paypal.js", 'type'=>'module'),
"html/paypal/paypal.html",
),
);
return $added_to_front;
}
add_shortcode('fipf_paypal_shortcode', 'fipf_paypal_shortcode_content');
/**
* the js file paypal.js needs to be imported as a module to use import
* @see https://developer.wordpress.org/reference/hooks/script_loader_tag/
function fipf_add_id_to_script( $tag, $handle, $src ) {
if ( $handle === 'PLGNTLS_paypal_js' ) {
$tag = '<script type="module" src="' . esc_url( $src ) . '" ></script>';
}
return $tag;
}
add_filter( 'script_loader_tag', 'fipf_add_id_to_script', 10, 3 );
*/
// handling routes and endpoints
// diff routes and endpoints : https://stackoverflow.com/q/56075017/9497573
function fipf_routes_endpoints()
{
$base_rest_route = "fipf_plugin/api/v1";
register_rest_route($base_rest_route, '/orders', array(
'methods' => 'POST',
'callback' => 'fipf_handle_orders_request',
));
// https://local_fipfcard_plugin.com/wp-json/fipf_plugin/api/v1/orders/21T129305J264761D/capture
register_rest_route($base_rest_route, '/orders/(?P<orderID>[a-zA-Z0-9]+)/capture', array(
'methods' => 'POST',
'callback' => 'fipf_handle_orders_capture_request',
));
};
add_action('rest_api_init', 'fipf_routes_endpoints');
?>

View File

@@ -1,97 +0,0 @@
<?php
include_once(PLGNTLS_class::get_path() . '/php/paypal/route_api_utils.php');
include_once(PLGNTLS_class::get_path() . '/php/paypal/update_user_payment.php');
/**
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/**
* @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend
*/
function fipf_handle_orders_request($request_data) {
try {
// Extract cart information from request body
$cart = $request_data['cart'];
// Process the order and get the response
$order_response = fipf_create_order($cart);
$json_response = $order_response['json_response'];
$http_status_code = $order_response['http_status_code'];
fipf_update_user_payment($json_response, 'start');
// Return response
return new WP_REST_Response($json_response, $http_status_code);
} catch (Exception $e) {
// Handle errors
error_log('Failed to create order: ' . $e->getMessage());
return new WP_Error('500', 'Failed to create order.', array('status' => 500));
}
}
/**
* Create an order to start the transaction.
* @see https://developer.paypal.com/docs/api/orders/v2/#orders_create
*/
function fipf_create_order( $cart )
{
// use the cart information passed from the front-end to calculate the purchase unit details
$access_token = fipf_generate_access_token();
$url = PAYPAL_API_BASE_URL . '/v2/checkout/orders';
$payload = array(
'intent' => "CAPTURE",
'purchase_units' => array(
array(
'amount' => array(
'currency_code' => "USD",
'value' => "100.00",
),
),
),
);
$headers = array(
"Content-Type: application/json",
"Authorization: Bearer " . $access_token
// Uncomment one of these to force an error for negative testing (in sandbox mode only). Documentation:
// https://developer.paypal.com/tools/sandbox/negative-testing/request-headers/
// "PayPal-Mock-Response": '{"mock_application_codes": "MISSING_REQUIRED_PARAMETER"}'
// "PayPal-Mock-Response": '{"mock_application_codes": "PERMISSION_DENIED"}'
// "PayPal-Mock-Response": '{"mock_application_codes": "INTERNAL_SERVER_ERROR"}'
);
// Initialize cURL session
$ch = curl_init();
// Set cURL options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Execute cURL session and get the response
$response = curl_exec($ch);
if ($response === false)
throw new Exception('cURL error: ' . curl_error($ch));
// Close cURL session
curl_close($ch);
// in utils
return fipf_handle_response($response);
};
?>

View File

@@ -1,74 +0,0 @@
<?php
include_once(PLGNTLS_class::get_path() . '/php/paypal/route_api_utils.php');
include_once(PLGNTLS_class::get_path() . '/php/paypal/update_user_payment.php');
/**
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
function fipf_handle_orders_capture_request($request) {
$order_id = $request['orderID'];
try {
// Implement captureOrder function logic here
// Make sure you implement captureOrder function similar to the Node.js code
$response_data = fipf_capture_order($order_id);
$http_status_code = $response_data['http_status_code'];
$json_response = $response_data['json_response'];
fipf_update_user_payment($json_response, 'end');
return new WP_REST_Response($json_response, $http_status_code);
}
catch (Exception $e) {
error_log('Failed to capture order: ' . $e->getMessage());
return new WP_REST_Response(array('error' => 'Failed to capture order.'), 500);
}
}
/**
* Capture payment for the created order to complete the transaction.
* @see https://developer.paypal.com/docs/api/orders/v2/#orders_capture
*/
function fipf_capture_order($orderID) {
$access_token = fipf_generate_access_token();
$url = PAYPAL_API_BASE_URL . '/v2/checkout/orders/' . $orderID . '/capture';
$headers = array(
"Content-Type: application/json",
"Authorization: Bearer " . $access_token
// Uncomment one of these to force an error for negative testing (in sandbox mode only). Documentation:
// https://developer.paypal.com/tools/sandbox/negative-testing/request-headers/
// 'PayPal-Mock-Response: {"mock_application_codes": "INSTRUMENT_DECLINED"}',
// 'PayPal-Mock-Response: {"mock_application_codes": "TRANSACTION_REFUSED"}',
// 'PayPal-Mock-Response: {"mock_application_codes": "INTERNAL_SERVER_ERROR"}'
);
// Initialize cURL session
$ch = curl_init();
// Set cURL options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Execute cURL session and get the response
$response = curl_exec($ch);
if ($response === false)
throw new Exception('cURL error: ' . curl_error($ch));
// Close cURL session
curl_close($ch);
// in utils
return fipf_handle_response($response);
};
?>

View File

@@ -1,98 +0,0 @@
<?php
/**
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/**
* @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend
*/
function fipf_handle_response($response) {
try
{
// Decode JSON response
$json_response = json_decode($response);
return array(
'json_response' => $json_response,
'http_status_code' => http_response_code()
);
}
catch (Exception $err)
{
// Get error message from response
$error_message = $response->text();
throw new Exception($error_message);
}
}
/*
async function handleResponse(response) {
try {
const jsonResponse = await response.json();
return {
jsonResponse,
httpStatusCode: response.status,
};
} catch (err) {
const errorMessage = await response.text();
throw new Error(errorMessage);
}
}
*/
/**
* Generate an OAuth 2.0 access token for authenticating with PayPal REST APIs.
* @see https://developer.paypal.com/docs/checkout/standard/integrate/#link-integratebackend
* @see https://developer.paypal.com/api/rest/authentication/
*/
function fipf_generate_access_token()
{
try
{
if ( !PAYPAL_CLIENT_ID || !PAYPAL_CLIENT_SECRET ) {
throw new Exception( "MISSING_API_CREDENTIALS" );
}
$credentials = PAYPAL_CLIENT_ID . ":" . PAYPAL_CLIENT_SECRET;
$auth = base64_encode($credentials);
$url = PAYPAL_API_BASE_URL . '/v1/oauth2/token';
$body = http_build_query(array('grant_type' => 'client_credentials'));
// Initialize curl
$ch = curl_init();
// Set curl options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: Basic ' . $auth,
));
// Execute curl and get the response
$data_json = curl_exec($ch);
if ( $data_json === false)
throw new Exception('cURL error: ' . curl_error($ch));
// Close curl
curl_close($ch);
$data = json_decode($data_json);
return $data->access_token;
}
catch (Exception $error)
{
error_log("Failed to generate Access Token:");
error_log($error->getMessage());
}
};
?>

View File

@@ -1,209 +0,0 @@
<?php
/**
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/**
* see documentation in private 'paypal.md'
* basically it check if the user who initiate the transaction
* is the same that finish it
*
* add_user_meta('user_id', 'fipf_order_id', 'aaaaaa');
* ['aaaaaa']
* add_user_meta('user_id', 'fipf_order_id', 'bbbbbb');
* ['aaaaaa', 'bbbbbb']
* add_user_meta('user_id', 'fipf_order_id', 'bbbbbb');
* ['aaaaaa', 'bbbbbb', 'bbbbbb']
* get_user_meta('user_id', 'fipf_order_id');
* ['aaaaaa', 'bbbbbb', 'bbbbbb']
* $del_ret = delete_user_meta('user_id', 'fipf_order_id', 'bbbbbb');
* ['aaaaaa'] - $del_ret === true
* $del_ret = delete_user_meta('user_id', 'fipf_order_id', 'bbbbbb');
* ['aaaaaa'] - $del_ret === false
*
*/
function fipf_update_user_payment($message, $step)
{
$order_id = $message->id;
$user_id = get_current_user_id();
/*
order status : https://developer.paypal.com/docs/api/orders/v2/#orders_capture!c=201&path=status&t=response
CREATED
SAVED
APPROVED ?
VOIDED
- COMPLETED
PAYER_ACTION_REQUIRED
*/
$status = $message->status;
//error_log("--- in update_user_payment, step :");
//error_log($step);
////error_log("message :");
////error_log(json_encode($message));
//error_log("order_id :");
//error_log($order_id);
//error_log("status :");
//error_log($status);
//$user_meta_order_id = get_user_meta($user_id, 'fipf_order_id');
//error_log("user_meta->fipf_order_id :");
//error_log(json_encode($user_meta_order_id));
//error_log("... update user");
// addind order_id to fipf_order_id meta field
// it can duplicate, it's not a problem : delete_user_meta will delete all
add_user_meta($user_id, 'fipf_order_id', $order_id);
// add a schedule event to delete this order_id
fipf_schedule_delete_orderid($user_id, $order_id);
fipf_validate_payment_for_user($user_id, $order_id);
// if transaction is COMPLETED, then delete order_id and update user
if ($status === 'COMPLETED')
{
// find the user containing the order_id and delete this order_id
$user_id_to_update = fipf_delete_order_id_on_success($user_id, $order_id);
// proceed to validate payment for user
fipf_validate_payment_for_user($user_id_to_update, $order_id);
}
//$user_meta_order_id = get_user_meta($user_id, 'fipf_order_id');
//error_log("user_meta->fipf_order_id :");
//error_log(json_encode($user_meta_order_id));
//error_log("--- out update_user_payment");
}
/**
*
* change acf field [carte_est_valide](validite) to true
* change acf field [date_d_achat](achat) to new current date
* change acf field [date_fin_validite](echance) to previous date + 1 year
*
* create scheduled emails to inform of end of validity
*
* acf uses 'Y-m-d H:i:s' format :
* -> https://www.advancedcustomfields.com/resources/date-time-picker/
*/
function fipf_validate_payment_for_user($user_id, $order_id)
{
$acf_date_format = 'Y-m-d H:i:s';
/**
* update card validity to true
*/
$post_id = 'user_'.$user_id;
update_field('carte_est_valide', true, $post_id);
/**
* update purchase date to now
*/
$date_now = date($acf_date_format);
update_field('date_d_achat', $date_now, $post_id);
/**
* update date limit validity to add 1 year
*/
$current_date_limit = get_field('date_fin_validite', $post_id);
// output is in format 'dd/mm/yyyy' which is not understood by php dates functions
// so i clean it
// -> not a reliable solution, someone can change the ouput format in dashboard
$current_date_limit = str_replace('/', '-', $current_date_limit);
// id current date limit is not in the futur, use now date
if ($current_date_limit === null)
$current_date_limit = $date_now;
else
{
// compare 2 dates : https://stackoverflow.com/q/8722806/9497573
// also I dont use strtotime to compare 2 ints,
// because i don't know if it will fail one day (2000 bug like)
$comp_current_date_limit = date_create($current_date_limit);
$comp_date_now = date_create($date_now);
$date_is_in_past = date_diff($comp_date_now, $comp_current_date_limit)->format("%R%a") < 0;
if ($date_is_in_past)
$current_date_limit = $date_now;
}
// add one year to current date limit
$time_plus_one_year = strtotime('+1 year', strtotime($current_date_limit));
$new_date_limit = date('Y-m-d H:i:s', $time_plus_one_year);
update_field('date_fin_validite', $new_date_limit, $post_id);
}
/**
* add a schedule event to delete this order_id
* after 3 days ?
* time() + 60 = one minute from now
* time() + MINUTE_IN_SECONDS = one minute from now
* -> https://codex.wordpress.org/Easier_Expression_of_Time_Constants
* -> also strtotime : https://www.php.net/manual/en/function.strtotime.php
*/
function fipf_schedule_delete_orderid($user_id, $order_id)
{
$delay = time() + MINUTE_IN_SECONDS;
wp_schedule_single_event($delay, 'fipf_orderid_deletion_event', array($user_id, $order_id));
}
/**
* action hook for the scheduled event
* TODO: ne marche pas je ne sais pas pourquoi, pas urgent a resoudre
*/
function fipf_delete_order_id_later($user_id, $order_id)
{
error_log("delete order_id[$order_id] from user_id[$user_id]");
delete_user_meta($user_id, 'fipf_order_id', $order_id);
}
add_action('fipf_orderid_deletion_event', 'fipf_delete_order_id_later', 5, 2);
/**
* @return mixed num - user_id
* bool false - if no match found
*/
function fipf_delete_order_id_on_success($current_user_id, $order_id)
{
$del_ret = delete_user_meta($current_user_id, 'fipf_order_id', $order_id);
if ($del_ret === true)
return $current_user_id;
// it means the current user didn't have this order_id
// so we look for another user
$users = get_users();
foreach ($users as $user)
{
$user_id = $user->ID;
$del_ret = delete_user_meta($user_id, 'fipf_order_id', $order_id);
if ($del_ret === true)
return $user_id;
}
return false;
}
?>

View File

@@ -1,15 +0,0 @@
<?php
function add_partenaires_PLGNTLS($customer_data){
$current_url = $_SERVER['HTTP_REFERER'];
$path_brut = parse_url($current_url, PHP_URL_PATH);
$path = trim($path_brut, '/');
if ($path === 'creation-du-compte-partenaire')
$customer_data['role'] = 'partenaire';
return $customer_data;
}
add_filter( 'xoo_el_register_new_customer_data', 'add_partenaires_PLGNTLS', 10, 1 );
?>

View File

@@ -1,55 +0,0 @@
<?php
/**
* it means someone outside wp is accessing the file, in this case kill it.
*/
if (!defined('ABSPATH')) {
die('You can not access this file!');
}
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
globals variables
const vs define : https://stackoverflow.com/questions/2447791/php-define-vs-const
*/
/* switch console_log
const CONSOLE_OFF = true;
*/
const FIPFCARD_CONSOLE_OFF = false;
/**
* a variable that will contain the name of the first script enqueued
*/
$fipfcard_first_script = null;
/**
* path to ajax.js file, from root of js dir
*/
$fipfcard_ajax_file = "utils/ajax.js";
/**
* paypal credentials
*
* LIVE :
*
* const PAYPAL_CLIENT_ID = "Aedn5e8z__hPBvKirqw5bwlhI9ChG8_N6c1xbgybYyBr4B4oP8uVzmVdH1QVKdPQKf6bWg7orPV4PDrO";
* const PAYPAL_CLIENT_SECRET = "EGeGwfHGxHxsjnC-tH8W0IL4nN3_xlc3sXFRPCQOw5uUoWae3eOgghuDKMnZc5DVGTbP6yIjVJ1BaAra";
*
* SANBOX :
*
* const PAYPAL_CLIENT_ID = "AfcmwxIXlG2ZxaMdjazX57I70BXz__aEqNWaTnqfSCI34a0V7nMbytswx7EViUjlpHs7opyrRwaH9YLl";
* const PAYPAL_CLIENT_SECRET = "EGunIhGRjPvn0Z8wXO0JsdhET30OStTAH_IyRsmhimEN23_qiRSFD-ql4tvnulKJw6TitZ-vU-ytc4A-";
*
*/
const PAYPAL_CLIENT_ID = "AfcmwxIXlG2ZxaMdjazX57I70BXz__aEqNWaTnqfSCI34a0V7nMbytswx7EViUjlpHs7opyrRwaH9YLl";
const PAYPAL_CLIENT_SECRET = "EGunIhGRjPvn0Z8wXO0JsdhET30OStTAH_IyRsmhimEN23_qiRSFD-ql4tvnulKJw6TitZ-vU-ytc4A-";
/**
* paypal api base url
*/
const PAYPAL_API_BASE_URL = "https://api-m.sandbox.paypal.com";
?>

Submodule private updated: 8b8c17b979...a86a33b46e