Issues (37)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  Header Injection
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/Invoice.php (7 issues)

1
<?php
2
3
namespace Phalcon\Cashier;
4
5
use DOMPDF;
6
use Carbon\Carbon;
7
use Phalcon\Mvc\View;
8
use Stripe\Invoice as StripeInvoice;
9
use Phalcon\Http\Response;
10
use Phalcon\Di\FactoryDefault;
0 ignored issues
show
The type Phalcon\Di\FactoryDefault was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
12
class Invoice
13
{
14
    /**
15
     * The user instance.
16
     */
17
    protected $user;
18
19
    /**
20
     * The Stripe invoice instance.
21
     *
22
     * @var \Stripe\Invoice
23
     */
24
    protected $invoice;
25
26
    /**
27
     * Create a new invoice instance.
28
     *
29
     * @param  Model           $user
0 ignored issues
show
The type Phalcon\Cashier\Model was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
30
     * @param  \Stripe\Invoice $invoice
31
     * @return void
32
     */
33
    public function __construct($user, StripeInvoice $invoice)
34
    {
35
        $this->user = $user;
36
        $this->invoice = $invoice;
37
    }
38
39
    /**
40
     * Get a Carbon date for the invoice.
41
     *
42
     * @param  \DateTimeZone|string $timezone
43
     * @return \Carbon\Carbon
44
     */
45
    public function date($timezone = null)
46
    {
47
        $carbon = Carbon::createFromTimestamp($this->invoice->date);
48
49
        return $timezone ? $carbon->setTimezone($timezone) : $carbon;
50
    }
51
52
    /**
53
     * Get the total amount that was paid (or will be paid).
54
     *
55
     * @return string
56
     */
57
    public function total()
58
    {
59
        return $this->formatAmount($this->rawTotal());
0 ignored issues
show
$this->rawTotal() of type double is incompatible with the type integer expected by parameter $amount of Phalcon\Cashier\Invoice::formatAmount(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

59
        return $this->formatAmount(/** @scrutinizer ignore-type */ $this->rawTotal());
Loading history...
60
    }
61
62
    /**
63
     * Get the raw total amount that was paid (or will be paid).
64
     *
65
     * @return float
66
     */
67
    public function rawTotal()
68
    {
69
        return max(0, $this->invoice->total - ($this->rawStartingBalance() * -1));
70
    }
71
72
    /**
73
     * Get the total of the invoice (before discounts).
74
     *
75
     * @return string
76
     */
77
    public function subtotal()
78
    {
79
        return $this->formatAmount(
80
            max(0, $this->invoice->subtotal - $this->rawStartingBalance())
81
        );
82
    }
83
84
    /**
85
     * Determine if the account had a starting balance.
86
     *
87
     * @return bool
88
     */
89
    public function hasStartingBalance()
90
    {
91
        return $this->rawStartingBalance() > 0;
92
    }
93
94
    /**
95
     * Get the starting balance for the invoice.
96
     *
97
     * @return string
98
     */
99
    public function startingBalance()
100
    {
101
        return $this->formatAmount($this->rawStartingBalance());
0 ignored issues
show
$this->rawStartingBalance() of type double is incompatible with the type integer expected by parameter $amount of Phalcon\Cashier\Invoice::formatAmount(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

101
        return $this->formatAmount(/** @scrutinizer ignore-type */ $this->rawStartingBalance());
Loading history...
102
    }
103
104
    /**
105
     * Determine if the invoice has a discount.
106
     *
107
     * @return bool
108
     */
109
    public function hasDiscount()
110
    {
111
        return $this->invoice->subtotal > 0 && $this->invoice->subtotal != $this->invoice->total
112
        && ! is_null($this->invoice->discount);
113
    }
114
115
    /**
116
     * Get the discount amount.
117
     *
118
     * @return string
119
     */
120
    public function discount()
121
    {
122
        return $this->formatAmount($this->invoice->subtotal - $this->invoice->total);
123
    }
124
125
    /**
126
     * Get the coupon code applied to the invoice.
127
     *
128
     * @return string|null
129
     */
130
    public function coupon()
131
    {
132
        if (isset($this->invoice->discount)) {
133
            return $this->invoice->discount->coupon->id;
134
        }
135
    }
136
137
    /**
138
     * Determine if the discount is a percentage.
139
     *
140
     * @return bool
141
     */
142
    public function discountIsPercentage()
143
    {
144
        return $this->coupon() && isset($this->invoice->discount->coupon->percent_off);
145
    }
146
147
    /**
148
     * Get the discount percentage for the invoice.
149
     *
150
     * @return int
151
     */
152
    public function percentOff()
153
    {
154
        if ($this->coupon()) {
155
            return $this->invoice->discount->coupon->percent_off;
156
        }
157
158
        return 0;
159
    }
160
161
    /**
162
     * Get the discount amount for the invoice.
163
     *
164
     * @return string
165
     */
166
    public function amountOff()
167
    {
168
        if (isset($this->invoice->discount->coupon->amount_off)) {
169
            return $this->formatAmount($this->invoice->discount->coupon->amount_off);
170
        } else {
171
            return $this->formatAmount(0);
172
        }
173
    }
174
175
    /**
176
     * Get all of the "invoice item" line items.
177
     *
178
     * @return array
179
     */
180
    public function invoiceItems()
181
    {
182
        return $this->invoiceItemsByType('invoiceitem');
183
    }
184
185
    /**
186
     * Get all of the "subscription" line items.
187
     *
188
     * @return array
189
     */
190
    public function subscriptions()
191
    {
192
        return $this->invoiceItemsByType('subscription');
193
    }
194
195
    /**
196
     * Get all of the invoie items by a given type.
197
     *
198
     * @param  string $type
199
     * @return array
200
     */
201
    public function invoiceItemsByType($type)
202
    {
203
        $lineItems = [];
204
205
        if (isset($this->lines->data)) {
0 ignored issues
show
Bug Best Practice introduced by
The property lines does not exist on Phalcon\Cashier\Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
206
            foreach ($this->lines->data as $line) {
207
                if ($line->type == $type) {
208
                    $lineItems[] = new InvoiceItem($this->user, $line);
209
                }
210
            }
211
        }
212
213
        return $lineItems;
214
    }
215
216
    /**
217
     * Format the given amount into a string based on the user's preferences.
218
     *
219
     * @param  int $amount
220
     * @return string
221
     */
222
    protected function formatAmount($amount)
223
    {
224
        return Cashier::formatAmount($amount);
225
    }
226
227
    /**
228
     * Get the View instance for the invoice.
229
     *
230
     * @param array $data
231
     */
232
    public function view(array $data)
233
    {
234
        $data = array_merge($data, ['invoice' => $this, 'user' => $this->user]);
235
        $view = $this->getView();
236
        return $view->render('cashier/receipt', $data);
237
    }
238
239
    /**
240
     * Return a {@link \Phalcon\Mvc\View\Simple} instance
241
     *
242
     * @return \Phalcon\Mvc\View\Simple
0 ignored issues
show
The type Phalcon\Mvc\View\Simple was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
243
     */
244
    public function getView()
245
    {
246
        $di = FactoryDefault::getDefault();
247
        if (!$this->view) {
248
            $viewApp = $di->get('view');
249
            if (!($viewsDir = $di->get('config')['viewDir'])) {
250
                $viewsDir = $viewApp->getViewsDir();
251
            }
252
            $view = $di->get('\Phalcon\Mvc\View\Simple');
253
            $view->setViewsDir($viewsDir);
254
            if ($engines = $viewApp->getRegisteredEngines()) {
255
                $view->registerEngines($engines);
256
            }
257
            $this->view = $view;
0 ignored issues
show
Bug Best Practice introduced by
The property view does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
258
        }
259
        return $this->view;
260
    }
261
262
    /**
263
     * Capture the invoice as a PDF and return the raw bytes.
264
     *
265
     * @param  array $data
266
     * @return string
267
     */
268
    public function pdf(array $data)
269
    {
270
        if (! defined('DOMPDF_ENABLE_AUTOLOAD')) {
271
            define('DOMPDF_ENABLE_AUTOLOAD', false);
272
        }
273
        $path = $_SERVER['DOCUMENT_ROOT'];
274
        if (file_exists($configPath = dirname($path) . '/vendor/dompdf/dompdf/dompdf_config.inc.php')) {
275
            include_once $configPath;
276
        }
277
278
        $dompdf = new DOMPDF;
279
280
        $dompdf->load_html($this->view($data));
281
282
        $dompdf->render();
283
284
        return $dompdf->output();
285
    }
286
287
    /**
288
     * Create an invoice download response.
289
     *
290
     * @param array $data
291
     */
292
    public function download(array $data)
293
    {
294
        $filename = $data['product'].'_'.$this->date()->month.'_'.$this->date()->year.'.pdf';
295
296
        $response = new Response();
297
        $response->setHeader('Content-Description', 'File Transfer');
298
        $response->setHeader('Content-Disposition', 'attachment; filename="'.$filename.'"');
299
        $response->setStatusCode(200, 'OK');
300
        $response->setContent($this->pdf($data));
301
        $response->setContentType('application/pdf');
302
        return $response->send();
303
    }
304
305
    /**
306
     * Get the raw starting balance for the invoice.
307
     *
308
     * @return float
309
     */
310
    public function rawStartingBalance()
311
    {
312
        return isset($this->invoice->starting_balance)
313
            ? $this->invoice->starting_balance : 0;
314
    }
315
316
    /**
317
     * Get the Stripe invoice instance.
318
     *
319
     * @return \Stripe\Invoice
320
     */
321
    public function asStripeInvoice()
322
    {
323
        return $this->invoice;
324
    }
325
326
    /**
327
     * Dynamically get values from the Stripe invoice.
328
     *
329
     * @param  string $key
330
     * @return mixed
331
     */
332
    public function __get($key)
333
    {
334
        return $this->invoice->{$key};
335
    }
336
}
337