spacejewel-ipn-communication/source/controllers/Hookmanager/Hookmanager.php

251 lines
7.6 KiB
PHP
Raw Permalink Normal View History

2018-06-07 10:56:13 +00:00
<?php
2018-06-07 14:14:25 +00:00
use \Slim\Http\Request as Request;
use \Slim\Http\Response as Response;
use Yadakhov\Json as Json;
2018-06-07 14:14:25 +00:00
2018-06-07 10:56:13 +00:00
// The hookmanager is the web-exposed class that allows you to manage a user within the billing system.
// This system takes care of CRUD operations on customers. It doesn't keep track of order but it does suspend
// you if you don't pay.
class Hookmanager
{
2018-06-07 14:14:25 +00:00
private $Customer;
2018-06-07 14:14:25 +00:00
private $Renderview;
2018-06-07 14:14:25 +00:00
private $APITools;
2018-06-07 14:14:25 +00:00
private $Mailer;
2019-01-30 13:39:28 +00:00
private $VirtualminHandler;
2019-01-30 13:39:28 +00:00
// Can be overloaded by child classes in order to add new features.
// alert types are defined by wordpress.
protected $alertTypes =
[
"subscription_created",
"subscription_updated",
"subscription_cancelled",
"subscription_payment_succeeded",
"subscription_payment_failed",
"subscription_payment_refunded",
2018-06-08 10:56:33 +00:00
"payment_refunded"
2018-06-08 10:56:33 +00:00
];
private $AppBaseURL;
2018-06-07 14:14:25 +00:00
public function __construct()
2018-06-07 10:56:13 +00:00
{
2019-01-30 13:39:28 +00:00
// TODO: Switch project to MVC structuring.
// This doesn't make much sense.
2018-06-07 14:14:25 +00:00
$this->Customer = new Customer();
$this->Renderview = new EmailRenderer();
$this->APITools = new ApplicationAPI();
$this->JsonHelper = new Json();
2019-01-30 13:39:28 +00:00
$this->VirtualminHandler = new VirtualminHandler();
$this->PackageController = new PackageController();
2018-06-07 14:14:25 +00:00
// Create mailer when needed
}
2018-06-08 14:46:18 +00:00
private function keyValidate($keyFromURI)
{
// FIXME: Theoretically, this method does not work.
// TODO: Devise a new way to validate keys without user ID
if($this->APITools->keysMatch($keyFromURI))
{
return true;
}
else
{
return false;
}
}
/**
*
* This function detects the intent within the payload.
* After doing so, it returns the intent back to you so that you can perfom the correct redirect
*
*/
public function detectPayloadIntent(Request $request, Response $response, $args)
2018-06-07 14:14:25 +00:00
{
if ($this->keyValidate($keyFromURI))
{
$data = $this->getStructuredVariableList($Request);
foreach ($this->alertTypes as $types => $value)
{
if ($types == $data['alert_name'])
{
$sVal = $value;
}
}
2018-06-08 10:56:33 +00:00
// Uses the response and redirect objects and the intent from the current request to redirect it
$this->redirectAlert($request, $response, $sVal);
}
2018-06-07 14:14:25 +00:00
throw new LogicException("Illegal API key");
2018-06-07 14:14:25 +00:00
}
2018-06-08 10:56:33 +00:00
// The response and request method is passed by the redirecting method
2019-01-30 13:39:28 +00:00
// KISS and DRY might not apply here
// This method choses what to do based on the request's "intent".
private function redirectAlert(Request $Request, Response $response, $intent)
2018-06-08 10:56:33 +00:00
{
switch ($intent)
{
// This serves as a proxy to all other methods
2018-06-08 10:56:33 +00:00
case "subscription_created":
$this->EventSubscriptionCreated($Request, $response);
2018-06-08 10:56:33 +00:00
break;
case "subscription_updated":
2018-06-08 14:57:49 +00:00
$this->EventSubscriptionUpdated($Request, $response);
2018-06-08 10:56:33 +00:00
break;
case "subscription_cancelled":
$this->EventSubscriptionCancelled($Request, $response);
2018-06-08 10:56:33 +00:00
break;
case "subscription_payment_successful":
$this->EventSubscriptionPaymentSuccess($Request, $response);
2018-06-08 10:56:33 +00:00
break;
case "subscription_payment_failed":
$this->EventSubscriptionPaymentFailed($Request, $response);
2018-06-08 10:56:33 +00:00
break;
case "subscription_payment_refunded":
$this->EventSubscriptionPaymentRefunded($Request, $response);
2018-06-08 10:56:33 +00:00
break;
2018-06-08 10:56:33 +00:00
default:
$this->JsonHelper->set
([
"status" => "fail",
2019-01-30 13:39:28 +00:00
"message" => "Error: Invalid alert type!",
"code" => 500
]);
// Writing JsonHelper while it's not a string but an object will cause it to fire it's __toString method, which
// assembles the JSON defined in the array notation as written above in the form of an array.
// Calling Slim's withStatus method gives us the ability to tell the client something went wrong.
return $response->write($this->JsonHelper)->withStatus(500);
2018-06-08 10:56:33 +00:00
}
}
// Return POST variable list in a structured array, DRY
private function getStructuredVariableList(Request $request)
{
2019-01-30 13:39:28 +00:00
return $request->getParsedBody();
}
2019-01-30 13:39:28 +00:00
// These methods below interact directly with the Virtualmin controller.
// args should also provide email and ip, not only plan
public function EventSubscriptionCreated(Request $request, Response $response, $args)
{
2019-01-30 13:39:28 +00:00
// Creates a subscription in the database.
// This method sends information directly to the virtualmin controller.
$combinedArguments = array_merge($this->PackageController->getDefaultOptionsArray(), $this->PackageController->selectPackage($args['package']));
$this->VirtualminHandler->CreateVirtualServer($domain, $password, $combinedArguments);
2018-06-07 14:14:25 +00:00
2018-06-07 10:56:13 +00:00
}
public function EventSubscriptionUpdated(Request $request, Response $response, $args)
2018-06-07 10:56:13 +00:00
{
// Update user information if necessary
}
public function EventSubscriptionCancelled(Request $request, Response $response, $args)
2018-06-07 10:56:13 +00:00
{
// Suspend user's domain name as stated on DB
// Delete after 30 days
}
public function EventSubscriptionPaymentSuccess(Request $request, Response $response, $args)
2018-06-07 10:56:13 +00:00
{
// Renew user's subscription within billing system
// Install hosting account if this is the user's first time and send out instructions email
}
// TODO: Lenient business logic
public function EventSubscriptionPaymentFailed(Request $request, Response $response, $args)
2018-06-07 10:56:13 +00:00
{
// Add payment strike to user account
// After three strikes, warn user that the system has waived further attempts. Suspend their account
// Give user an ultimatum: Pay or remain suspended
// If user fails to pay during the next 7 days, permanently suspend their account (Reject further payments. Remove user from paddle first)
// If payment is successful afterwards, remove all payment strikes (Success logic should execute automatically)
}
public function EventSubscriptionPaymentRefunded(Request $request, Response $response, $args)
2018-06-07 10:56:13 +00:00
{
// Ban customer from billing system
// Delete all customer data
}
2019-01-30 13:39:28 +00:00
private function postProcessFor($domain, $password)
{
}
2018-06-07 10:56:13 +00:00
}