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

framework/Payment/Gateway/Api/PayPal.class.php (2 issues)

assigning incompatible types to properties.

Bug Documentation Major

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            PayPal Class
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 / Framework / Payment / Gateway / Api
9
 * @version          1.1
10
 */
11
12
namespace PH7\Framework\Payment\Gateway\Api;
13
14
defined('PH7') or exit('Restricted access');
15
16
use PH7\Framework\File\Stream;
17
use PH7\Framework\Url\Url;
18
19
/**
20
 * PayPal class using PayPal's API
21
 *
22
 * @link https://developer.paypal.com/docs/integration/direct/identity/seamless-checkout/
23
 */
24
class Paypal extends Provider implements Api
25
{
26
    const SANDBOX_PAYMENT_URL = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
27
    const PAYMENT_URL = 'https://www.paypal.com/cgi-bin/webscr';
28
29
    /** @var string */
30
    private $_sUrl;
31
32
    /** @var string */
33
    private $_sRequest = 'cmd=_notify-validate';
34
35
    /** @var string */
36
    private $_sMsg;
37
38
    /** @var string|null */
39
    private $_bValid = null;
40
41
42
    /**
43
     * @param boolean $bSandbox Default FALSE
44
     */
45
    public function __construct($bSandbox = false)
46
    {
47
        if ($bSandbox) {
48
            $this->_sUrl = self::SANDBOX_PAYMENT_URL;
49
        } else {
50
            $this->_sUrl = self::PAYMENT_URL;
51
        }
52
53
        $this->param('cmd', '_xclick');
54
    }
55
56
    /**
57
     * Get Checkout URL.
58
     *
59
     * @param string $sParam
60
     *
61
     * @return string
62
     * @internal We added an empty parameter for the method only to be compatible with the API interface.
63
     */
64
    public function getUrl($sParam = '')
65
    {
66
        return $this->_sUrl;
67
    }
68
69
    /**
70
     * Get message status.
71
     *
72
     * @return string
73
     */
74
    public function getMsg()
75
    {
76
        return $this->_sMsg;
77
    }
78
79
    /**
80
     * Check if the transaction is valid.
81
     *
82
     * @param string $sParam1
83
     * @param string $sParam2
84
     *
85
     * @return boolean
86
     * @internal We added two empty parameters for the method only to be compatible with the API interface.
87
     */
88
    public function valid($sParam1 = '', $sParam2 = '')
89
    {
90
        // If already validated, just return last result
91
        if (true === $this->_bValid || false === $this->_bValid) {
92
            return $this->_bValid;
93
        }
94
95
        $this->setParams();
96
97
        $mStatus = $this->getStatus();
98
99
        if (0 == strcmp('VERIFIED', $mStatus)) {
100
            // Valid
101
            if ($_POST['payment_status'] == 'Completed') {
102
                $this->_bValid = true;
0 ignored issues
show
Documentation Bug introduced by
It seems like true of type boolean is incompatible with the declared type string|null of property $_bValid.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
103
                $this->_sMsg = t('Transaction valid and completed.');
104
            } else {
105
                $this->_bValid = false;
0 ignored issues
show
Documentation Bug introduced by
It seems like false of type false is incompatible with the declared type string|null of property $_bValid.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
106
                $this->_sMsg = t('Transaction valid but not completed.');
107
            }
108
        } elseif (0 == strcmp('INVALID', $mStatus)) {
109
            // Bad Connection
110
            $this->_bValid = false;
111
            $this->_sMsg = t('Invalid transaction.');
112
        } else {
113
            // Bad Connection
114
            $this->_bValid = false;
115
            $this->_sMsg = t('Connection to PayPal failed.');
116
        }
117
118
        return $this->_bValid;
119
    }
120
121
    /**
122
     * Connect to Paypal.
123
     *
124
     * @return boolean|string Message from the transaction status on success or FALSE on failure.
125
     */
126
     protected function getStatus()
127
     {
128
         $rCh = curl_init($this->_sUrl);
129
         curl_setopt($rCh, CURLOPT_POST, 1);
130
         curl_setopt($rCh, CURLOPT_RETURNTRANSFER, 1);
131
         curl_setopt($rCh, CURLOPT_POSTFIELDS, $this->_sRequest);
132
         curl_setopt($rCh, CURLOPT_SSL_VERIFYPEER, 1);
133
         curl_setopt($rCh, CURLOPT_SSL_VERIFYHOST, 2);
134
         curl_setopt($rCh, CURLOPT_HTTPHEADER, array('Host: www.paypal.com'));
135
         $mRes = curl_exec($rCh);
136
         curl_close($rCh);
137
         unset($rCh);
138
139
         return $mRes;
140
     }
141
142
    /**
143
     * Set the data parameters POST from PayPal system.
144
     *
145
     * @return self
146
     */
147
     protected function setParams()
148
     {
149
         foreach ($this->getPostDatas() as $sKey => $sValue) {
150
             $this->setUrlData($sKey, $sValue);
151
         }
152
153
         return $this;
154
     }
155
156
    /**
157
     * Set data URL e.g., "&key=value"
158
     *
159
     * @param string $sName
160
     * @param string $sValue
161
     *
162
     * @return self
163
     */
164
    protected function setUrlData($sName, $sValue)
165
    {
166
        $this->_sRequest .= '&' . $sName . '=' . Url::encode($sValue);
167
        return $this;
168
    }
169
170
    /**
171
     * Get the Post Data.
172
     *
173
     * @return array
174
     */
175
    protected function getPostDatas()
176
    {
177
        $rRawPost = Stream::getInput();
178
        $aRawPost = explode('&', $rRawPost);
179
        $aPostData = array();
180
181
        foreach ($aRawPost as $sKeyVal) {
182
            $aKeyVal = explode ('=', $sKeyVal);
183
            if (count($aKeyVal) == 2) {
184
                $aPostData[$aKeyVal[0]] = Url::encode($aKeyVal[1]);
185
            }
186
            unset($aKeyVal);
187
        }
188
        unset($aRawPost);
189
190
        return $aPostData;
191
    }
192
}
193