Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Michael Iseard
Kudos-Donations
Commits
4a30dde9
Commit
4a30dde9
authored
Jun 24, 2020
by
Michael Iseard
Browse files
Buckets of changes
parent
51e0dfc6
Changes
13
Hide whitespace changes
Inline
Side-by-side
admin/class-kudos-admin.php
View file @
4a30dde9
...
...
@@ -123,6 +123,18 @@ class Kudos_Admin {
);
add_action
(
"admin_print_scripts-
{
$transactions_page_hook_suffix
}
"
,
[
$this
,
'kudos_transactions_page_assets'
]
);
$subscriptions_page_hook_suffix
=
add_submenu_page
(
'kudos-settings'
,
/* translators: %s: Plugin name */
sprintf
(
__
(
'%s Subscriptions'
,
'kudos-donations'
),
'Kudos'
),
__
(
'Subscriptions'
,
'kudos-donations'
),
'manage_options'
,
'kudos-subscriptions'
,
[
$this
,
'subscriptions_table'
]
);
add_action
(
"admin_print_scripts-
{
$subscriptions_page_hook_suffix
}
"
,
[
$this
,
'kudos_subscriptions_page_assets'
]
);
}
/**
...
...
@@ -150,8 +162,22 @@ class Kudos_Admin {
* @since 1.1.0
*/
public
function
kudos_transactions_page_assets
()
{
wp_enqueue_style
(
$this
->
plugin_name
.
'-transactions'
,
get_asset_url
(
'kudos-admin-transactions.css'
),
[],
$this
->
version
,
'all'
);
wp_enqueue_script
(
$this
->
plugin_name
.
'-transaction'
,
get_asset_url
(
'kudos-admin-transactions.js'
),
[
'jquery'
],
$this
->
version
,
false
);
wp_enqueue_script
(
$this
->
plugin_name
.
'-transactions'
,
get_asset_url
(
'kudos-admin-transactions.js'
),
[
'jquery'
],
$this
->
version
,
false
);
wp_localize_script
(
$this
->
plugin_name
.
'-transactions'
,
'kudos'
,
[
'confirmation'
=>
__
(
'Are you sure you want to delete this transaction?'
,
'kudos-donations'
),
]);
}
/**
* Assets specific to the Kudos Subscriptions page
*
* @since 1.1.0
*/
public
function
kudos_subscriptions_page_assets
()
{
wp_enqueue_script
(
$this
->
plugin_name
.
'-subscriptions'
,
get_asset_url
(
'kudos-admin-subscriptions.js'
),
[
'jquery'
],
$this
->
version
,
false
);
wp_localize_script
(
$this
->
plugin_name
.
'-subscriptions'
,
'kudos'
,
[
'confirmation'
=>
__
(
'Are you sure you want to cancel this subscription?'
,
'kudos-donations'
),
]);
}
/**
...
...
@@ -166,9 +192,9 @@ class Kudos_Admin {
if
(
'delete'
===
$table
->
current_action
())
{
$message
=
__
(
'Transaction deleted'
,
'kudos-donations'
);
}
elseif
(
'bulk-delete'
===
$table
->
current_action
()
&&
isset
(
$_REQUEST
[
'bulk-
delete
'
]))
{
}
elseif
(
'bulk-delete'
===
$table
->
current_action
()
&&
isset
(
$_REQUEST
[
'bulk-
action
'
]))
{
/* translators: %s: Number of transactions */
$message
=
sprintf
(
__
(
'%s transaction(s) deleted'
,
'kudos-donations'
),
count
(
$_REQUEST
[
'bulk-
delete
'
]));
$message
=
sprintf
(
__
(
'%s transaction(s) deleted'
,
'kudos-donations'
),
count
(
$_REQUEST
[
'bulk-
action
'
]));
}
?>
<div
class=
"wrap"
>
...
...
@@ -194,6 +220,46 @@ class Kudos_Admin {
<?php
}
/**
* Creates the subscriptions table
*
* @since 1.1.0
*/
public
function
subscriptions_table
()
{
$table
=
new
Subscriptions_Table
();
$table
->
prepare_items
();
$message
=
''
;
if
(
'cancel'
===
$table
->
current_action
())
{
$message
=
__
(
'Subscription cancelled'
,
'kudos-donations'
);
}
elseif
(
'bulk-cancel'
===
$table
->
current_action
()
&&
isset
(
$_REQUEST
[
'bulk-action'
]))
{
/* translators: %s: Number of transactions */
$message
=
sprintf
(
__
(
'%s subscription(s) cancelled'
,
'kudos-donations'
),
count
(
$_REQUEST
[
'bulk-action'
]));
}
?>
<div
class=
"wrap"
>
<h1
class=
"wp-heading-inline"
>
<?php
_e
(
'Subscriptions'
,
'kudos-donations'
);
?>
</h1>
<?php
if
(
!
empty
(
$_REQUEST
[
's'
]))
{
?>
<span
class=
"subtitle"
>
<?php
/* translators: %s: Search term */
printf
(
__
(
'Search results for “%s”'
),
$_REQUEST
[
's'
])
?>
</span>
<?php
}
?>
<p>
<?php
_e
(
"Your recent Kudos subscriptions"
,
'kudos-donations'
);
?>
</p>
<?php
if
(
$message
)
{
?>
<div
class=
"updated below-h2"
id=
"message"
><p>
<?php
echo
esc_html
(
$message
);
?>
</p></div>
<?php
}
?>
<form
id=
"subscriptions-table"
method=
"POST"
>
<?php
$table
->
display
();
?>
</form>
</div>
<?php
}
/**
* Exports transactions if request present.
* Needs to be hooked to admin_init as it modifies headers.
...
...
@@ -205,9 +271,16 @@ class Kudos_Admin {
if
(
isset
(
$_REQUEST
[
'export_transactions'
]))
{
$table
=
new
Transactions_Table
();
$table
->
export
_transactions
();
$table
->
export
();
}
if
(
isset
(
$_REQUEST
[
'export_subscriptions'
]))
{
$table
=
new
Subscriptions_Table
();
$table
->
export
();
}
}
/**
...
...
includes/class-kudos-activator.php
View file @
4a30dde9
...
...
@@ -33,6 +33,7 @@ class Kudos_Activator {
Kudos_Logger
::
init
();
self
::
create_transactions_table
();
self
::
create_donors_table
();
self
::
create_subscriptions_table
();
self
::
set_defaults
();
}
...
...
@@ -50,14 +51,13 @@ class Kudos_Activator {
$sql
=
"CREATE TABLE
$table_name
(
id mediumint(9) NOT NULL AUTO_INCREMENT,
time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
name VARCHAR(255),
email VARCHAR(320),
value DECIMAL(7,2) NOT NULL,
currency VARCHAR(255),
status VARCHAR(255) DEFAULT 'open' NOT NULL,
method VARCHAR(255),
mode VARCHAR(255) NOT NULL,
sequence_type VARCHAR(255) NOT NULL,
customer_id VARCHAR(255),
order_id VARCHAR(255) NOT NULL,
transaction_id VARCHAR(255),
PRIMARY KEY (id)
...
...
@@ -87,7 +87,6 @@ class Kudos_Activator {
city VARCHAR(255),
country VARCHAR(255),
customer_id VARCHAR(255),
payment_frequency VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
)
$charset_collate
"
;
...
...
@@ -95,6 +94,35 @@ class Kudos_Activator {
dbDelta
(
$sql
);
}
/**
* Creates the subscription table
*
* @since 1.1.0
*/
private
static
function
create_subscriptions_table
()
{
global
$wpdb
;
$charset_collate
=
$wpdb
->
get_charset_collate
();
$table_name
=
$wpdb
->
prefix
.
"kudos_subscriptions"
;
//get the database table prefix to create my new table
$sql
=
"CREATE TABLE
$table_name
(
id mediumint(9) NOT NULL AUTO_INCREMENT,
time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
value DECIMAL(7,2) NOT NULL,
currency VARCHAR(255),
frequency VARCHAR(255) NOT NULL,
customer_id VARCHAR(255),
transaction_id VARCHAR(255),
k_subscription_id VARCHAR(255),
subscription_id VARCHAR(255),
status VARCHAR(255),
PRIMARY KEY (id)
)
$charset_collate
"
;
require_once
(
ABSPATH
.
'wp-admin/includes/upgrade.php'
);
dbDelta
(
$sql
);
}
/**
* Adds default options if not already set
*
...
...
includes/class-kudos-donor.php
View file @
4a30dde9
...
...
@@ -4,28 +4,21 @@ namespace Kudos;
use
wpdb
;
class
Kudos_Donor
{
class
Kudos_Donor
extends
Database_Object
{
public
const
TABLE
=
"kudos_donors"
;
/**
* @var wpdb
*/
private
$wpdb
;
const
TABLE
=
"kudos_donors"
;
protected
$wpdb
;
/**
* Kudos_Donor constructor.
*
* @since 1.1.0
* @var string
*/
public
function
__construct
()
{
global
$wpdb
;
$this
->
wpdb
=
$wpdb
;
}
protected
$table
;
/**
* @param string $email
* @param string $customer_id
* @param string $payment_frequency
* @param string $name
* @param string|null $street
* @param string|null $postcode
...
...
@@ -35,65 +28,31 @@ class Kudos_Donor {
* @return bool|false|int
* @since 1.1.0
*/
public
function
create_donor
(
$email
,
$customer_id
,
$payment_frequency
,
$name
=
null
,
$street
=
null
,
$postcode
=
null
,
$city
=
null
,
$country
=
null
)
{
return
$this
->
wpdb
->
insert
(
$this
->
wpdb
->
prefix
.
self
::
TABLE
,
[
'email'
=>
$email
,
'name'
=>
$name
,
'street'
=>
$street
,
'postcode'
=>
$postcode
,
'city'
=>
$city
,
'country'
=>
$country
,
'customer_id'
=>
$customer_id
,
'payment_frequency'
=>
$payment_frequency
]
);
public
function
insert_donor
(
$email
,
$customer_id
,
$name
=
null
,
$street
=
null
,
$postcode
=
null
,
$city
=
null
,
$country
=
null
)
{
return
$this
->
insert
([
'email'
=>
$email
,
'name'
=>
$name
,
'street'
=>
$street
,
'postcode'
=>
$postcode
,
'city'
=>
$city
,
'country'
=>
$country
,
'customer_id'
=>
$customer_id
,
]);
}
/**
* Update donor by email
*
* @param string $email
* @param string $payment_frequency
* @param string $name
* @param string|null $street
* @param string|null $postcode
* @param string|null $city
* @param string|null $country
* @param array $array
*
* @return bool|false|int
* @since 1.1.0
*/
public
function
update_donor
(
$email
,
$payment_frequency
,
$name
=
null
,
$street
=
null
,
$postcode
=
null
,
$city
=
null
,
$country
=
null
)
{
return
$this
->
wpdb
->
update
(
$this
->
wpdb
->
prefix
.
self
::
TABLE
,
[
'name'
=>
$name
,
'street'
=>
$street
,
'postcode'
=>
$postcode
,
'city'
=>
$city
,
'country'
=>
$country
,
'payment_frequency'
=>
$payment_frequency
],
[
'email'
=>
$email
,
]
);
}
/**
* @param string $email // Email address used to find a donor
* @param array $fields // Specify fields to fetch from database
* @return false|int
*
* @return array|object|void|null
* @since 1.1.0
* * @since 1.1.0
*/
public
function
get_donor
(
$email
,
array
$fields
=
[
'*'
])
{
$wpdb
=
$this
->
wpdb
;
$table
=
$this
->
wpdb
->
prefix
.
self
::
TABLE
;
$columns
=
implode
(
', '
,
$fields
);
public
function
update_donor
(
$email
,
$array
)
{
return
$wpdb
->
get_row
(
$wpdb
->
prepare
(
"
SELECT
$columns
FROM
$table
WHERE email = '%s'
"
,
$email
)
);
return
$this
->
update
(
$array
,
[
'email'
=>
$email
]);
}
}
\ No newline at end of file
includes/class-kudos-invoice.php
View file @
4a30dde9
...
...
@@ -2,6 +2,7 @@
namespace
Kudos
;
use
Composer\DependencyResolver\Transaction
;
use
Dompdf\Dompdf
;
use
Throwable
;
...
...
@@ -88,17 +89,12 @@ class Kudos_Invoice
'company_name'
=>
get_option
(
'_kudos_invoice_company_name'
),
'company_address'
=>
get_option
(
'_kudos_invoice_company_address'
),
'vat_number'
=>
get_option
(
'_kudos_invoice_vat_number'
),
'donor_name'
=>
$transaction
->
name
,
'donor_street'
=>
$transaction
->
street
,
'donor_postcode'
=>
$transaction
->
postcode
,
'donor_city'
=>
$transaction
->
city
,
];
$donorClass
=
new
Kudos_Donor
();
$donor
=
$donorClass
->
get_donor
(
$transaction
->
email
);
if
(
$donor
)
{
$invoiceArray
[
'donor_name'
]
=
$donor
->
name
;
$invoiceArray
[
'donor_street'
]
=
$donor
->
street
;
$invoiceArray
[
'donor_postcode'
]
=
$donor
->
postcode
;
$invoiceArray
[
'donor_city'
]
=
$donor
->
city
;
}
try
{
$dompdf
->
loadHtml
(
$twig
->
render
(
'pdf/invoice.html.twig'
,
$invoiceArray
)
...
...
@@ -154,14 +150,9 @@ class Kudos_Invoice
*/
public
static
function
regenerate_invoices
()
{
global
$wpdb
;
$table
=
$wpdb
->
prefix
.
Kudos_Transaction
::
TABLE
;
$query
=
"
SELECT * from
$table
"
;
$transactions
=
new
Kudos_Transaction
();
$transactions
=
$transactions
->
get_transactions
();
$transactions
=
$wpdb
->
get_results
(
$query
);
$n
=
0
;
foreach
(
$transactions
as
$transaction
)
{
...
...
includes/class-kudos-mollie.php
View file @
4a30dde9
...
...
@@ -4,7 +4,9 @@ namespace Kudos;
use
Mollie\Api\Exceptions\ApiException
;
use
Mollie\Api\MollieApiClient
;
use
Mollie\Api\Resources\Customer
;
use
Mollie\Api\Resources\Payment
;
use
Mollie\Api\Resources\Subscription
;
use
WP_Error
;
use
WP_HTTP_Response
;
use
WP_REST_Request
;
...
...
@@ -104,23 +106,24 @@ class Kudos_Mollie
return
false
;
}
/**
* Creates a payment and returns it as an object
*
* @param $value
* @param string $redirectUrl
* @param string|null $name
* @param string|null $email
*
* @param $customerId
*
* @return bool|object
* @since 1.0.0
*/
public
function
create_payment
(
$value
,
$redirectUrl
,
$name
=
null
,
$email
=
null
,
$customerId
=
null
)
{
/**
* Creates a payment and returns it as an object
*
* @param $value
* @param string $redirectUrl
* @param string|null $payment_frequency
* @param string|null $name
* @param string|null $email
*
* @param $customerId
*
* @return bool|object
* @since 1.0.0
*/
public
function
create_payment
(
$value
,
$payment_frequency
,
$redirectUrl
,
$name
=
null
,
$email
=
null
,
$customerId
=
null
)
{
$mollieApi
=
$this
->
mollieApi
;
$order_id
=
time
();
$order_id
=
'kdo_'
.
time
();
$currency
=
'EUR'
;
$value
=
number_format
(
$value
,
2
);
...
...
@@ -130,17 +133,36 @@ class Kudos_Mollie
$redirectUrl
=
add_query_arg
(
'_wpnonce'
,
wp_create_nonce
(
'check_kudos_order-'
.
$order_id
),
$redirectUrl
);
}
// Set payment frequency
switch
(
$payment_frequency
)
{
case
"12 months"
:
$frequency_text
=
__
(
'Yearly'
,
'kudos-donations'
);
$sequenceType
=
'first'
;
break
;
case
"1 month"
:
$frequency_text
=
__
(
'Monthly'
,
'kudos-donations'
);
$sequenceType
=
'first'
;
break
;
case
"oneoff"
:
default
:
$frequency_text
=
__
(
'One off'
,
'kudos-donations'
);
$sequenceType
=
'oneoff'
;
}
$paymentArray
=
[
"amount"
=>
[
"currency"
=>
$currency
,
"value"
=>
$value
],
"redirectUrl"
=>
$redirectUrl
,
"webhookUrl"
=>
rest_url
(
'kudos/v1/mollie/webhook'
),
// "webhookUrl" => rest_url('kudos/v1/mollie/payment/webhook'),
"sequenceType"
=>
$sequenceType
,
"webhookUrl"
=>
'http://d38699244220.ngrok.io/wp-json/kudos/v1/mollie/payment/webhook'
,
/* translators: %s: The order id */
"description"
=>
sprintf
(
__
(
"Kudos
Payment
- %s"
,
'kudos-donations'
),
$order_id
),
"description"
=>
sprintf
(
__
(
"Kudos
Donation (%s)
- %s"
,
'kudos-donations'
),
$frequency_text
,
$order_id
),
'metadata'
=>
[
'order_id'
=>
$order_id
,
'payment_frequency'
=>
$payment_frequency
,
'email'
=>
$email
,
'name'
=>
$name
]
...
...
@@ -155,7 +177,7 @@ class Kudos_Mollie
$payment
=
$mollieApi
->
payments
->
create
(
$paymentArray
);
$transaction
=
$this
->
transaction
;
$transaction
->
create
_transaction
(
$order_id
,
$value
,
$currency
,
$payment
->
status
,
$payment
->
sequenceType
,
$email
,
$name
);
$transaction
->
insert
_transaction
(
$order_id
,
$customerId
,
$value
,
$currency
,
$payment
->
status
,
$payment
->
sequenceType
);
return
$payment
;
...
...
@@ -166,6 +188,63 @@ class Kudos_Mollie
}
/**
* Create a subscription
*
* @param object $transaction
* @param $interval
* @param null $times
*
* @return bool|object
* @since 1.1.0
*/
public
function
create_subscription
(
$transaction
,
$interval
,
$times
=
null
)
{
$mollieApi
=
$this
->
mollieApi
;
$customer_id
=
$transaction
->
customer_id
;
$k_subscription_id
=
'kds_'
.
time
();
$startDate
=
date
(
"Y-m-d"
,
strtotime
(
"+"
.
$interval
));
$currency
=
'EUR'
;
$value
=
number_format
(
$transaction
->
value
,
2
);
$subscriptionArray
=
[
"amount"
=>
[
"value"
=>
$value
,
"currency"
=>
$currency
],
"interval"
=>
$interval
,
"startDate"
=>
$startDate
,
"description"
=>
sprintf
(
__
(
'Kudos Subscription (%s) - %s'
,
'kudos-donations'
),
$interval
,
$k_subscription_id
),
// "webhookUrl" => rest_url('kudos/v1/mollie/subscription/webhook'),
"webhookUrl"
=>
'http://d38699244220.ngrok.io/wp-json/kudos/v1/mollie/subscription/webhook'
,
"metadata"
=>
[
"subscription_id"
=>
$k_subscription_id
]
];
if
(
$times
)
{
$subscriptionArray
[
"times"
]
=
$times
;
}
try
{
/** @var Customer $customer */
$customer
=
$mollieApi
->
customers
->
get
(
$customer_id
);
$subscription
=
$customer
->
createSubscription
(
$subscriptionArray
);
if
(
$subscription
)
{
$kudos_subscription
=
new
Kudos_Subscription
();
$kudos_subscription
->
insert_subscription
(
$transaction
->
transaction_id
,
$customer_id
,
$interval
,
$value
,
$currency
,
$k_subscription_id
,
$subscription
->
id
,
$subscription
->
status
);
return
$subscription
;
}
return
false
;
}
catch
(
ApiException
$e
)
{
$this
->
logger
->
log
(
$e
->
getMessage
(),
'CRITICAL'
,
[
$customer_id
,
$subscriptionArray
]);
return
false
;
}
}
/**
* @param $email
* @param $name
...
...
@@ -194,6 +273,20 @@ class Kudos_Mollie
}
public
function
cancel_subscription
(
$customerId
,
$subscriptionId
)
{
$mollieApi
=
$this
->
mollieApi
;
try
{
$customer
=
$mollieApi
->
customers
->
get
(
$customerId
);
return
$customer
->
cancelSubscription
(
$subscriptionId
);
}
catch
(
ApiException
$e
)
{
$this
->
logger
->
log
(
$e
->
getMessage
(),
'CRITICAL'
,
[
$customerId
,
$subscriptionId
]);
return
false
;
}
}
/**
* Register webhook using rest
*
...
...
@@ -201,7 +294,9 @@ class Kudos_Mollie
* @return void
*/
public
function
register_webhook
()
{
register_rest_route
(
'kudos/v1'
,
'mollie/webhook'
,
[
// Payment webhook
register_rest_route
(
'kudos/v1'
,
'mollie/payment/webhook'
,
[
'methods'
=>
'POST'
,
'callback'
=>
[
$this
,
'rest_api_mollie_webhook'
],
'args'
=>
[
...
...
@@ -210,6 +305,17 @@ class Kudos_Mollie
]
]
]
);
// Subscription webhook
register_rest_route
(
'kudos/v1'
,
'mollie/subscription/webhook'
,
[
'methods'
=>
'POST'
,
'callback'
=>
[
$this
,
'rest_api_mollie_webhook'
],
'args'
=>
[
'id'
=>
[
'required'
=>
true
]
]
]
);
}
/**
...
...
@@ -307,27 +413,38 @@ class Kudos_Mollie
$order_id
=
$payment
->
metadata
->
order_id
;
$transaction_id
=
$payment
->
id
;
$status
=
$payment
->
status
;
$this
->
transaction
->
update_transaction
(
$order_id
,
$transaction_id
,
$status
,
$payment
->
method
);
$sequence_type
=
$payment
->
sequenceType
;
$this
->
transaction
->
update_transaction
(
$order_id
,
[
'status'
=>
$status
,
'transaction_id'
=>
$transaction_id
,
'method'
=>
$payment
->
method
]);
// Send email receipt on success
$mailer
=
new
Kudos_Mailer
();
if
(
$payment
->
isPaid
()
&&
!
$payment
->
hasRefunds
()
&&
!
$payment
->
hasChargebacks
())
{
// Get transaction
$transaction
=
$this
->
transaction
->
get_transaction
(
$order_id
);
$transaction
=
$this
->
transaction
->
get_transaction
_by
([
'order_id'
=>
$order_id
]
);
// Create invoice
$this
->
invoice
->
generate_invoice
(
$transaction
);
// Send email - email setting is checked in mailer
if
(
$transaction
->
email
)
{
// Send email - email setting is checked in mailer
$mailer
->
send_invoice
(
$transaction
);
// Set up recurring payment if sequence is first
if
(
$sequence_type
===
'first'
)
{
return
$this
->
create_subscription
(
$transaction
,
$payment
->
metadata
->
payment_frequency
);
}
}
}
/* translators: %s: Mollie */
$note
=
sprintf
(
__
(
'Webhook requested by %s.'
,
'kudos-donations'
),
'Mollie'
);
$this
->
logger
->
log
(
$note
,
'INFO'
,
[
'order_id'
=>
$order_id
,
'status'
=>
$status
]);
$this
->
logger
->
log
(
$note
,
'INFO'
,
[
'order_id'
=>
$order_id
,
'status'
=>
$status
,
'sequence_type'
=>
$sequence_type
]);
return
$response
;
}
...
...
includes/class-kudos-transaction.php
View file @
4a30dde9
...
...
@@ -4,79 +4,106 @@ namespace Kudos;
use
wpdb
;
class
Kudos_Transaction
{
class
Kudos_Transaction
extends
Database_Object
{
public
const
TABLE
=
"kudos_transactions"
;
/**
* @var wpdb
*/
private
$wpdb
;
const
TABLE
=
"kudos_transactions"
;
public
function
__construct
()
{
global
$wpdb
;
$this
->
wpdb
=
$wpdb
;