core/modules/shop/ShopTransactionController.php
<?php
require_once 'ShopController.php';
class ShopTransactionController extends ShopController
{
public function view()
{
$transaction = new TransactionModel();
Ajde::app()->getDocument()->setTitle(trans('Your order'));
// Get from ID
if ($this->hasNotEmpty('id')) {
if ($transaction->loadByField('secret', $this->getId()) !== false) {
$this->getView()->assign('source', 'id');
}
} else {
// Get existing transaction / user details
$session = new Ajde_Session('AC.Shop');
if ($session->has('currentTransaction') && $transaction->loadByPK($session->get('currentTransaction'))) {
$this->getView()->assign('source', 'session');
}
}
$this->getView()->assign('transaction', $transaction);
return $this->render();
}
public function export()
{
$transaction = new TransactionModel();
// Get from ID
if (!($this->hasNotEmpty('id') && $transaction->loadByField('secret', $this->getId()) !== false)) {
Ajde::app()->getResponse()->redirectNotFound();
}
/** @var Ajde_Document_Format_Generated $doc */
$doc = Ajde::app()->getDocument();
$url = config('app.rootUrl').'shop/transaction:view/'.$this->getId().'.html';
$filename = $transaction->getOrderId();
if ($this->getFormat() === 'pdf') {
$pdf = $doc->generate([
'url' => $url,
'filename' => $filename,
]);
$doc->setContentType('application/pdf');
Ajde::app()->getResponse()->addHeader('Content-Disposition',
'attachment; filename="'.$filename.'.pdf"');
return $pdf;
}
}
public function setup()
{
// Get existing transaction / user details
$transaction = new TransactionModel();
$session = new Ajde_Session('AC.Shop');
$user = UserModel::getLoggedIn();
if ($session->has('currentTransaction') && $transaction->loadByPK($session->get('currentTransaction'))) {
$name = $transaction->name;
$email = $transaction->email;
$address = $transaction->shipment_address;
$zipcode = $transaction->shipment_zipcode;
$city = $transaction->shipment_city;
$region = $transaction->shipment_region;
$country = $transaction->shipment_country;
$comment = $transaction->comment;
} elseif ($user !== false) {
// Insert intermediate transaction to save country and present user
// with shipping options, ignore response
$this->setupJson($user);
$name = $user->fullname;
$email = $user->email;
$address = $user->address;
$zipcode = $user->zipcode;
$city = $user->city;
$region = $user->region;
$country = $user->country;
$comment = '';
} else {
// Insert intermediate transaction to save cart and allow user to
// see shipping options when country is choosen
$this->setupJson(true);
$name = '';
$email = '';
$address = '';
$zipcode = '';
$city = '';
$region = '';
$country = '';
$comment = '';
}
$view = $this->getView();
$view->assign('name', $name);
$view->assign('email', $email);
$view->assign('address', $address);
$view->assign('zipcode', $zipcode);
$view->assign('city', $city);
$view->assign('region', $region);
$view->assign('country', $country);
$view->assign('comment', $comment);
$view->assign('user', $user);
return $this->render();
}
public function shipment()
{
$transaction = new TransactionModel();
$session = new Ajde_Session('AC.Shop');
if ($session->has('currentTransaction') && $transaction->loadByPK($session->get('currentTransaction'))) {
if (Ajde::app()->getRequest()->has('country')) {
$transaction->shipment_country = Ajde::app()->getRequest()->getParam('country');
$transaction->save();
}
$shipment = new ShippingModel($transaction);
$method = $transaction->shipment_method;
if (empty($method) || !$shipment->isAvailable($method)) {
$method = $shipment->getFirstMethod()->getName();
}
} else {
$shipment = false;
$method = false;
$transaction = false;
}
$this->getView()->assign('method', $method);
$this->getView()->assign('shipment', $shipment);
$this->getView()->assign('transaction', $transaction);
return $this->render();
}
public function setupJson($source = false)
{
$request = Ajde::app()->getRequest();
// Init vars
$name = null;
$email = null;
$address = null;
$zipcode = null;
$city = null;
$region = null;
$country = null;
$shipmentMethod = null;
$comment = null;
if ($source === false) {
// Read request
$name = $request->getPostParam('name', false);
$email = $request->getPostParam('email', false);
$address = $request->getPostParam('shipment_address', false);
$zipcode = $request->getPostParam('shipment_zipcode', false);
$city = $request->getPostParam('shipment_city', false);
$region = $request->getPostParam('shipment_region', false);
$country = $request->getPostParam('shipment_country', false);
$shipmentMethod = $request->getPostParam('shipment_method', false);
$comment = $request->getPostParam('comment', false);
} else {
if ($source instanceof Ajde_User) {
// Read user
$name = $source->fullname;
$email = $source->email;
$address = $source->address;
$zipcode = $source->zipcode;
$city = $source->city;
$region = $source->region;
$country = $source->country;
$shipmentMethod = false;
$comment = false;
}
}
// Return when fields are not complete
if ($source === false) {
if (
empty($name) ||
empty($email) ||
empty($address) ||
empty($zipcode) ||
empty($city) ||
empty($country)
) {
return [
'success' => false,
'message' => trans('Not all your details are filled out'),
];
}
if (Ajde_Component_String::validEmail($email) === false) {
return [
'success' => false,
'message' => trans('Please provide a valid e-mail address'),
];
}
if (empty($shipmentMethod)) {
return [
'success' => false,
'message' => trans('Please choose a shipment method'),
];
}
}
// Check for current transaction
$transaction = new TransactionModel();
$session = new Ajde_Session('AC.Shop');
if ($session->has('currentTransaction') && $transaction->loadByPK($session->get('currentTransaction'))) {
// Edit existing transaction
$method = 'save';
} else {
// Insert new transaction
$method = 'insert';
}
// Update transaction info
$transaction->name = $name;
$transaction->email = $email;
$transaction->shipment_address = $address;
$transaction->shipment_zipcode = $zipcode;
$transaction->shipment_city = $city;
$transaction->shipment_region = $region;
$transaction->shipment_country = $country;
$transaction->shipment_method = $shipmentMethod;
$transaction->comment = $comment;
// Save info to user
if ($user = $this->getLoggedInUser()) {
if ($request->hasPostParam('save_details', false)) {
$user->address = $address;
$user->zipcode = $zipcode;
$user->city = $city;
$user->region = $region;
$user->country = $country;
$user->save();
$user->login();
}
$transaction->user = $user->getPK();
}
// Update shipping total
$shipping = new ShippingModel($transaction);
$transaction->shipment_cost = 0;
if (!empty($shipmentMethod) && $shipping->isAvailable($shipmentMethod)) {
$transaction->shipment_cost = $shipping->getMethod($shipmentMethod)->getTotal();
}
// Insert new transaction
if ($method === 'insert') {
if ($transaction->insert()) {
$this->updateFromCart($transaction);
$session = new Ajde_Session('AC.Shop');
$session->set('currentTransaction', $transaction->getPK());
if (!$transaction->shipment_itemsqty > 0) {
return [
'success' => false,
'message' => trans('No items added to current order'),
];
}
return [
'success' => true,
];
}
return [
'success' => false,
'message' => trans('Something went wrong'),
];
}
$transaction->payment_amount = $transaction->shipment_itemstotal + $transaction->shipment_cost;
// Update current transaction
if ($transaction->save()) {
if (!$transaction->shipment_itemsqty > 0) {
return [
'success' => false,
'message' => trans('No items added to current transaction'),
];
}
return [
'success' => true,
];
}
// Everything else failed
return [
'success' => false,
'message' => trans('Something went wrong'),
];
}
public function updateFromCart(Ajde_Shop_Transaction $transaction)
{
$cart = new CartModel();
$cart->loadCurrent();
if ($cart->countItems() > 0) {
$transaction->shipment_description = $cart->getHtmlSummaryTable();
$transaction->shipment_itemsqty = $cart->countQty();
$transaction->shipment_itemsvatamount = $cart->getItems()->getVATAmount();
$transaction->shipment_itemstotal = $cart->getItems()->getTotal();
$transaction->payment_amount = $transaction->shipment_itemstotal + $transaction->shipment_cost;
} else {
$transaction->shipment_description = '';
$transaction->shipment_itemsqty = 0;
$transaction->shipment_itemsvatamount = 0;
$transaction->shipment_itemstotal = 0;
$transaction->payment_amount = 0;
}
$transaction->setItemsFromCart($cart);
$transaction->save();
}
public function update()
{
// Check for current transaction
$transaction = new TransactionModel();
$session = new Ajde_Session('AC.Shop');
if ($session->has('currentTransaction') && $transaction->loadByPK($session->get('currentTransaction'))) {
$this->updateFromCart($transaction);
}
Ajde_Session_Flash::alert(trans('Your order has been updated', 'shop'));
$this->redirect('shop/transaction:setup');
// $this->setAction('view');
// return $this->view();
}
public function cancel()
{
// Edit existing transaction?
$transaction = new TransactionModel();
$session = new Ajde_Session('AC.Shop');
if ($session->has('currentTransaction') && $transaction->loadByPK($session->get('currentTransaction'))) {
$transaction->payment_status = 'cancelled';
$transaction->save();
$session->destroy();
}
Ajde_Session_Flash::alert(trans('Your order has been cancelled', 'shop'));
$this->redirect('shop');
}
public function payment()
{
$transaction = new TransactionModel();
$session = new Ajde_Session('AC.Shop');
if ($session->has('currentTransaction') && $transaction->loadByPK($session->get('currentTransaction'))) {
if (!$transaction->shipment_itemsqty > 0) {
$this->redirect('shop');
}
}
$this->getView()->assign('transaction', $transaction);
return $this->render();
}
public function resetPayment()
{
$transaction = new TransactionModel();
$session = new Ajde_Session('AC.Shop');
// Get transaction from ID if available
if ($this->hasNotEmpty('id')) {
if ($transaction->loadByField('secret', $this->getId()) !== false) {
$session->set('currentTransaction', $transaction->getPK());
}
}
if ($session->has('currentTransaction') && $transaction->loadByPK($session->get('currentTransaction'))) {
$transaction->payment_provider = null;
$transaction->payment_status = 'pending';
$transaction->secret_archive = $transaction->secret_archive.$transaction->secret.PHP_EOL;
$transaction->secret = $transaction->generateSecret();
$transaction->save();
}
$this->redirect('shop/transaction:payment');
}
public function paymentJson()
{
$request = Ajde::app()->getRequest();
$provider = $request->getPostParam('provider', false);
if (empty($provider)) {
return [
'success' => false,
'message' => trans('Please choose a payment provider'),
];
}
// Check for current transaction
$transaction = new TransactionModel();
$session = new Ajde_Session('AC.Shop');
if ($session->has('currentTransaction') && $transaction->loadByPK($session->get('currentTransaction'))) {
if ($transaction->payment_status !== 'pending') {
return [
'success' => false,
'message' => trans('Payment already initiated, please refresh this page'),
];
}
} else {
return [
'success' => false,
'message' => trans('No current order found'),
];
}
$transaction->payment_provider = $provider;
$provider = $transaction->getProvider();
$redirectUrl = $provider->getRedirectUrl();
if ($redirectUrl !== false) {
$transaction->payment_status = 'requested';
$transaction->save();
if ($provider->usePostProxy()) {
$this->setAction('postproxy');
$proxy = $this->getView();
$proxy->assign('provider', $provider);
return [
'success' => true,
'postproxy' => $proxy->render(),
];
}
return [
'success' => true,
'redirect' => $redirectUrl,
];
}
return [
'success' => false,
'message' => 'Could not contact the payment provider, please try again',
];
}
public function complete()
{
$cart = new CartModel();
$cart->loadCurrent();
$cart->emptyItems();
// Get existing transaction
$transaction = new TransactionModel();
$session = new Ajde_Session('AC.Shop');
if ($session->has('currentTransaction')) {
$transaction->loadByPK($session->get('currentTransaction'));
}
$session->destroy();
$this->getView()->assign('transaction', $transaction);
return $this->render();
}
public function refused()
{
return $this->render();
}
public function callback()
{
$providerName = $this->getId();
$provider = Ajde_Shop_Transaction_Provider::getProvider($providerName);
$status = $provider->updatePayment();
if ($status['success'] === true) {
$transaction = $status['transaction'];
if (isset($transaction)) {
$this->mailUser($transaction);
$this->mailUpdateAdmin($transaction, 'Order completed');
}
$this->redirect('shop/transaction:complete');
} else {
$transaction = $status['transaction'];
if (isset($transaction)) {
$this->mailUpdateAdmin($transaction, 'Order refused');
}
$this->redirect('shop/transaction:refused');
}
}
public function startNew()
{
$session = new Ajde_Session('AC.Shop');
$session->destroy();
return $this->redirect('shop/cart');
}
public function mailUpdateAdmin(TransactionModel $transaction, $subject = null)
{
$recipient = config('app.email');
$mailer = new Ajde_Mailer();
$mailer->SendQuickMail($recipient, $recipient, config('app.title'),
isset($subject) ? $subject : 'Order update', $transaction->getOverviewHtml());
}
public function mailUser(TransactionModel $transaction)
{
$viewLink = config('app.rootUrl').'shop/transaction:view/'.$transaction->secret.'.html';
$mailer = new Ajde_Mailer();
$mailer->sendUsingModel('your_order', $transaction->email, $transaction->name, [
'viewlink' => $viewLink,
]);
}
/**
* @param TransactionItemModel $transaction
*
* @deprecated use mailUser
*
* @throws Ajde_Core_Exception_Deprecated
* @throws Ajde_Exception
* @throws Exception
* @throws phpmailerException
*/
public function mailUserDeprecated(TransactionItemModel $transaction)
{
throw new Ajde_Core_Exception_Deprecated();
$mailer = new Ajde_Mailer();
$mailer->IsMail(); // use php mail()
$mailer->AddAddress($transaction->email, $transaction->name);
$mailer->From = config('app.email');
$mailer->FromName = config('app.title');
$mailer->Subject = 'Your order';
$mailer->Body = '<h2>Your order on '.config('app.title').'</h2>'.
'<p>Thank you for shopping with us. We will ship your items as soon as possible if you chose for delivery.<br/>'.
'To view the status of your order, please click this link:</p>'.
'<p><a href=\''.config('app.rootUrl').'shop/transaction:view/'.$transaction->secret.'.html\'>View your order status</a></p>'.
'<p>Hope to welcome you again soon on <a href=\''.config('app.rootUrl').'\'>'.config('app.title').'</a></p>';
$mailer->IsHTML(true);
if (!$mailer->Send()) {
Ajde_Log::log('Mail to '.$transaction->email.' failed');
}
}
public function test()
{
$this->setAction('test/confirm');
return $this->render();
}
public function iban()
{
$this->setAction('iban/confirm');
return $this->render();
}
}