Completed
Branch master (6a6544)
by Pierre-Henry
33:43
created

modules/payment/controllers/MainController.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * @title          Main Controller
4
 *
5
 * @author         Pierre-Henry Soria <[email protected]>
6
 * @copyright      (c) 2012-2017, Pierre-Henry Soria. All Rights Reserved.
7
 * @license        GNU General Public License; See PH7.LICENSE.txt and PH7.COPYRIGHT.txt in the root directory.
8
 * @package        PH7 / App / System / Module / Payment / Controller
9
 * @version        1.4
10
 */
11
12
namespace PH7;
13
14
use PH7\Framework\Mvc\Model\DbConfig;
15
use PH7\Framework\Mail\Mail;
16
17
class MainController extends Controller
18
{
19
    /** @var AffiliateCoreModel */
20
    protected $oUserModel;
21
22
    /** @var PaymentModel */
23
    protected $oPayModel;
24
25
    /** @var string */
26
    protected $sTitle;
27
28
    /** @var int */
29
    protected $iProfileId;
30
31
    /** @var bool Payment status. Default is failure (FALSE) */
32
    private $_bStatus = false;
33
34
35
    public function __construct()
36
    {
37
        parent::__construct();
38
39
        $this->oUserModel = new AffiliateCoreModel;
40
        $this->oPayModel = new PaymentModel;
41
        $this->iProfileId = $this->session->get('member_id');
42
    }
43
44
    public function index()
45
    {
46
        $this->sTitle = t('Payment Zone');
47
        $this->view->page_title = $this->view->h1_title = $this->sTitle;
48
        $this->output();
49
    }
50
51
    public function membership()
52
    {
53
        $oMembershipModel = $this->oPayModel->getMemberships();
54
55
        if (empty($oMembershipModel))
56
        {
57
            $this->displayPageNotFound(t('No membership found!'));
58
        }
59
        else
60
        {
61
            $this->sTitle = t('Memberships List');
62
            $this->view->page_title = $this->view->h2_title = $this->sTitle;
63
            $this->view->memberships = $oMembershipModel;
64
            $this->output();
65
        }
66
    }
67
68
    public function pay($iMembershipId = null)
69
    {
70
        $iMembershipId = (int) $iMembershipId;
71
72
        $oMembershipModel = $this->oPayModel->getMemberships($iMembershipId);
73
74
        if (empty($iMembershipId) || empty($oMembershipModel))
75
        {
76
            $this->displayPageNotFound(t('No membership found!'));
77
        }
78
        else
79
        {
80
            // Adding the stylesheet for Gatway Logo
81
            $this->design->addCss(PH7_LAYOUT . PH7_SYS . PH7_MOD . $this->registry->module . PH7_SH . PH7_TPL . PH7_TPL_MOD_NAME . PH7_SH . PH7_CSS, 'common.css');
82
83
            // Regenerate the session ID to prevent the session fixation attack
84
            $this->session->regenerateId();
85
86
            $this->sTitle = t('Pay!');
87
            $this->view->page_title = $this->view->h2_title = $this->sTitle;
88
            $this->view->membership = $oMembershipModel;
89
            $this->output();
90
        }
91
    }
92
93
    public function process($sProvider = '')
94
    {
95
        switch ($sProvider)
96
        {
97
            case 'paypal':
98
            {
99
                $oPayPal = new PayPal($this->config->values['module.setting']['sandbox.enabled']);
100
                if ($oPayPal->valid() && $this->httpRequest->postExists('custom'))
101
                {
102
                    $aData = explode('|', base64_decode($this->httpRequest->post('custom')));
103
                    $iItemNumber = (int) $aData[0];
104
                    $fPrice = $aData[1];
105
                    if ($this->oUserModel->updateMembership($iItemNumber, $this->iProfileId, $fPrice, $this->dateTime->get()->dateTime('Y-m-d H:i:s')))
106
                    {
107
                        $this->_bStatus = true; // Status is OK
108
                        // PayPal will call automatically the "notification()" method thanks its IPN feature and "notify_url" form attribute.
109
                    }
110
                }
111
                unset($oPayPal);
112
            }
113
            break;
114
115
            case 'stripe':
116
            {
117
                if ($this->httpRequest->postExists('stripeToken'))
118
                {
119
                    \Stripe\Stripe::setApiKey($this->config->values['module.setting']['stripe.secret_key']);
120
                    $sAmount = $this->httpRequest->post('amount');
121
122
                    try
123
                    {
124
                        $oCharge = \Stripe\Charge::create(
125
                            [
126
                                'amount' => Stripe::getAmount($sAmount),
127
                                'currency' => $this->config->values['module.setting']['currency'],
128
                                'source' => $this->httpRequest->post('stripeToken'),
129
                                'description'    => 'Membership charged for ' . $this->httpRequest->post('stripeEmail')
130
                            ]
131
                        );
132
133
                        if ($this->oUserModel->updateMembership($this->httpRequest->post('item_number'), $this->iProfileId, $sAmount, $this->dateTime->get()->dateTime('Y-m-d H:i:s')))
134
                        {
135
                            $this->_bStatus = true; // Status is OK
136
                            $this->notification('Stripe'); // Add info into the log file
137
                        }
138
                    }
139
                    catch (\Stripe\Error\Card $oE)
140
                    {
141
                        // The card has been declined
142
                        // Do nothing here as "$this->_bStatus" is by default FALSE and so it will display "Error occurred" msg later
143
                    }
144
                    catch (\Stripe\Error\Base $oE)
145
                    {
146
                        $this->design->setMessage( $this->str->escape($oE->getMessage(), true) );
147
                    }
148
                }
149
            }
150
            break;
151
152
            case '2co':
153
            {
154
                $o2CO = new TwoCO($this->config->values['module.setting']['sandbox.enabled']);
155
                $sVendorId = $this->config->values['module.setting']['2co.vendor_id'];
156
                $sSecretWord = $this->config->values['module.setting']['2co.secret_word'];
157
158
                if ($o2CO->valid($sVendorId, $sSecretWord) && $this->httpRequest->postExists('sale_id'))
159
                {
160
                    if ($this->oUserModel->updateMembership($this->httpRequest->post('cart_order_id'), $this->iProfileId, $this->httpRequest->post('total'), $this->dateTime->get()->dateTime('Y-m-d H:i:s')))
161
                    {
162
                        $this->_bStatus = true; // Status is OK
163
                        $this->notification('TwoCO'); // Add info into the log file
164
                    }
165
                }
166
                unset($o2CO);
167
            }
168
            break;
169
170
            case 'ccbill':
171
            {
172
                // In developing...
173
                // Contact us at <[email protected]> or <[email protected]> if you want to help us by developing the payment system CCBill
174
            }
175
            break;
176
177
            default:
178
                $this->displayPageNotFound(t('Provinder Not Found!'));
179
        }
180
181
        // Set the page titles
182
        $this->sTitle = ($this->_bStatus) ? t('Thank you!') : t('Error occurred!');
183
        $this->view->page_title = $this->view->h2_title = $this->sTitle;
184
185
        if ($this->_bStatus)
186
        {
187
            $this->updateAffCom();
188
            $this->clearCache();
189
        }
190
191
        // Set the valid page
192
        $sPage = ($this->_bStatus) ? 'success' : 'error';
193
        $this->manualTplInclude($sPage . $this->view->getTplExt());
194
195
        // Output
196
        $this->output();
197
    }
198
199
    public function notification($sGatewayName = '')
200
    {
201
        // Save buyer information to a log file
202
        if ($sGatewayName == 'PayPal' || $sGatewayName == 'Stripe' || $sGatewayName == 'TwoCO' || $sGatewayName == 'CCBill')
203
        {
204
            $sGatewayName = 'PH7\\' . $sGatewayName;
205
            $this->log(new $sGatewayName(false), t('%0% payment was made with the following information:', $sGatewayName));
206
        }
207
208
        // Send a notification email
209
        $this->sendNotifyMail();
210
    }
211
212
    public function info()
213
    {
214
        $this->sTitle = t('Details of the membership');
215
        $this->view->page_title = $this->view->h2_title = $this->sTitle;
216
217
        $oInfo = $this->oUserModel->getMembershipDetails($this->iProfileId);
218
        if ($oInfo->expirationDays != 0 && !empty($oInfo->membershipDate)) {
219
            $oDate = new \DateTime($oInfo->membershipDate);
220
            $oDate->add(new \DateInterval( sprintf('P%dD', $oInfo->expirationDays)) );
221
            $this->view->expirationDate = $oDate->format($this->config->values['language.application']['date_time_format']);
222
            unset($oDate);
223
        } else {
224
            $this->view->expirationDate = t('Never');
225
        }
226
        $this->view->membershipName = $oInfo->membershipName;
227
        unset($oInfo);
228
229
        $this->output();
230
    }
231
232
    /**
233
     * Update the Affiliate Commission.
234
     *
235
     * @return void
236
     */
237
    protected function updateAffCom()
238
    {
239
        // Load the Affiliate config file
240
        $this->config->load(PH7_PATH_SYS_MOD . 'affiliate' . PH7_DS . PH7_CONFIG . PH7_CONFIG_FILE);
241
242
        $iAffId = $this->oUserModel->getAffiliatedId($this->iProfileId);
243
        if ($iAffId < 1) return; // If there is no valid ID, we stop the method.
244
245
        $iAmount = $this->oUserModel->readProfile($this->iProfileId)->price;
246
        $iAffCom = ($iAmount*$this->config->values['module.setting']['rate.user_membership_payment']/100);
247
248
        if ($iAffCom > 0)
249
            $this->oUserModel->updateUserJoinCom($iAffId, $iAffCom);
250
    }
251
252
    /**
253
     * Send a notification email to the admin about the payment (IPN -> Instant Payment Notification).
254
     *
255
     * @return integer Number of recipients who were accepted for delivery.
256
     */
257
    protected function sendNotifyMail()
258
    {
259
        $sTo = DbConfig::getSetting('adminEmail');
260
        $sBuyer = $this->session->get('member_first_name') . ' (' . $this->session->get('member_username') . ')';
261
262
        $this->view->intro = t('Hello!') . '<br />' . t('You received a new Payment from %0%', $sBuyer);
263
        $this->view->date = t('Date of the payment: %0%', $this->dateTime->get()->date());
264
        $this->view->browser_info = t('User Browser info: %0%', $this->browser->getUserAgent());
265
        $this->view->ip = t('Ip of the buyer: %0%', $this->design->ip(null, false));
266
        $this->view->details_text = t('Please find all other details below');
267
        $this->view->details_data = print_r($_POST, true);
268
269
        $sMessageHtml = $this->view->parseMail(PH7_PATH_SYS . 'global/' . PH7_VIEWS . PH7_TPL_MAIL_NAME . '/tpl/mail/sys/mod/payment/ipn.tpl', $sTo);
270
271
        $aInfo = [
272
            'to' => $sTo,
273
            'subject' => t('New Payment Received from %0%', $sBuyer)
274
        ];
275
276
        return (new Mail)->send($aInfo, $sMessageHtml);
277
    }
278
279
    /**
280
     * Create a Payment Log file.
281
     *
282
     * @param \PH7\Framework\Payment\Gateway\Api\Api $oProvider A provider class.
283
     * @param string $sMsg
284
     * @return void
285
     */
286
    protected function log(Framework\Payment\Gateway\Api\Api $oProvider, $sMsg)
0 ignored issues
show
log uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
287
    {
288
        if ($this->config->values['module.setting']['log_file.enabled'])
289
        {
290
            $sLogTxt = $sMsg . Framework\File\File::EOL . Framework\File\File::EOL . Framework\File\File::EOL . Framework\File\File::EOL;
291
            $oProvider->saveLog($sLogTxt . print_r($_POST, true), $this->registry);
292
        }
293
    }
294
295
    /**
296
     * Clear Membership cache.
297
     *
298
     * @return void
299
     */
300
    protected function clearCache()
301
    {
302
        (new Framework\Cache\Cache)->start(UserCoreModel::CACHE_GROUP, 'membershipdetails' . $this->iProfileId, null)->clear();
303
    }
304
}
305