├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── CREDITS
├── LICENSE.md
├── README.md
├── composer.json
├── composer.lock
├── examples
├── .bog.example
├── .cartu.example
└── .tbcpay.example
├── phpcs.xml
├── phpunit.xml.dist
├── src
├── Contracts
│ ├── Logger.php
│ └── Options.php
├── Logger.php
├── Options.php
├── Payment.php
└── Provider
│ ├── AbstractProvider.php
│ ├── AbstractXMLResponse.php
│ ├── Card
│ ├── Bog
│ │ ├── Provider.php
│ │ └── XMLResponse.php
│ └── Cartu
│ │ ├── Provider.php
│ │ └── XMLResponse.php
│ └── Pay
│ └── Tbcpay
│ ├── Provider.php
│ └── XMLResponse.php
└── tests
├── Bootstrap.php
└── Unit
├── LoggerTest.php
├── OptionsTest.php
├── PaymentTest.php
└── TestCase.php
/.gitignore:
--------------------------------------------------------------------------------
1 | # IDE & System Related Files #
2 | .buildpath
3 | .project
4 | .settings
5 | .DS_Store
6 | .idea
7 | .phpintel
8 | composer.phar
9 |
10 | # Local System Files (i.e. cache, logs, etc.) #
11 | /cache
12 | /build/logs
13 | /build/coverage
14 | /tmp
15 |
16 | # Test Related Files #
17 | /phpunit.xml
18 |
19 | # Composer
20 | vendor/
21 |
22 | .fuse_hidden*
23 |
24 | # phpDocumentor Logs #
25 | phpdoc-*
26 |
27 | # OSX #
28 | ._*
29 | .Spotlight-V100
30 | .Trashes
31 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - 5.3
5 | - 5.4
6 | - 5.5
7 | - 5.6
8 | - 7.0
9 | - 7.1
10 | - hhvm
11 |
12 | sudo: false
13 |
14 | before_install:
15 | - composer self-update
16 |
17 | install:
18 | - travis_retry composer update --no-interaction --prefer-source
19 |
20 | script:
21 | - ./vendor/bin/phpcs --standard=phpcs.xml -snp --encoding=utf-8 src/ --report-width=150
22 | - ./vendor/bin/phpunit
23 |
24 | matrix:
25 | allow_failures:
26 | - php: 5.3
27 | - php: 5.4
28 | fast_finish: true
29 |
30 |
31 | notifications:
32 | on_success: never
33 | on_failure: always
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Contributing
2 | -------------
3 |
4 | Before you contribute code to this project, please make sure it conforms to the PSR-2 coding standard
5 | and that the project unit tests still pass. The easiest way to contribute is to work on a checkout of the repository,
6 | or your own fork. If you do this, you can run the following commands to check if everything is ready to submit:
7 |
8 | cd php-geopayment
9 | composer update
10 | ./vendor/bin/phpcs --standard=phpcs.xml -sp --encoding=utf-8 src/ --report-width=150
11 |
12 | Which should give you no errors, indicating that there are no coding standard errors. And then:
13 |
14 | ./vendor/bin/phpunit
15 |
16 | Which should give you no failures or errors. You can ignore any skipped tests as these are for external tools.
17 |
18 | Pushing
19 | -------
20 |
21 | Development is based on the git flow branching model (see http://nvie.com/posts/a-successful-git-branching-model/ )
22 | If you fix a bug please push in hotfix branch.
23 | If you develop a new feature please create a new branch.
24 |
25 | Version
26 | -------
27 | Version number: 0.#version.#hotfix
28 |
--------------------------------------------------------------------------------
/CREDITS:
--------------------------------------------------------------------------------
1 | This is at least a partial credits-file of people that have
2 | contributed to the current project. It is sorted by name and
3 | formatted to allow easy grepping and beautification by
4 | scripts. The fields are: name (N), email (E), web-address
5 | (W) and description (D).
6 | Thanks,
7 |
8 | Avtandil Kikabidze
9 | ----------
10 |
11 | N: Avtandil Kikabidze aka LONGMAN
12 | E: akalongman@gmail.com
13 | W: http://longman.me
14 | D: Project owner, Maintainer
15 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The [MIT License](http://opensource.org/licenses/mit-license.php)
2 |
3 | Copyright (c) 2015 [Avtandil Kikabidze aka LONGMAN](https://github.com/akalongman)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GeoPayment
2 |
3 | [](https://travis-ci.org/akalongman/php-geopayment)
4 | [](https://packagist.org/packages/longman/geopayment)
5 | [](https://packagist.org/packages/longman/geopayment)
6 | [](https://packagist.org/packages/longman/geopayment)
7 | [](LICENSE.md)
8 |
9 | Georgian bank/terminal payment integration library
10 |
11 | ## Table of Contents
12 | - [Installation](#installation)
13 | - [Composer](#composer)
14 | - [Usage](#usage)
15 | - [Card Payments](#card-payments) (Visa/MasterCard/AmEX)
16 | - [BOG](#bog) (Bank of Georgia)
17 | - [Step 1: Redirecting on payment page](#bog-step-1-redirecting-on-payment-page)
18 | - [Step 2: Bank checks payment availability](#bog-step-2-bank-checks-payment-availability)
19 | - [Step 3: Bank registers payment](#bog-step-3-bank-registers-payment)
20 | - [Cartu](#cartu) (Cartu Bank)
21 | - [Step 1: Redirecting on payment page](#cartu-step-1-redirecting-on-payment-page)
22 | - [Step 2: Bank registers payment](#cartu-step-2-bank-registers-payment)
23 | - [Terminal Payments](#terminal-payments)
24 | - [TBC Pay](#tbc-pay)
25 | - [Step 1: Check payment](#tbc-pay-step-1-check-payment)
26 | - [Step 2: Register Payment](#tbc-pay-step-2-register-payment)
27 | - [Recommended Response codes](#tbc-pay-recommended-response-codes)
28 | - [Liberty Pay](#liberty-pay)
29 | - [Step 1: Check payment](#liberty-pay-step-1-check-payment)
30 | - [Step 2: Register Payment](#liberty-liberty-step-2-register-payment)
31 | - [Recommended Response codes](#liberty-pay-recommended-response-codes)
32 |
33 | - [TODO](#todo)
34 | - [Troubleshooting](#troubleshooting)
35 | - [Contributing](#contributing)
36 | - [License](#license)
37 | - [Credits](#credits)
38 |
39 |
40 | ## Installation
41 |
42 | ### Composer
43 |
44 | Install this package through [Composer](https://getcomposer.org/).
45 |
46 | Edit your project's `composer.json` file to require `longman/geopayment`
47 |
48 | Create *composer.json* file:
49 | ```js
50 | {
51 | "name": "yourproject/yourproject",
52 | "type": "project",
53 | "require": {
54 | "longman/geopayment": "*"
55 | }
56 | }
57 | ```
58 | And run composer update
59 |
60 | **Or** run a command in your command line:
61 |
62 | ```
63 | composer require longman/geopayment
64 | ```
65 |
66 | ***
67 |
68 | [(Back to top)](#table-of-contents)
69 |
70 |
71 | ## Usage
72 |
73 | ```php
74 | 'value1',
82 | 'option2' => 'value2',
83 | 'option3' => 'value3',
84 | . . .
85 | ];
86 |
87 | // or create .configfile file and specify file path in options
88 | $options = [
89 | 'config_path' => '/path/to/folder/.configfile',
90 | ];
91 |
92 | // Create payment instance
93 | $payment = new Payment('{provider}', '{type}', $options);
94 |
95 | // do more job depending on bank documentation
96 |
97 | ```
98 |
99 | **Important:** If your .config file is under server document_root, you must deny access to that file via http.
100 |
101 | Apache
102 |
103 | Add in your .htaccess file:
104 | ```
105 |
106 | Order allow,deny
107 | Deny from all
108 | Satisfy all
109 |
110 | ```
111 |
112 | Nginx
113 |
114 | In server section:
115 | ```
116 | location ~ /\. {
117 | deny all;
118 | access_log off;
119 | log_not_found off;
120 | }
121 | ```
122 |
123 | ### Card Payments
124 |
125 | #### Bog
126 |
127 | BOG config example you can find here [.bog.example](examples/.bog.example)
128 |
129 | ##### Bog Step 1: Redirecting on payment page
130 |
131 | ```php
132 | '/path/to/config/.bog',
139 | ];
140 |
141 | // Create payment instance
142 | $payment = new Payment('bog', Payment::TYPE_CARD, $options);
143 |
144 | // Set mode 'redirect'
145 | $payment->setMode('redirect');
146 |
147 | // Set success url
148 | $payment->setSuccessUrl('your_success_url');
149 |
150 | // Set fail url
151 | $payment->setFailUrl('your_fail_url');
152 |
153 | // Set order id or any payment identificator in your db
154 | $payment->addParam('order_id', 'your_order_id');
155 |
156 | // You can add more params if needed
157 | $payment->addParam('param1', 'value1');
158 | $payment->addParam('param2', 'value2');
159 |
160 | // And simple redirect
161 | $payment->redirect();
162 |
163 | // Or get payment initialization url if needed and after redirect
164 | $url = $payment->getPaymentUrl();
165 | . . .
166 | $payment->redirect($url);
167 | ```
168 |
169 | ##### Bog Step 2: Bank checks payment availability
170 |
171 | ```php
172 | '/path/to/config/.bog',
179 | ];
180 |
181 | $payment = new Payment('bog', Payment::TYPE_CARD, $options);
182 |
183 | // Set mode 'check'
184 | $payment->setMode('check');
185 |
186 | // Check IP (if needed)
187 | $payment->checkIpAllowed();
188 |
189 | // Check HTTP authorization
190 | $payment->checkHttpAuth();
191 |
192 | // Check signature validation (depends on documentation)
193 | $payment->checkSignature();
194 |
195 | // Here you must check order_id or any other parameters which before redirecting set via $payment->addParam
196 | $order_id = $payment->getParam('o.order_id');
197 | if (!$order_id) {
198 | $payment->sendErrorResponse('order_id is empty!');
199 | }
200 |
201 | // check if order exists
202 | $order = get_order_from_yout_db($order_id);
203 | if (empty($order)) {
204 | $payment->sendErrorResponse('order with id "'.$order_id.'" not found!');
205 | }
206 |
207 | // check if order already completed
208 | if ($order->isCompleted()) {
209 | $payment->sendErrorResponse('Purchase for order "'.$order_id.'" already completed!');
210 | }
211 | . . .
212 |
213 | // Build parameters for response
214 | $params = [];
215 | $params['amount'] = 'Order price (In minor units)';
216 | $params['short_desc'] = 'Payment short description';
217 | $params['long_desc'] = 'Payment long description';
218 |
219 | $payment->sendSuccessResponse($params);
220 |
221 | ```
222 |
223 |
224 | ##### Bog Step 3: Bank registers payment
225 |
226 | ```php
227 | '/path/to/config/.bog',
234 | ];
235 |
236 | $payment = new Payment('bog', Payment::TYPE_CARD, $options);
237 |
238 | // Set mode 'reg'
239 | $payment->setMode('reg');
240 |
241 | // Check IP (if needed)
242 | $payment->checkIpAllowed();
243 |
244 | // Check HTTP authorization
245 | $payment->checkHttpAuth();
246 |
247 | // Check signature validation (depends on documentation)
248 | $payment->checkSignature();
249 |
250 | // Here you must check order_id or any other parameters which before redirecting set via $payment->addParam
251 | $order_id = $payment->getParam('o.order_id');
252 | if (!$order_id) {
253 | $payment->sendErrorResponse('order_id is empty!');
254 | }
255 |
256 | // check if order exists
257 | $order = get_order_from_yout_db($order_id);
258 | if (empty($order)) {
259 | $payment->sendErrorResponse('order with id "'.$order_id.'" not found!');
260 | }
261 |
262 | // check if order already completed
263 | if ($order->isCompleted()) {
264 | $payment->sendErrorResponse('Purchase for order "'.$order_id.'" already completed!');
265 | }
266 |
267 | // Get and check payment result code
268 | $result_code = $payment->getParam('result_code');
269 | if (empty($result_code)) {
270 | $payment->sendErrorResponse('result_code is empty!');
271 | }
272 |
273 | // Register payment with result code (1 - success, 2 - failed)
274 | . . .
275 |
276 | // Send response
277 | $payment->sendSuccessResponse();
278 |
279 | ```
280 |
281 | ***
282 |
283 | [(Back to top)](#table-of-contents)
284 |
285 |
286 |
287 | #### Cartu
288 |
289 | Cartu config example you can find here [.cartu.example](examples/.cartu.example)
290 |
291 | ##### Cartu Step 1: Redirecting on payment page
292 |
293 | ```php
294 | '/path/to/config/.cartu',
301 | ];
302 |
303 | // Create payment instance
304 | $payment = new Payment('cartu', Payment::TYPE_CARD, $options);
305 |
306 | // Set mode 'redirect'
307 | $payment->setMode('redirect');
308 |
309 | // generate order id
310 | $order_id = '1111111';
311 |
312 | // prepare parameters for redirect
313 | $purchase_desc = $order_id.'!!!';
314 | $purchase_amt = '20.25';
315 |
316 | $payment->addParam('PurchaseDesc', $purchase_desc);
317 | $payment->addParam('PurchaseAmt', $purchase_amt);
318 |
319 | // And simple redirect
320 | $payment->redirect();
321 |
322 | // Or get payment initialization url if needed and after redirect
323 | $url = $payment->getPaymentUrl();
324 | . . .
325 | $payment->redirect($url);
326 | ```
327 |
328 | ##### Cartu Step 2: Bank registers payment
329 |
330 | ```php
331 | '/path/to/config/.cartu',
338 | ];
339 |
340 | $payment = new Payment('cartu', Payment::TYPE_CARD, $options);
341 |
342 | $payment->setMode('response');
343 |
344 | // Check IP (if needed)
345 | $payment->checkIpAllowed();
346 |
347 | // get bank parameters
348 | $TransactionId = $payment->getTransactionId();
349 | $PaymentId = $payment->getPaymentId();
350 | $PaymentDate = $payment->getPaymentDate();
351 | $Amount = $payment->getAmount();
352 | $CardType = $payment->getCardType();
353 | $Reason = $payment->getReason();
354 | $Status = $payment->getStatus();
355 |
356 | switch($Status) {
357 | case 'C': // check
358 | // check order availability by TransactionId
359 |
360 | $payment->sendSuccessResponse($params);
361 | break;
362 |
363 | case 'Y': // success
364 | // update order status by TransactionId
365 |
366 | $payment->sendSuccessResponse($params);
367 | break;
368 |
369 | case 'N': // failed
370 | // set order status to failed
371 |
372 | $payment->sendErrorResponse('Transaction failed');
373 | break;
374 |
375 | case 'U': // unfinished
376 |
377 | $payment->sendErrorResponse('Unfinished request');
378 |
379 | break;
380 |
381 | default:
382 | // throw error
383 | $payment->sendErrorResponse('Status unspecified');
384 |
385 | break;
386 | }
387 |
388 |
389 | ```
390 |
391 | ***
392 |
393 | [(Back to top)](#table-of-contents)
394 |
395 |
396 |
397 | ### Terminal Payments
398 |
399 |
400 | #### TBC Pay
401 |
402 | TBC Pay config example you can find here [.tbcpay.example](examples/.tbcpay.example)
403 |
404 | ##### TBC Pay Step 1: Check payment
405 |
406 | ```php
407 | '/path/to/config/.tbcpay',
414 | ];
415 |
416 | // Create payment instance
417 | $payment = new Payment('tbcpay', Payment::TYPE_PAY, $options);
418 |
419 | // Set mode 'check'
420 | $payment->setMode('check');
421 |
422 | // Check IP (if needed)
423 | $payment->checkIpAllowed();
424 |
425 | // Check HTTP authorization
426 | $payment->checkHttpAuth();
427 |
428 | // Get account identifier from request
429 | $account = $payment->getParam('account');
430 | if (empty($account)) {
431 | // Pass response code and message
432 | $payment->sendErrorResponse(4, 'Invalid Account Number Format');
433 | }
434 |
435 | // Check account id in db and show error if needed
436 | . . .
437 |
438 | // Generate some extra data for response. You can add more parameters if needed
439 | $extra = [];
440 | $extra['customer'] = 'John Doe';
441 | $extra['debt'] = '500.00';
442 |
443 | $payment->sendSuccessResponse($extra);
444 |
445 | ```
446 |
447 | ##### TBC Pay Step 2: Register Payment
448 |
449 | ```php
450 | '/path/to/config/.tbcpay',
457 | ];
458 |
459 | // Create payment instance
460 | $payment = new Payment('tbcpay', Payment::TYPE_PAY, $options);
461 |
462 | // Set mode 'reg'
463 | $payment->setMode('reg');
464 |
465 | // Check IP (if needed)
466 | $payment->checkIpAllowed();
467 |
468 | // Check HTTP authorization
469 | $payment->checkHttpAuth();
470 |
471 | // Get account identifier from request
472 | $account = $payment->getParam('account');
473 | if (empty($account)) {
474 | $payment->sendErrorResponse(4, 'Invalid Account Number Format');
475 | }
476 |
477 | // Check account id in db and show error if needed
478 | . . .
479 |
480 | // Get transaction id
481 | $txn_id = $payment->getParam('txn_id');
482 | if (empty($txn_id)) {
483 | $payment->sendErrorResponse(300, 'txn_id is not defined');
484 | }
485 |
486 | // Check transaction id in db and show error if needed
487 | . . .
488 |
489 | // Get payd amount
490 | $sum = $payment->getParam('sum');
491 | if (empty($sum)) {
492 | $payment->sendErrorResponse(300, 'sum is not defined');
493 | }
494 |
495 | $payment->sendSuccessResponse();
496 |
497 |
498 | ```
499 |
500 | ##### TBC Pay: Recommended Response codes
501 |
502 | | Code | Message |
503 | |:----:|:-------:|
504 | | 0 | Success |
505 | | 1 | Server timeout |
506 | | 4 | Invalid account format |
507 | | 5 | Account not found |
508 | | 7 | Payment is restricted |
509 | | 215 | Duplicate transaction |
510 | | 275 | Invalid amount |
511 | | 300 | Internal server error |
512 |
513 |
514 | ***
515 |
516 | [(Back to top)](#table-of-contents)
517 |
518 |
519 | #### Liberty Pay
520 |
521 | ##### Liberty Pay Step 1: Check payment
522 |
523 | TBD
524 |
525 | ##### Liberty Pay Step 2: Register Payment
526 |
527 | TBD
528 |
529 | ##### Liberty Pay: Recommended Response codes
530 |
531 | | Code | Message |
532 | |:----:|:-------:|
533 | | 0 | Success |
534 | | 1 | Server timeout |
535 | | 4 | Invalid account format |
536 | | 5 | Account not found |
537 | | 7 | Payment is restricted |
538 | | 215 | Duplicate transaction |
539 | | 275 | Invalid amount |
540 | | 300 | Internal server error |
541 |
542 |
543 | ***
544 |
545 | [(Back to top)](#table-of-contents)
546 |
547 |
548 |
549 |
550 | ## TODO
551 |
552 | Add more providers and write more tests
553 |
554 | ## Troubleshooting
555 |
556 | If you like living on the edge, please report any bugs you find on the
557 | [PHP GeoPayment issues](https://github.com/akalongman/php-geopayment/issues) page.
558 |
559 | ## Contributing
560 |
561 | Pull requests are welcome.
562 | See [CONTRIBUTING.md](CONTRIBUTING.md) for information.
563 |
564 | ## License
565 |
566 | Please see the [LICENSE](LICENSE.md) included in this repository for a full copy of the MIT license,
567 | which this project is licensed under.
568 |
569 | ## Credits
570 |
571 | - [Avtandil Kikabidze aka LONGMAN](https://github.com/akalongman)
572 |
573 | Full credit list in [CREDITS](CREDITS)
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "longman/geopayment",
3 | "type": "library",
4 | "description": "PHP library for working with Georgian payment providers and banks",
5 | "keywords": ["payment", "pay", "georgia", "bog", "tbc", "cartu", "merchant", "visa", "ecommerce", "tbcpay", "libertypay", "terminal"],
6 | "license": "MIT",
7 | "homepage": "https://github.com/akalongman/php-geopayment",
8 | "support": {
9 | "issues": "https://github.com/akalongman/php-geopayment/issues",
10 | "source": "https://github.com/akalongman/php-geopayment"
11 | },
12 | "authors": [
13 | {
14 | "name": "Avtandil Kikabidze aka LONGMAN",
15 | "email": "akalongman@gmail.com",
16 | "homepage": "http://longman.me",
17 | "role": "Maintainer, Developer"
18 | }
19 | ],
20 | "require": {
21 | "php": ">=5.3.0",
22 | "monolog/monolog": "~1.17",
23 | "symfony/var-dumper": "~3.0|~4.0",
24 | "vlucas/phpdotenv": "~2.2",
25 | "symfony/http-foundation": "~3.0|~4.0",
26 | "nesbot/carbon": "~1.21",
27 | "longman/ip-tools": "~1.1"
28 | },
29 | "require-dev": {
30 | "mockery/mockery": "0.9.*",
31 | "phpunit/phpunit": "~4.0",
32 | "phpspec/phpspec": "2.4.*",
33 | "squizlabs/php_codesniffer": "2.5.*"
34 | },
35 | "autoload": {
36 | "psr-4": {
37 | "Longman\\GeoPayment\\": "src/"
38 | }
39 | },
40 | "autoload-dev": {
41 | "psr-4": {
42 | "Tests\\": "tests/"
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "b939be7921dcc59575fafce6e9321693",
8 | "packages": [
9 | {
10 | "name": "longman/ip-tools",
11 | "version": "1.2.1",
12 | "source": {
13 | "type": "git",
14 | "url": "https://github.com/akalongman/php-ip-tools.git",
15 | "reference": "6c050dfbf91811d14b9b3aa31fb7116eac0f0a18"
16 | },
17 | "dist": {
18 | "type": "zip",
19 | "url": "https://api.github.com/repos/akalongman/php-ip-tools/zipball/6c050dfbf91811d14b9b3aa31fb7116eac0f0a18",
20 | "reference": "6c050dfbf91811d14b9b3aa31fb7116eac0f0a18",
21 | "shasum": ""
22 | },
23 | "require": {
24 | "ext-bcmath": "*",
25 | "php": ">=5.5"
26 | },
27 | "require-dev": {
28 | "phpspec/phpspec": "~2.1",
29 | "phpunit/phpunit": "~4.1",
30 | "squizlabs/php_codesniffer": "~2.3"
31 | },
32 | "type": "library",
33 | "autoload": {
34 | "psr-4": {
35 | "Longman\\IPTools\\": "src/"
36 | }
37 | },
38 | "notification-url": "https://packagist.org/downloads/",
39 | "license": [
40 | "MIT"
41 | ],
42 | "authors": [
43 | {
44 | "name": "Avtandil Kikabidze aka LONGMAN",
45 | "email": "akalongman@gmail.com",
46 | "homepage": "https://longman.me",
47 | "role": "Developer"
48 | }
49 | ],
50 | "description": "PHP IP Tools for manipulation with IPv4 and IPv6",
51 | "homepage": "https://github.com/akalongman/php-ip-tools",
52 | "keywords": [
53 | "IP",
54 | "Match",
55 | "compare",
56 | "ipv4",
57 | "ipv6",
58 | "mask",
59 | "subnet",
60 | "tools",
61 | "utilities"
62 | ],
63 | "time": "2016-10-23T20:08:46+00:00"
64 | },
65 | {
66 | "name": "monolog/monolog",
67 | "version": "1.23.0",
68 | "source": {
69 | "type": "git",
70 | "url": "https://github.com/Seldaek/monolog.git",
71 | "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4"
72 | },
73 | "dist": {
74 | "type": "zip",
75 | "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4",
76 | "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4",
77 | "shasum": ""
78 | },
79 | "require": {
80 | "php": ">=5.3.0",
81 | "psr/log": "~1.0"
82 | },
83 | "provide": {
84 | "psr/log-implementation": "1.0.0"
85 | },
86 | "require-dev": {
87 | "aws/aws-sdk-php": "^2.4.9 || ^3.0",
88 | "doctrine/couchdb": "~1.0@dev",
89 | "graylog2/gelf-php": "~1.0",
90 | "jakub-onderka/php-parallel-lint": "0.9",
91 | "php-amqplib/php-amqplib": "~2.4",
92 | "php-console/php-console": "^3.1.3",
93 | "phpunit/phpunit": "~4.5",
94 | "phpunit/phpunit-mock-objects": "2.3.0",
95 | "ruflin/elastica": ">=0.90 <3.0",
96 | "sentry/sentry": "^0.13",
97 | "swiftmailer/swiftmailer": "^5.3|^6.0"
98 | },
99 | "suggest": {
100 | "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
101 | "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
102 | "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
103 | "ext-mongo": "Allow sending log messages to a MongoDB server",
104 | "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
105 | "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver",
106 | "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
107 | "php-console/php-console": "Allow sending log messages to Google Chrome",
108 | "rollbar/rollbar": "Allow sending log messages to Rollbar",
109 | "ruflin/elastica": "Allow sending log messages to an Elastic Search server",
110 | "sentry/sentry": "Allow sending log messages to a Sentry server"
111 | },
112 | "type": "library",
113 | "extra": {
114 | "branch-alias": {
115 | "dev-master": "2.0.x-dev"
116 | }
117 | },
118 | "autoload": {
119 | "psr-4": {
120 | "Monolog\\": "src/Monolog"
121 | }
122 | },
123 | "notification-url": "https://packagist.org/downloads/",
124 | "license": [
125 | "MIT"
126 | ],
127 | "authors": [
128 | {
129 | "name": "Jordi Boggiano",
130 | "email": "j.boggiano@seld.be",
131 | "homepage": "http://seld.be"
132 | }
133 | ],
134 | "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
135 | "homepage": "http://github.com/Seldaek/monolog",
136 | "keywords": [
137 | "log",
138 | "logging",
139 | "psr-3"
140 | ],
141 | "time": "2017-06-19T01:22:40+00:00"
142 | },
143 | {
144 | "name": "nesbot/carbon",
145 | "version": "1.34.0",
146 | "source": {
147 | "type": "git",
148 | "url": "https://github.com/briannesbitt/Carbon.git",
149 | "reference": "1dbd3cb01c5645f3e7deda7aa46ef780d95fcc33"
150 | },
151 | "dist": {
152 | "type": "zip",
153 | "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/1dbd3cb01c5645f3e7deda7aa46ef780d95fcc33",
154 | "reference": "1dbd3cb01c5645f3e7deda7aa46ef780d95fcc33",
155 | "shasum": ""
156 | },
157 | "require": {
158 | "php": ">=5.3.9",
159 | "symfony/translation": "~2.6 || ~3.0 || ~4.0"
160 | },
161 | "require-dev": {
162 | "friendsofphp/php-cs-fixer": "~2",
163 | "phpunit/phpunit": "^4.8.35 || ^5.7"
164 | },
165 | "type": "library",
166 | "extra": {
167 | "laravel": {
168 | "providers": [
169 | "Carbon\\Laravel\\ServiceProvider"
170 | ]
171 | }
172 | },
173 | "autoload": {
174 | "psr-4": {
175 | "": "src/"
176 | }
177 | },
178 | "notification-url": "https://packagist.org/downloads/",
179 | "license": [
180 | "MIT"
181 | ],
182 | "authors": [
183 | {
184 | "name": "Brian Nesbitt",
185 | "email": "brian@nesbot.com",
186 | "homepage": "http://nesbot.com"
187 | }
188 | ],
189 | "description": "A simple API extension for DateTime.",
190 | "homepage": "http://carbon.nesbot.com",
191 | "keywords": [
192 | "date",
193 | "datetime",
194 | "time"
195 | ],
196 | "time": "2018-09-20T19:36:25+00:00"
197 | },
198 | {
199 | "name": "psr/log",
200 | "version": "1.0.2",
201 | "source": {
202 | "type": "git",
203 | "url": "https://github.com/php-fig/log.git",
204 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
205 | },
206 | "dist": {
207 | "type": "zip",
208 | "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
209 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
210 | "shasum": ""
211 | },
212 | "require": {
213 | "php": ">=5.3.0"
214 | },
215 | "type": "library",
216 | "extra": {
217 | "branch-alias": {
218 | "dev-master": "1.0.x-dev"
219 | }
220 | },
221 | "autoload": {
222 | "psr-4": {
223 | "Psr\\Log\\": "Psr/Log/"
224 | }
225 | },
226 | "notification-url": "https://packagist.org/downloads/",
227 | "license": [
228 | "MIT"
229 | ],
230 | "authors": [
231 | {
232 | "name": "PHP-FIG",
233 | "homepage": "http://www.php-fig.org/"
234 | }
235 | ],
236 | "description": "Common interface for logging libraries",
237 | "homepage": "https://github.com/php-fig/log",
238 | "keywords": [
239 | "log",
240 | "psr",
241 | "psr-3"
242 | ],
243 | "time": "2016-10-10T12:19:37+00:00"
244 | },
245 | {
246 | "name": "symfony/http-foundation",
247 | "version": "v4.1.6",
248 | "source": {
249 | "type": "git",
250 | "url": "https://github.com/symfony/http-foundation.git",
251 | "reference": "d528136617ff24f530e70df9605acc1b788b08d4"
252 | },
253 | "dist": {
254 | "type": "zip",
255 | "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d528136617ff24f530e70df9605acc1b788b08d4",
256 | "reference": "d528136617ff24f530e70df9605acc1b788b08d4",
257 | "shasum": ""
258 | },
259 | "require": {
260 | "php": "^7.1.3",
261 | "symfony/polyfill-mbstring": "~1.1"
262 | },
263 | "require-dev": {
264 | "predis/predis": "~1.0",
265 | "symfony/expression-language": "~3.4|~4.0"
266 | },
267 | "type": "library",
268 | "extra": {
269 | "branch-alias": {
270 | "dev-master": "4.1-dev"
271 | }
272 | },
273 | "autoload": {
274 | "psr-4": {
275 | "Symfony\\Component\\HttpFoundation\\": ""
276 | },
277 | "exclude-from-classmap": [
278 | "/Tests/"
279 | ]
280 | },
281 | "notification-url": "https://packagist.org/downloads/",
282 | "license": [
283 | "MIT"
284 | ],
285 | "authors": [
286 | {
287 | "name": "Fabien Potencier",
288 | "email": "fabien@symfony.com"
289 | },
290 | {
291 | "name": "Symfony Community",
292 | "homepage": "https://symfony.com/contributors"
293 | }
294 | ],
295 | "description": "Symfony HttpFoundation Component",
296 | "homepage": "https://symfony.com",
297 | "time": "2018-10-03T08:48:45+00:00"
298 | },
299 | {
300 | "name": "symfony/polyfill-mbstring",
301 | "version": "v1.9.0",
302 | "source": {
303 | "type": "git",
304 | "url": "https://github.com/symfony/polyfill-mbstring.git",
305 | "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8"
306 | },
307 | "dist": {
308 | "type": "zip",
309 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8",
310 | "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8",
311 | "shasum": ""
312 | },
313 | "require": {
314 | "php": ">=5.3.3"
315 | },
316 | "suggest": {
317 | "ext-mbstring": "For best performance"
318 | },
319 | "type": "library",
320 | "extra": {
321 | "branch-alias": {
322 | "dev-master": "1.9-dev"
323 | }
324 | },
325 | "autoload": {
326 | "psr-4": {
327 | "Symfony\\Polyfill\\Mbstring\\": ""
328 | },
329 | "files": [
330 | "bootstrap.php"
331 | ]
332 | },
333 | "notification-url": "https://packagist.org/downloads/",
334 | "license": [
335 | "MIT"
336 | ],
337 | "authors": [
338 | {
339 | "name": "Nicolas Grekas",
340 | "email": "p@tchwork.com"
341 | },
342 | {
343 | "name": "Symfony Community",
344 | "homepage": "https://symfony.com/contributors"
345 | }
346 | ],
347 | "description": "Symfony polyfill for the Mbstring extension",
348 | "homepage": "https://symfony.com",
349 | "keywords": [
350 | "compatibility",
351 | "mbstring",
352 | "polyfill",
353 | "portable",
354 | "shim"
355 | ],
356 | "time": "2018-08-06T14:22:27+00:00"
357 | },
358 | {
359 | "name": "symfony/polyfill-php72",
360 | "version": "v1.9.0",
361 | "source": {
362 | "type": "git",
363 | "url": "https://github.com/symfony/polyfill-php72.git",
364 | "reference": "95c50420b0baed23852452a7f0c7b527303ed5ae"
365 | },
366 | "dist": {
367 | "type": "zip",
368 | "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/95c50420b0baed23852452a7f0c7b527303ed5ae",
369 | "reference": "95c50420b0baed23852452a7f0c7b527303ed5ae",
370 | "shasum": ""
371 | },
372 | "require": {
373 | "php": ">=5.3.3"
374 | },
375 | "type": "library",
376 | "extra": {
377 | "branch-alias": {
378 | "dev-master": "1.9-dev"
379 | }
380 | },
381 | "autoload": {
382 | "psr-4": {
383 | "Symfony\\Polyfill\\Php72\\": ""
384 | },
385 | "files": [
386 | "bootstrap.php"
387 | ]
388 | },
389 | "notification-url": "https://packagist.org/downloads/",
390 | "license": [
391 | "MIT"
392 | ],
393 | "authors": [
394 | {
395 | "name": "Nicolas Grekas",
396 | "email": "p@tchwork.com"
397 | },
398 | {
399 | "name": "Symfony Community",
400 | "homepage": "https://symfony.com/contributors"
401 | }
402 | ],
403 | "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
404 | "homepage": "https://symfony.com",
405 | "keywords": [
406 | "compatibility",
407 | "polyfill",
408 | "portable",
409 | "shim"
410 | ],
411 | "time": "2018-08-06T14:22:27+00:00"
412 | },
413 | {
414 | "name": "symfony/translation",
415 | "version": "v4.1.6",
416 | "source": {
417 | "type": "git",
418 | "url": "https://github.com/symfony/translation.git",
419 | "reference": "9f0b61e339160a466ebcde167a6c5521c810e304"
420 | },
421 | "dist": {
422 | "type": "zip",
423 | "url": "https://api.github.com/repos/symfony/translation/zipball/9f0b61e339160a466ebcde167a6c5521c810e304",
424 | "reference": "9f0b61e339160a466ebcde167a6c5521c810e304",
425 | "shasum": ""
426 | },
427 | "require": {
428 | "php": "^7.1.3",
429 | "symfony/polyfill-mbstring": "~1.0"
430 | },
431 | "conflict": {
432 | "symfony/config": "<3.4",
433 | "symfony/dependency-injection": "<3.4",
434 | "symfony/yaml": "<3.4"
435 | },
436 | "require-dev": {
437 | "psr/log": "~1.0",
438 | "symfony/config": "~3.4|~4.0",
439 | "symfony/console": "~3.4|~4.0",
440 | "symfony/dependency-injection": "~3.4|~4.0",
441 | "symfony/finder": "~2.8|~3.0|~4.0",
442 | "symfony/intl": "~3.4|~4.0",
443 | "symfony/yaml": "~3.4|~4.0"
444 | },
445 | "suggest": {
446 | "psr/log-implementation": "To use logging capability in translator",
447 | "symfony/config": "",
448 | "symfony/yaml": ""
449 | },
450 | "type": "library",
451 | "extra": {
452 | "branch-alias": {
453 | "dev-master": "4.1-dev"
454 | }
455 | },
456 | "autoload": {
457 | "psr-4": {
458 | "Symfony\\Component\\Translation\\": ""
459 | },
460 | "exclude-from-classmap": [
461 | "/Tests/"
462 | ]
463 | },
464 | "notification-url": "https://packagist.org/downloads/",
465 | "license": [
466 | "MIT"
467 | ],
468 | "authors": [
469 | {
470 | "name": "Fabien Potencier",
471 | "email": "fabien@symfony.com"
472 | },
473 | {
474 | "name": "Symfony Community",
475 | "homepage": "https://symfony.com/contributors"
476 | }
477 | ],
478 | "description": "Symfony Translation Component",
479 | "homepage": "https://symfony.com",
480 | "time": "2018-10-02T16:36:10+00:00"
481 | },
482 | {
483 | "name": "symfony/var-dumper",
484 | "version": "v4.1.6",
485 | "source": {
486 | "type": "git",
487 | "url": "https://github.com/symfony/var-dumper.git",
488 | "reference": "60319b45653580b0cdacca499344577d87732f16"
489 | },
490 | "dist": {
491 | "type": "zip",
492 | "url": "https://api.github.com/repos/symfony/var-dumper/zipball/60319b45653580b0cdacca499344577d87732f16",
493 | "reference": "60319b45653580b0cdacca499344577d87732f16",
494 | "shasum": ""
495 | },
496 | "require": {
497 | "php": "^7.1.3",
498 | "symfony/polyfill-mbstring": "~1.0",
499 | "symfony/polyfill-php72": "~1.5"
500 | },
501 | "conflict": {
502 | "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0",
503 | "symfony/console": "<3.4"
504 | },
505 | "require-dev": {
506 | "ext-iconv": "*",
507 | "symfony/process": "~3.4|~4.0",
508 | "twig/twig": "~1.34|~2.4"
509 | },
510 | "suggest": {
511 | "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
512 | "ext-intl": "To show region name in time zone dump",
513 | "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
514 | },
515 | "bin": [
516 | "Resources/bin/var-dump-server"
517 | ],
518 | "type": "library",
519 | "extra": {
520 | "branch-alias": {
521 | "dev-master": "4.1-dev"
522 | }
523 | },
524 | "autoload": {
525 | "files": [
526 | "Resources/functions/dump.php"
527 | ],
528 | "psr-4": {
529 | "Symfony\\Component\\VarDumper\\": ""
530 | },
531 | "exclude-from-classmap": [
532 | "/Tests/"
533 | ]
534 | },
535 | "notification-url": "https://packagist.org/downloads/",
536 | "license": [
537 | "MIT"
538 | ],
539 | "authors": [
540 | {
541 | "name": "Nicolas Grekas",
542 | "email": "p@tchwork.com"
543 | },
544 | {
545 | "name": "Symfony Community",
546 | "homepage": "https://symfony.com/contributors"
547 | }
548 | ],
549 | "description": "Symfony mechanism for exploring and dumping PHP variables",
550 | "homepage": "https://symfony.com",
551 | "keywords": [
552 | "debug",
553 | "dump"
554 | ],
555 | "time": "2018-10-02T16:36:10+00:00"
556 | },
557 | {
558 | "name": "vlucas/phpdotenv",
559 | "version": "v2.5.1",
560 | "source": {
561 | "type": "git",
562 | "url": "https://github.com/vlucas/phpdotenv.git",
563 | "reference": "8abb4f9aa89ddea9d52112c65bbe8d0125e2fa8e"
564 | },
565 | "dist": {
566 | "type": "zip",
567 | "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/8abb4f9aa89ddea9d52112c65bbe8d0125e2fa8e",
568 | "reference": "8abb4f9aa89ddea9d52112c65bbe8d0125e2fa8e",
569 | "shasum": ""
570 | },
571 | "require": {
572 | "php": ">=5.3.9"
573 | },
574 | "require-dev": {
575 | "phpunit/phpunit": "^4.8.35 || ^5.0"
576 | },
577 | "type": "library",
578 | "extra": {
579 | "branch-alias": {
580 | "dev-master": "2.5-dev"
581 | }
582 | },
583 | "autoload": {
584 | "psr-4": {
585 | "Dotenv\\": "src/"
586 | }
587 | },
588 | "notification-url": "https://packagist.org/downloads/",
589 | "license": [
590 | "BSD-3-Clause"
591 | ],
592 | "authors": [
593 | {
594 | "name": "Vance Lucas",
595 | "email": "vance@vancelucas.com",
596 | "homepage": "http://www.vancelucas.com"
597 | }
598 | ],
599 | "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.",
600 | "keywords": [
601 | "dotenv",
602 | "env",
603 | "environment"
604 | ],
605 | "time": "2018-07-29T20:33:41+00:00"
606 | }
607 | ],
608 | "packages-dev": [
609 | {
610 | "name": "doctrine/instantiator",
611 | "version": "1.1.0",
612 | "source": {
613 | "type": "git",
614 | "url": "https://github.com/doctrine/instantiator.git",
615 | "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda"
616 | },
617 | "dist": {
618 | "type": "zip",
619 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
620 | "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
621 | "shasum": ""
622 | },
623 | "require": {
624 | "php": "^7.1"
625 | },
626 | "require-dev": {
627 | "athletic/athletic": "~0.1.8",
628 | "ext-pdo": "*",
629 | "ext-phar": "*",
630 | "phpunit/phpunit": "^6.2.3",
631 | "squizlabs/php_codesniffer": "^3.0.2"
632 | },
633 | "type": "library",
634 | "extra": {
635 | "branch-alias": {
636 | "dev-master": "1.2.x-dev"
637 | }
638 | },
639 | "autoload": {
640 | "psr-4": {
641 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
642 | }
643 | },
644 | "notification-url": "https://packagist.org/downloads/",
645 | "license": [
646 | "MIT"
647 | ],
648 | "authors": [
649 | {
650 | "name": "Marco Pivetta",
651 | "email": "ocramius@gmail.com",
652 | "homepage": "http://ocramius.github.com/"
653 | }
654 | ],
655 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
656 | "homepage": "https://github.com/doctrine/instantiator",
657 | "keywords": [
658 | "constructor",
659 | "instantiate"
660 | ],
661 | "time": "2017-07-22T11:58:36+00:00"
662 | },
663 | {
664 | "name": "hamcrest/hamcrest-php",
665 | "version": "v1.2.2",
666 | "source": {
667 | "type": "git",
668 | "url": "https://github.com/hamcrest/hamcrest-php.git",
669 | "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c"
670 | },
671 | "dist": {
672 | "type": "zip",
673 | "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/b37020aa976fa52d3de9aa904aa2522dc518f79c",
674 | "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c",
675 | "shasum": ""
676 | },
677 | "require": {
678 | "php": ">=5.3.2"
679 | },
680 | "replace": {
681 | "cordoval/hamcrest-php": "*",
682 | "davedevelopment/hamcrest-php": "*",
683 | "kodova/hamcrest-php": "*"
684 | },
685 | "require-dev": {
686 | "phpunit/php-file-iterator": "1.3.3",
687 | "satooshi/php-coveralls": "dev-master"
688 | },
689 | "type": "library",
690 | "autoload": {
691 | "classmap": [
692 | "hamcrest"
693 | ],
694 | "files": [
695 | "hamcrest/Hamcrest.php"
696 | ]
697 | },
698 | "notification-url": "https://packagist.org/downloads/",
699 | "license": [
700 | "BSD"
701 | ],
702 | "description": "This is the PHP port of Hamcrest Matchers",
703 | "keywords": [
704 | "test"
705 | ],
706 | "time": "2015-05-11T14:41:42+00:00"
707 | },
708 | {
709 | "name": "mockery/mockery",
710 | "version": "0.9.9",
711 | "source": {
712 | "type": "git",
713 | "url": "https://github.com/mockery/mockery.git",
714 | "reference": "6fdb61243844dc924071d3404bb23994ea0b6856"
715 | },
716 | "dist": {
717 | "type": "zip",
718 | "url": "https://api.github.com/repos/mockery/mockery/zipball/6fdb61243844dc924071d3404bb23994ea0b6856",
719 | "reference": "6fdb61243844dc924071d3404bb23994ea0b6856",
720 | "shasum": ""
721 | },
722 | "require": {
723 | "hamcrest/hamcrest-php": "~1.1",
724 | "lib-pcre": ">=7.0",
725 | "php": ">=5.3.2"
726 | },
727 | "require-dev": {
728 | "phpunit/phpunit": "~4.0"
729 | },
730 | "type": "library",
731 | "extra": {
732 | "branch-alias": {
733 | "dev-master": "0.9.x-dev"
734 | }
735 | },
736 | "autoload": {
737 | "psr-0": {
738 | "Mockery": "library/"
739 | }
740 | },
741 | "notification-url": "https://packagist.org/downloads/",
742 | "license": [
743 | "BSD-3-Clause"
744 | ],
745 | "authors": [
746 | {
747 | "name": "Pádraic Brady",
748 | "email": "padraic.brady@gmail.com",
749 | "homepage": "http://blog.astrumfutura.com"
750 | },
751 | {
752 | "name": "Dave Marshall",
753 | "email": "dave.marshall@atstsolutions.co.uk",
754 | "homepage": "http://davedevelopment.co.uk"
755 | }
756 | ],
757 | "description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.",
758 | "homepage": "http://github.com/padraic/mockery",
759 | "keywords": [
760 | "BDD",
761 | "TDD",
762 | "library",
763 | "mock",
764 | "mock objects",
765 | "mockery",
766 | "stub",
767 | "test",
768 | "test double",
769 | "testing"
770 | ],
771 | "time": "2017-02-28T12:52:32+00:00"
772 | },
773 | {
774 | "name": "phpdocumentor/reflection-common",
775 | "version": "1.0.1",
776 | "source": {
777 | "type": "git",
778 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
779 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
780 | },
781 | "dist": {
782 | "type": "zip",
783 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
784 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
785 | "shasum": ""
786 | },
787 | "require": {
788 | "php": ">=5.5"
789 | },
790 | "require-dev": {
791 | "phpunit/phpunit": "^4.6"
792 | },
793 | "type": "library",
794 | "extra": {
795 | "branch-alias": {
796 | "dev-master": "1.0.x-dev"
797 | }
798 | },
799 | "autoload": {
800 | "psr-4": {
801 | "phpDocumentor\\Reflection\\": [
802 | "src"
803 | ]
804 | }
805 | },
806 | "notification-url": "https://packagist.org/downloads/",
807 | "license": [
808 | "MIT"
809 | ],
810 | "authors": [
811 | {
812 | "name": "Jaap van Otterdijk",
813 | "email": "opensource@ijaap.nl"
814 | }
815 | ],
816 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
817 | "homepage": "http://www.phpdoc.org",
818 | "keywords": [
819 | "FQSEN",
820 | "phpDocumentor",
821 | "phpdoc",
822 | "reflection",
823 | "static analysis"
824 | ],
825 | "time": "2017-09-11T18:02:19+00:00"
826 | },
827 | {
828 | "name": "phpdocumentor/reflection-docblock",
829 | "version": "4.3.0",
830 | "source": {
831 | "type": "git",
832 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
833 | "reference": "94fd0001232e47129dd3504189fa1c7225010d08"
834 | },
835 | "dist": {
836 | "type": "zip",
837 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08",
838 | "reference": "94fd0001232e47129dd3504189fa1c7225010d08",
839 | "shasum": ""
840 | },
841 | "require": {
842 | "php": "^7.0",
843 | "phpdocumentor/reflection-common": "^1.0.0",
844 | "phpdocumentor/type-resolver": "^0.4.0",
845 | "webmozart/assert": "^1.0"
846 | },
847 | "require-dev": {
848 | "doctrine/instantiator": "~1.0.5",
849 | "mockery/mockery": "^1.0",
850 | "phpunit/phpunit": "^6.4"
851 | },
852 | "type": "library",
853 | "extra": {
854 | "branch-alias": {
855 | "dev-master": "4.x-dev"
856 | }
857 | },
858 | "autoload": {
859 | "psr-4": {
860 | "phpDocumentor\\Reflection\\": [
861 | "src/"
862 | ]
863 | }
864 | },
865 | "notification-url": "https://packagist.org/downloads/",
866 | "license": [
867 | "MIT"
868 | ],
869 | "authors": [
870 | {
871 | "name": "Mike van Riel",
872 | "email": "me@mikevanriel.com"
873 | }
874 | ],
875 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
876 | "time": "2017-11-30T07:14:17+00:00"
877 | },
878 | {
879 | "name": "phpdocumentor/type-resolver",
880 | "version": "0.4.0",
881 | "source": {
882 | "type": "git",
883 | "url": "https://github.com/phpDocumentor/TypeResolver.git",
884 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
885 | },
886 | "dist": {
887 | "type": "zip",
888 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
889 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
890 | "shasum": ""
891 | },
892 | "require": {
893 | "php": "^5.5 || ^7.0",
894 | "phpdocumentor/reflection-common": "^1.0"
895 | },
896 | "require-dev": {
897 | "mockery/mockery": "^0.9.4",
898 | "phpunit/phpunit": "^5.2||^4.8.24"
899 | },
900 | "type": "library",
901 | "extra": {
902 | "branch-alias": {
903 | "dev-master": "1.0.x-dev"
904 | }
905 | },
906 | "autoload": {
907 | "psr-4": {
908 | "phpDocumentor\\Reflection\\": [
909 | "src/"
910 | ]
911 | }
912 | },
913 | "notification-url": "https://packagist.org/downloads/",
914 | "license": [
915 | "MIT"
916 | ],
917 | "authors": [
918 | {
919 | "name": "Mike van Riel",
920 | "email": "me@mikevanriel.com"
921 | }
922 | ],
923 | "time": "2017-07-14T14:27:02+00:00"
924 | },
925 | {
926 | "name": "phpspec/php-diff",
927 | "version": "v1.0.2",
928 | "source": {
929 | "type": "git",
930 | "url": "https://github.com/phpspec/php-diff.git",
931 | "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a"
932 | },
933 | "dist": {
934 | "type": "zip",
935 | "url": "https://api.github.com/repos/phpspec/php-diff/zipball/30e103d19519fe678ae64a60d77884ef3d71b28a",
936 | "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a",
937 | "shasum": ""
938 | },
939 | "type": "library",
940 | "autoload": {
941 | "psr-0": {
942 | "Diff": "lib/"
943 | }
944 | },
945 | "notification-url": "https://packagist.org/downloads/",
946 | "license": [
947 | "BSD-3-Clause"
948 | ],
949 | "authors": [
950 | {
951 | "name": "Chris Boulton",
952 | "homepage": "http://github.com/chrisboulton"
953 | }
954 | ],
955 | "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).",
956 | "time": "2013-11-01T13:02:21+00:00"
957 | },
958 | {
959 | "name": "phpspec/phpspec",
960 | "version": "2.4.1",
961 | "source": {
962 | "type": "git",
963 | "url": "https://github.com/phpspec/phpspec.git",
964 | "reference": "5528ce1e93a1efa090c9404aba3395c329b4e6ed"
965 | },
966 | "dist": {
967 | "type": "zip",
968 | "url": "https://api.github.com/repos/phpspec/phpspec/zipball/5528ce1e93a1efa090c9404aba3395c329b4e6ed",
969 | "reference": "5528ce1e93a1efa090c9404aba3395c329b4e6ed",
970 | "shasum": ""
971 | },
972 | "require": {
973 | "doctrine/instantiator": "^1.0.1",
974 | "ext-tokenizer": "*",
975 | "php": ">=5.3.3",
976 | "phpspec/php-diff": "~1.0.0",
977 | "phpspec/prophecy": "~1.4",
978 | "sebastian/exporter": "~1.0",
979 | "symfony/console": "~2.3|~3.0",
980 | "symfony/event-dispatcher": "~2.1|~3.0",
981 | "symfony/finder": "~2.1|~3.0",
982 | "symfony/process": "^2.6|~3.0",
983 | "symfony/yaml": "~2.1|~3.0"
984 | },
985 | "require-dev": {
986 | "behat/behat": "^3.0.11",
987 | "bossa/phpspec2-expect": "~1.0",
988 | "phpunit/phpunit": "~4.4",
989 | "symfony/filesystem": "~2.1|~3.0"
990 | },
991 | "suggest": {
992 | "phpspec/nyan-formatters": "~1.0 – Adds Nyan formatters"
993 | },
994 | "bin": [
995 | "bin/phpspec"
996 | ],
997 | "type": "library",
998 | "extra": {
999 | "branch-alias": {
1000 | "dev-master": "2.2.x-dev"
1001 | }
1002 | },
1003 | "autoload": {
1004 | "psr-0": {
1005 | "PhpSpec": "src/"
1006 | }
1007 | },
1008 | "notification-url": "https://packagist.org/downloads/",
1009 | "license": [
1010 | "MIT"
1011 | ],
1012 | "authors": [
1013 | {
1014 | "name": "Konstantin Kudryashov",
1015 | "email": "ever.zet@gmail.com",
1016 | "homepage": "http://everzet.com"
1017 | },
1018 | {
1019 | "name": "Marcello Duarte",
1020 | "homepage": "http://marcelloduarte.net/"
1021 | }
1022 | ],
1023 | "description": "Specification-oriented BDD framework for PHP 5.3+",
1024 | "homepage": "http://phpspec.net/",
1025 | "keywords": [
1026 | "BDD",
1027 | "SpecBDD",
1028 | "TDD",
1029 | "spec",
1030 | "specification",
1031 | "testing",
1032 | "tests"
1033 | ],
1034 | "time": "2016-01-01T10:17:54+00:00"
1035 | },
1036 | {
1037 | "name": "phpspec/prophecy",
1038 | "version": "1.8.0",
1039 | "source": {
1040 | "type": "git",
1041 | "url": "https://github.com/phpspec/prophecy.git",
1042 | "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06"
1043 | },
1044 | "dist": {
1045 | "type": "zip",
1046 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
1047 | "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
1048 | "shasum": ""
1049 | },
1050 | "require": {
1051 | "doctrine/instantiator": "^1.0.2",
1052 | "php": "^5.3|^7.0",
1053 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
1054 | "sebastian/comparator": "^1.1|^2.0|^3.0",
1055 | "sebastian/recursion-context": "^1.0|^2.0|^3.0"
1056 | },
1057 | "require-dev": {
1058 | "phpspec/phpspec": "^2.5|^3.2",
1059 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
1060 | },
1061 | "type": "library",
1062 | "extra": {
1063 | "branch-alias": {
1064 | "dev-master": "1.8.x-dev"
1065 | }
1066 | },
1067 | "autoload": {
1068 | "psr-0": {
1069 | "Prophecy\\": "src/"
1070 | }
1071 | },
1072 | "notification-url": "https://packagist.org/downloads/",
1073 | "license": [
1074 | "MIT"
1075 | ],
1076 | "authors": [
1077 | {
1078 | "name": "Konstantin Kudryashov",
1079 | "email": "ever.zet@gmail.com",
1080 | "homepage": "http://everzet.com"
1081 | },
1082 | {
1083 | "name": "Marcello Duarte",
1084 | "email": "marcello.duarte@gmail.com"
1085 | }
1086 | ],
1087 | "description": "Highly opinionated mocking framework for PHP 5.3+",
1088 | "homepage": "https://github.com/phpspec/prophecy",
1089 | "keywords": [
1090 | "Double",
1091 | "Dummy",
1092 | "fake",
1093 | "mock",
1094 | "spy",
1095 | "stub"
1096 | ],
1097 | "time": "2018-08-05T17:53:17+00:00"
1098 | },
1099 | {
1100 | "name": "phpunit/php-code-coverage",
1101 | "version": "2.2.4",
1102 | "source": {
1103 | "type": "git",
1104 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
1105 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
1106 | },
1107 | "dist": {
1108 | "type": "zip",
1109 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
1110 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
1111 | "shasum": ""
1112 | },
1113 | "require": {
1114 | "php": ">=5.3.3",
1115 | "phpunit/php-file-iterator": "~1.3",
1116 | "phpunit/php-text-template": "~1.2",
1117 | "phpunit/php-token-stream": "~1.3",
1118 | "sebastian/environment": "^1.3.2",
1119 | "sebastian/version": "~1.0"
1120 | },
1121 | "require-dev": {
1122 | "ext-xdebug": ">=2.1.4",
1123 | "phpunit/phpunit": "~4"
1124 | },
1125 | "suggest": {
1126 | "ext-dom": "*",
1127 | "ext-xdebug": ">=2.2.1",
1128 | "ext-xmlwriter": "*"
1129 | },
1130 | "type": "library",
1131 | "extra": {
1132 | "branch-alias": {
1133 | "dev-master": "2.2.x-dev"
1134 | }
1135 | },
1136 | "autoload": {
1137 | "classmap": [
1138 | "src/"
1139 | ]
1140 | },
1141 | "notification-url": "https://packagist.org/downloads/",
1142 | "license": [
1143 | "BSD-3-Clause"
1144 | ],
1145 | "authors": [
1146 | {
1147 | "name": "Sebastian Bergmann",
1148 | "email": "sb@sebastian-bergmann.de",
1149 | "role": "lead"
1150 | }
1151 | ],
1152 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
1153 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
1154 | "keywords": [
1155 | "coverage",
1156 | "testing",
1157 | "xunit"
1158 | ],
1159 | "time": "2015-10-06T15:47:00+00:00"
1160 | },
1161 | {
1162 | "name": "phpunit/php-file-iterator",
1163 | "version": "1.4.5",
1164 | "source": {
1165 | "type": "git",
1166 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
1167 | "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4"
1168 | },
1169 | "dist": {
1170 | "type": "zip",
1171 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4",
1172 | "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4",
1173 | "shasum": ""
1174 | },
1175 | "require": {
1176 | "php": ">=5.3.3"
1177 | },
1178 | "type": "library",
1179 | "extra": {
1180 | "branch-alias": {
1181 | "dev-master": "1.4.x-dev"
1182 | }
1183 | },
1184 | "autoload": {
1185 | "classmap": [
1186 | "src/"
1187 | ]
1188 | },
1189 | "notification-url": "https://packagist.org/downloads/",
1190 | "license": [
1191 | "BSD-3-Clause"
1192 | ],
1193 | "authors": [
1194 | {
1195 | "name": "Sebastian Bergmann",
1196 | "email": "sb@sebastian-bergmann.de",
1197 | "role": "lead"
1198 | }
1199 | ],
1200 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
1201 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
1202 | "keywords": [
1203 | "filesystem",
1204 | "iterator"
1205 | ],
1206 | "time": "2017-11-27T13:52:08+00:00"
1207 | },
1208 | {
1209 | "name": "phpunit/php-text-template",
1210 | "version": "1.2.1",
1211 | "source": {
1212 | "type": "git",
1213 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
1214 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
1215 | },
1216 | "dist": {
1217 | "type": "zip",
1218 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
1219 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
1220 | "shasum": ""
1221 | },
1222 | "require": {
1223 | "php": ">=5.3.3"
1224 | },
1225 | "type": "library",
1226 | "autoload": {
1227 | "classmap": [
1228 | "src/"
1229 | ]
1230 | },
1231 | "notification-url": "https://packagist.org/downloads/",
1232 | "license": [
1233 | "BSD-3-Clause"
1234 | ],
1235 | "authors": [
1236 | {
1237 | "name": "Sebastian Bergmann",
1238 | "email": "sebastian@phpunit.de",
1239 | "role": "lead"
1240 | }
1241 | ],
1242 | "description": "Simple template engine.",
1243 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
1244 | "keywords": [
1245 | "template"
1246 | ],
1247 | "time": "2015-06-21T13:50:34+00:00"
1248 | },
1249 | {
1250 | "name": "phpunit/php-timer",
1251 | "version": "1.0.9",
1252 | "source": {
1253 | "type": "git",
1254 | "url": "https://github.com/sebastianbergmann/php-timer.git",
1255 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f"
1256 | },
1257 | "dist": {
1258 | "type": "zip",
1259 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
1260 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
1261 | "shasum": ""
1262 | },
1263 | "require": {
1264 | "php": "^5.3.3 || ^7.0"
1265 | },
1266 | "require-dev": {
1267 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
1268 | },
1269 | "type": "library",
1270 | "extra": {
1271 | "branch-alias": {
1272 | "dev-master": "1.0-dev"
1273 | }
1274 | },
1275 | "autoload": {
1276 | "classmap": [
1277 | "src/"
1278 | ]
1279 | },
1280 | "notification-url": "https://packagist.org/downloads/",
1281 | "license": [
1282 | "BSD-3-Clause"
1283 | ],
1284 | "authors": [
1285 | {
1286 | "name": "Sebastian Bergmann",
1287 | "email": "sb@sebastian-bergmann.de",
1288 | "role": "lead"
1289 | }
1290 | ],
1291 | "description": "Utility class for timing",
1292 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
1293 | "keywords": [
1294 | "timer"
1295 | ],
1296 | "time": "2017-02-26T11:10:40+00:00"
1297 | },
1298 | {
1299 | "name": "phpunit/php-token-stream",
1300 | "version": "1.4.12",
1301 | "source": {
1302 | "type": "git",
1303 | "url": "https://github.com/sebastianbergmann/php-token-stream.git",
1304 | "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16"
1305 | },
1306 | "dist": {
1307 | "type": "zip",
1308 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16",
1309 | "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16",
1310 | "shasum": ""
1311 | },
1312 | "require": {
1313 | "ext-tokenizer": "*",
1314 | "php": ">=5.3.3"
1315 | },
1316 | "require-dev": {
1317 | "phpunit/phpunit": "~4.2"
1318 | },
1319 | "type": "library",
1320 | "extra": {
1321 | "branch-alias": {
1322 | "dev-master": "1.4-dev"
1323 | }
1324 | },
1325 | "autoload": {
1326 | "classmap": [
1327 | "src/"
1328 | ]
1329 | },
1330 | "notification-url": "https://packagist.org/downloads/",
1331 | "license": [
1332 | "BSD-3-Clause"
1333 | ],
1334 | "authors": [
1335 | {
1336 | "name": "Sebastian Bergmann",
1337 | "email": "sebastian@phpunit.de"
1338 | }
1339 | ],
1340 | "description": "Wrapper around PHP's tokenizer extension.",
1341 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
1342 | "keywords": [
1343 | "tokenizer"
1344 | ],
1345 | "time": "2017-12-04T08:55:13+00:00"
1346 | },
1347 | {
1348 | "name": "phpunit/phpunit",
1349 | "version": "4.8.36",
1350 | "source": {
1351 | "type": "git",
1352 | "url": "https://github.com/sebastianbergmann/phpunit.git",
1353 | "reference": "46023de9a91eec7dfb06cc56cb4e260017298517"
1354 | },
1355 | "dist": {
1356 | "type": "zip",
1357 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517",
1358 | "reference": "46023de9a91eec7dfb06cc56cb4e260017298517",
1359 | "shasum": ""
1360 | },
1361 | "require": {
1362 | "ext-dom": "*",
1363 | "ext-json": "*",
1364 | "ext-pcre": "*",
1365 | "ext-reflection": "*",
1366 | "ext-spl": "*",
1367 | "php": ">=5.3.3",
1368 | "phpspec/prophecy": "^1.3.1",
1369 | "phpunit/php-code-coverage": "~2.1",
1370 | "phpunit/php-file-iterator": "~1.4",
1371 | "phpunit/php-text-template": "~1.2",
1372 | "phpunit/php-timer": "^1.0.6",
1373 | "phpunit/phpunit-mock-objects": "~2.3",
1374 | "sebastian/comparator": "~1.2.2",
1375 | "sebastian/diff": "~1.2",
1376 | "sebastian/environment": "~1.3",
1377 | "sebastian/exporter": "~1.2",
1378 | "sebastian/global-state": "~1.0",
1379 | "sebastian/version": "~1.0",
1380 | "symfony/yaml": "~2.1|~3.0"
1381 | },
1382 | "suggest": {
1383 | "phpunit/php-invoker": "~1.1"
1384 | },
1385 | "bin": [
1386 | "phpunit"
1387 | ],
1388 | "type": "library",
1389 | "extra": {
1390 | "branch-alias": {
1391 | "dev-master": "4.8.x-dev"
1392 | }
1393 | },
1394 | "autoload": {
1395 | "classmap": [
1396 | "src/"
1397 | ]
1398 | },
1399 | "notification-url": "https://packagist.org/downloads/",
1400 | "license": [
1401 | "BSD-3-Clause"
1402 | ],
1403 | "authors": [
1404 | {
1405 | "name": "Sebastian Bergmann",
1406 | "email": "sebastian@phpunit.de",
1407 | "role": "lead"
1408 | }
1409 | ],
1410 | "description": "The PHP Unit Testing framework.",
1411 | "homepage": "https://phpunit.de/",
1412 | "keywords": [
1413 | "phpunit",
1414 | "testing",
1415 | "xunit"
1416 | ],
1417 | "time": "2017-06-21T08:07:12+00:00"
1418 | },
1419 | {
1420 | "name": "phpunit/phpunit-mock-objects",
1421 | "version": "2.3.8",
1422 | "source": {
1423 | "type": "git",
1424 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
1425 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
1426 | },
1427 | "dist": {
1428 | "type": "zip",
1429 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
1430 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
1431 | "shasum": ""
1432 | },
1433 | "require": {
1434 | "doctrine/instantiator": "^1.0.2",
1435 | "php": ">=5.3.3",
1436 | "phpunit/php-text-template": "~1.2",
1437 | "sebastian/exporter": "~1.2"
1438 | },
1439 | "require-dev": {
1440 | "phpunit/phpunit": "~4.4"
1441 | },
1442 | "suggest": {
1443 | "ext-soap": "*"
1444 | },
1445 | "type": "library",
1446 | "extra": {
1447 | "branch-alias": {
1448 | "dev-master": "2.3.x-dev"
1449 | }
1450 | },
1451 | "autoload": {
1452 | "classmap": [
1453 | "src/"
1454 | ]
1455 | },
1456 | "notification-url": "https://packagist.org/downloads/",
1457 | "license": [
1458 | "BSD-3-Clause"
1459 | ],
1460 | "authors": [
1461 | {
1462 | "name": "Sebastian Bergmann",
1463 | "email": "sb@sebastian-bergmann.de",
1464 | "role": "lead"
1465 | }
1466 | ],
1467 | "description": "Mock Object library for PHPUnit",
1468 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
1469 | "keywords": [
1470 | "mock",
1471 | "xunit"
1472 | ],
1473 | "time": "2015-10-02T06:51:40+00:00"
1474 | },
1475 | {
1476 | "name": "sebastian/comparator",
1477 | "version": "1.2.4",
1478 | "source": {
1479 | "type": "git",
1480 | "url": "https://github.com/sebastianbergmann/comparator.git",
1481 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be"
1482 | },
1483 | "dist": {
1484 | "type": "zip",
1485 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
1486 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
1487 | "shasum": ""
1488 | },
1489 | "require": {
1490 | "php": ">=5.3.3",
1491 | "sebastian/diff": "~1.2",
1492 | "sebastian/exporter": "~1.2 || ~2.0"
1493 | },
1494 | "require-dev": {
1495 | "phpunit/phpunit": "~4.4"
1496 | },
1497 | "type": "library",
1498 | "extra": {
1499 | "branch-alias": {
1500 | "dev-master": "1.2.x-dev"
1501 | }
1502 | },
1503 | "autoload": {
1504 | "classmap": [
1505 | "src/"
1506 | ]
1507 | },
1508 | "notification-url": "https://packagist.org/downloads/",
1509 | "license": [
1510 | "BSD-3-Clause"
1511 | ],
1512 | "authors": [
1513 | {
1514 | "name": "Jeff Welch",
1515 | "email": "whatthejeff@gmail.com"
1516 | },
1517 | {
1518 | "name": "Volker Dusch",
1519 | "email": "github@wallbash.com"
1520 | },
1521 | {
1522 | "name": "Bernhard Schussek",
1523 | "email": "bschussek@2bepublished.at"
1524 | },
1525 | {
1526 | "name": "Sebastian Bergmann",
1527 | "email": "sebastian@phpunit.de"
1528 | }
1529 | ],
1530 | "description": "Provides the functionality to compare PHP values for equality",
1531 | "homepage": "http://www.github.com/sebastianbergmann/comparator",
1532 | "keywords": [
1533 | "comparator",
1534 | "compare",
1535 | "equality"
1536 | ],
1537 | "time": "2017-01-29T09:50:25+00:00"
1538 | },
1539 | {
1540 | "name": "sebastian/diff",
1541 | "version": "1.4.3",
1542 | "source": {
1543 | "type": "git",
1544 | "url": "https://github.com/sebastianbergmann/diff.git",
1545 | "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4"
1546 | },
1547 | "dist": {
1548 | "type": "zip",
1549 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4",
1550 | "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4",
1551 | "shasum": ""
1552 | },
1553 | "require": {
1554 | "php": "^5.3.3 || ^7.0"
1555 | },
1556 | "require-dev": {
1557 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
1558 | },
1559 | "type": "library",
1560 | "extra": {
1561 | "branch-alias": {
1562 | "dev-master": "1.4-dev"
1563 | }
1564 | },
1565 | "autoload": {
1566 | "classmap": [
1567 | "src/"
1568 | ]
1569 | },
1570 | "notification-url": "https://packagist.org/downloads/",
1571 | "license": [
1572 | "BSD-3-Clause"
1573 | ],
1574 | "authors": [
1575 | {
1576 | "name": "Kore Nordmann",
1577 | "email": "mail@kore-nordmann.de"
1578 | },
1579 | {
1580 | "name": "Sebastian Bergmann",
1581 | "email": "sebastian@phpunit.de"
1582 | }
1583 | ],
1584 | "description": "Diff implementation",
1585 | "homepage": "https://github.com/sebastianbergmann/diff",
1586 | "keywords": [
1587 | "diff"
1588 | ],
1589 | "time": "2017-05-22T07:24:03+00:00"
1590 | },
1591 | {
1592 | "name": "sebastian/environment",
1593 | "version": "1.3.8",
1594 | "source": {
1595 | "type": "git",
1596 | "url": "https://github.com/sebastianbergmann/environment.git",
1597 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea"
1598 | },
1599 | "dist": {
1600 | "type": "zip",
1601 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea",
1602 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea",
1603 | "shasum": ""
1604 | },
1605 | "require": {
1606 | "php": "^5.3.3 || ^7.0"
1607 | },
1608 | "require-dev": {
1609 | "phpunit/phpunit": "^4.8 || ^5.0"
1610 | },
1611 | "type": "library",
1612 | "extra": {
1613 | "branch-alias": {
1614 | "dev-master": "1.3.x-dev"
1615 | }
1616 | },
1617 | "autoload": {
1618 | "classmap": [
1619 | "src/"
1620 | ]
1621 | },
1622 | "notification-url": "https://packagist.org/downloads/",
1623 | "license": [
1624 | "BSD-3-Clause"
1625 | ],
1626 | "authors": [
1627 | {
1628 | "name": "Sebastian Bergmann",
1629 | "email": "sebastian@phpunit.de"
1630 | }
1631 | ],
1632 | "description": "Provides functionality to handle HHVM/PHP environments",
1633 | "homepage": "http://www.github.com/sebastianbergmann/environment",
1634 | "keywords": [
1635 | "Xdebug",
1636 | "environment",
1637 | "hhvm"
1638 | ],
1639 | "time": "2016-08-18T05:49:44+00:00"
1640 | },
1641 | {
1642 | "name": "sebastian/exporter",
1643 | "version": "1.2.2",
1644 | "source": {
1645 | "type": "git",
1646 | "url": "https://github.com/sebastianbergmann/exporter.git",
1647 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4"
1648 | },
1649 | "dist": {
1650 | "type": "zip",
1651 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4",
1652 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4",
1653 | "shasum": ""
1654 | },
1655 | "require": {
1656 | "php": ">=5.3.3",
1657 | "sebastian/recursion-context": "~1.0"
1658 | },
1659 | "require-dev": {
1660 | "ext-mbstring": "*",
1661 | "phpunit/phpunit": "~4.4"
1662 | },
1663 | "type": "library",
1664 | "extra": {
1665 | "branch-alias": {
1666 | "dev-master": "1.3.x-dev"
1667 | }
1668 | },
1669 | "autoload": {
1670 | "classmap": [
1671 | "src/"
1672 | ]
1673 | },
1674 | "notification-url": "https://packagist.org/downloads/",
1675 | "license": [
1676 | "BSD-3-Clause"
1677 | ],
1678 | "authors": [
1679 | {
1680 | "name": "Jeff Welch",
1681 | "email": "whatthejeff@gmail.com"
1682 | },
1683 | {
1684 | "name": "Volker Dusch",
1685 | "email": "github@wallbash.com"
1686 | },
1687 | {
1688 | "name": "Bernhard Schussek",
1689 | "email": "bschussek@2bepublished.at"
1690 | },
1691 | {
1692 | "name": "Sebastian Bergmann",
1693 | "email": "sebastian@phpunit.de"
1694 | },
1695 | {
1696 | "name": "Adam Harvey",
1697 | "email": "aharvey@php.net"
1698 | }
1699 | ],
1700 | "description": "Provides the functionality to export PHP variables for visualization",
1701 | "homepage": "http://www.github.com/sebastianbergmann/exporter",
1702 | "keywords": [
1703 | "export",
1704 | "exporter"
1705 | ],
1706 | "time": "2016-06-17T09:04:28+00:00"
1707 | },
1708 | {
1709 | "name": "sebastian/global-state",
1710 | "version": "1.1.1",
1711 | "source": {
1712 | "type": "git",
1713 | "url": "https://github.com/sebastianbergmann/global-state.git",
1714 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
1715 | },
1716 | "dist": {
1717 | "type": "zip",
1718 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
1719 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
1720 | "shasum": ""
1721 | },
1722 | "require": {
1723 | "php": ">=5.3.3"
1724 | },
1725 | "require-dev": {
1726 | "phpunit/phpunit": "~4.2"
1727 | },
1728 | "suggest": {
1729 | "ext-uopz": "*"
1730 | },
1731 | "type": "library",
1732 | "extra": {
1733 | "branch-alias": {
1734 | "dev-master": "1.0-dev"
1735 | }
1736 | },
1737 | "autoload": {
1738 | "classmap": [
1739 | "src/"
1740 | ]
1741 | },
1742 | "notification-url": "https://packagist.org/downloads/",
1743 | "license": [
1744 | "BSD-3-Clause"
1745 | ],
1746 | "authors": [
1747 | {
1748 | "name": "Sebastian Bergmann",
1749 | "email": "sebastian@phpunit.de"
1750 | }
1751 | ],
1752 | "description": "Snapshotting of global state",
1753 | "homepage": "http://www.github.com/sebastianbergmann/global-state",
1754 | "keywords": [
1755 | "global state"
1756 | ],
1757 | "time": "2015-10-12T03:26:01+00:00"
1758 | },
1759 | {
1760 | "name": "sebastian/recursion-context",
1761 | "version": "1.0.5",
1762 | "source": {
1763 | "type": "git",
1764 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
1765 | "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7"
1766 | },
1767 | "dist": {
1768 | "type": "zip",
1769 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
1770 | "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
1771 | "shasum": ""
1772 | },
1773 | "require": {
1774 | "php": ">=5.3.3"
1775 | },
1776 | "require-dev": {
1777 | "phpunit/phpunit": "~4.4"
1778 | },
1779 | "type": "library",
1780 | "extra": {
1781 | "branch-alias": {
1782 | "dev-master": "1.0.x-dev"
1783 | }
1784 | },
1785 | "autoload": {
1786 | "classmap": [
1787 | "src/"
1788 | ]
1789 | },
1790 | "notification-url": "https://packagist.org/downloads/",
1791 | "license": [
1792 | "BSD-3-Clause"
1793 | ],
1794 | "authors": [
1795 | {
1796 | "name": "Jeff Welch",
1797 | "email": "whatthejeff@gmail.com"
1798 | },
1799 | {
1800 | "name": "Sebastian Bergmann",
1801 | "email": "sebastian@phpunit.de"
1802 | },
1803 | {
1804 | "name": "Adam Harvey",
1805 | "email": "aharvey@php.net"
1806 | }
1807 | ],
1808 | "description": "Provides functionality to recursively process PHP variables",
1809 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1810 | "time": "2016-10-03T07:41:43+00:00"
1811 | },
1812 | {
1813 | "name": "sebastian/version",
1814 | "version": "1.0.6",
1815 | "source": {
1816 | "type": "git",
1817 | "url": "https://github.com/sebastianbergmann/version.git",
1818 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
1819 | },
1820 | "dist": {
1821 | "type": "zip",
1822 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1823 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1824 | "shasum": ""
1825 | },
1826 | "type": "library",
1827 | "autoload": {
1828 | "classmap": [
1829 | "src/"
1830 | ]
1831 | },
1832 | "notification-url": "https://packagist.org/downloads/",
1833 | "license": [
1834 | "BSD-3-Clause"
1835 | ],
1836 | "authors": [
1837 | {
1838 | "name": "Sebastian Bergmann",
1839 | "email": "sebastian@phpunit.de",
1840 | "role": "lead"
1841 | }
1842 | ],
1843 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1844 | "homepage": "https://github.com/sebastianbergmann/version",
1845 | "time": "2015-06-21T13:59:46+00:00"
1846 | },
1847 | {
1848 | "name": "squizlabs/php_codesniffer",
1849 | "version": "2.5.1",
1850 | "source": {
1851 | "type": "git",
1852 | "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
1853 | "reference": "6731851d6aaf1d0d6c58feff1065227b7fda3ba8"
1854 | },
1855 | "dist": {
1856 | "type": "zip",
1857 | "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/6731851d6aaf1d0d6c58feff1065227b7fda3ba8",
1858 | "reference": "6731851d6aaf1d0d6c58feff1065227b7fda3ba8",
1859 | "shasum": ""
1860 | },
1861 | "require": {
1862 | "ext-tokenizer": "*",
1863 | "ext-xmlwriter": "*",
1864 | "php": ">=5.1.2"
1865 | },
1866 | "require-dev": {
1867 | "phpunit/phpunit": "~4.0"
1868 | },
1869 | "bin": [
1870 | "scripts/phpcs",
1871 | "scripts/phpcbf"
1872 | ],
1873 | "type": "library",
1874 | "extra": {
1875 | "branch-alias": {
1876 | "dev-master": "2.x-dev"
1877 | }
1878 | },
1879 | "autoload": {
1880 | "classmap": [
1881 | "CodeSniffer.php",
1882 | "CodeSniffer/CLI.php",
1883 | "CodeSniffer/Exception.php",
1884 | "CodeSniffer/File.php",
1885 | "CodeSniffer/Fixer.php",
1886 | "CodeSniffer/Report.php",
1887 | "CodeSniffer/Reporting.php",
1888 | "CodeSniffer/Sniff.php",
1889 | "CodeSniffer/Tokens.php",
1890 | "CodeSniffer/Reports/",
1891 | "CodeSniffer/Tokenizers/",
1892 | "CodeSniffer/DocGenerators/",
1893 | "CodeSniffer/Standards/AbstractPatternSniff.php",
1894 | "CodeSniffer/Standards/AbstractScopeSniff.php",
1895 | "CodeSniffer/Standards/AbstractVariableSniff.php",
1896 | "CodeSniffer/Standards/IncorrectPatternException.php",
1897 | "CodeSniffer/Standards/Generic/Sniffs/",
1898 | "CodeSniffer/Standards/MySource/Sniffs/",
1899 | "CodeSniffer/Standards/PEAR/Sniffs/",
1900 | "CodeSniffer/Standards/PSR1/Sniffs/",
1901 | "CodeSniffer/Standards/PSR2/Sniffs/",
1902 | "CodeSniffer/Standards/Squiz/Sniffs/",
1903 | "CodeSniffer/Standards/Zend/Sniffs/"
1904 | ]
1905 | },
1906 | "notification-url": "https://packagist.org/downloads/",
1907 | "license": [
1908 | "BSD-3-Clause"
1909 | ],
1910 | "authors": [
1911 | {
1912 | "name": "Greg Sherwood",
1913 | "role": "lead"
1914 | }
1915 | ],
1916 | "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
1917 | "homepage": "http://www.squizlabs.com/php-codesniffer",
1918 | "keywords": [
1919 | "phpcs",
1920 | "standards"
1921 | ],
1922 | "time": "2016-01-19T23:39:10+00:00"
1923 | },
1924 | {
1925 | "name": "symfony/console",
1926 | "version": "v3.4.17",
1927 | "source": {
1928 | "type": "git",
1929 | "url": "https://github.com/symfony/console.git",
1930 | "reference": "3b2b415d4c48fbefca7dc742aa0a0171bfae4e0b"
1931 | },
1932 | "dist": {
1933 | "type": "zip",
1934 | "url": "https://api.github.com/repos/symfony/console/zipball/3b2b415d4c48fbefca7dc742aa0a0171bfae4e0b",
1935 | "reference": "3b2b415d4c48fbefca7dc742aa0a0171bfae4e0b",
1936 | "shasum": ""
1937 | },
1938 | "require": {
1939 | "php": "^5.5.9|>=7.0.8",
1940 | "symfony/debug": "~2.8|~3.0|~4.0",
1941 | "symfony/polyfill-mbstring": "~1.0"
1942 | },
1943 | "conflict": {
1944 | "symfony/dependency-injection": "<3.4",
1945 | "symfony/process": "<3.3"
1946 | },
1947 | "require-dev": {
1948 | "psr/log": "~1.0",
1949 | "symfony/config": "~3.3|~4.0",
1950 | "symfony/dependency-injection": "~3.4|~4.0",
1951 | "symfony/event-dispatcher": "~2.8|~3.0|~4.0",
1952 | "symfony/lock": "~3.4|~4.0",
1953 | "symfony/process": "~3.3|~4.0"
1954 | },
1955 | "suggest": {
1956 | "psr/log-implementation": "For using the console logger",
1957 | "symfony/event-dispatcher": "",
1958 | "symfony/lock": "",
1959 | "symfony/process": ""
1960 | },
1961 | "type": "library",
1962 | "extra": {
1963 | "branch-alias": {
1964 | "dev-master": "3.4-dev"
1965 | }
1966 | },
1967 | "autoload": {
1968 | "psr-4": {
1969 | "Symfony\\Component\\Console\\": ""
1970 | },
1971 | "exclude-from-classmap": [
1972 | "/Tests/"
1973 | ]
1974 | },
1975 | "notification-url": "https://packagist.org/downloads/",
1976 | "license": [
1977 | "MIT"
1978 | ],
1979 | "authors": [
1980 | {
1981 | "name": "Fabien Potencier",
1982 | "email": "fabien@symfony.com"
1983 | },
1984 | {
1985 | "name": "Symfony Community",
1986 | "homepage": "https://symfony.com/contributors"
1987 | }
1988 | ],
1989 | "description": "Symfony Console Component",
1990 | "homepage": "https://symfony.com",
1991 | "time": "2018-10-02T16:33:53+00:00"
1992 | },
1993 | {
1994 | "name": "symfony/debug",
1995 | "version": "v4.1.6",
1996 | "source": {
1997 | "type": "git",
1998 | "url": "https://github.com/symfony/debug.git",
1999 | "reference": "e3f76ce6198f81994e019bb2b4e533e9de1b9b90"
2000 | },
2001 | "dist": {
2002 | "type": "zip",
2003 | "url": "https://api.github.com/repos/symfony/debug/zipball/e3f76ce6198f81994e019bb2b4e533e9de1b9b90",
2004 | "reference": "e3f76ce6198f81994e019bb2b4e533e9de1b9b90",
2005 | "shasum": ""
2006 | },
2007 | "require": {
2008 | "php": "^7.1.3",
2009 | "psr/log": "~1.0"
2010 | },
2011 | "conflict": {
2012 | "symfony/http-kernel": "<3.4"
2013 | },
2014 | "require-dev": {
2015 | "symfony/http-kernel": "~3.4|~4.0"
2016 | },
2017 | "type": "library",
2018 | "extra": {
2019 | "branch-alias": {
2020 | "dev-master": "4.1-dev"
2021 | }
2022 | },
2023 | "autoload": {
2024 | "psr-4": {
2025 | "Symfony\\Component\\Debug\\": ""
2026 | },
2027 | "exclude-from-classmap": [
2028 | "/Tests/"
2029 | ]
2030 | },
2031 | "notification-url": "https://packagist.org/downloads/",
2032 | "license": [
2033 | "MIT"
2034 | ],
2035 | "authors": [
2036 | {
2037 | "name": "Fabien Potencier",
2038 | "email": "fabien@symfony.com"
2039 | },
2040 | {
2041 | "name": "Symfony Community",
2042 | "homepage": "https://symfony.com/contributors"
2043 | }
2044 | ],
2045 | "description": "Symfony Debug Component",
2046 | "homepage": "https://symfony.com",
2047 | "time": "2018-10-02T16:36:10+00:00"
2048 | },
2049 | {
2050 | "name": "symfony/event-dispatcher",
2051 | "version": "v3.4.17",
2052 | "source": {
2053 | "type": "git",
2054 | "url": "https://github.com/symfony/event-dispatcher.git",
2055 | "reference": "b2e1f19280c09a42dc64c0b72b80fe44dd6e88fb"
2056 | },
2057 | "dist": {
2058 | "type": "zip",
2059 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b2e1f19280c09a42dc64c0b72b80fe44dd6e88fb",
2060 | "reference": "b2e1f19280c09a42dc64c0b72b80fe44dd6e88fb",
2061 | "shasum": ""
2062 | },
2063 | "require": {
2064 | "php": "^5.5.9|>=7.0.8"
2065 | },
2066 | "conflict": {
2067 | "symfony/dependency-injection": "<3.3"
2068 | },
2069 | "require-dev": {
2070 | "psr/log": "~1.0",
2071 | "symfony/config": "~2.8|~3.0|~4.0",
2072 | "symfony/dependency-injection": "~3.3|~4.0",
2073 | "symfony/expression-language": "~2.8|~3.0|~4.0",
2074 | "symfony/stopwatch": "~2.8|~3.0|~4.0"
2075 | },
2076 | "suggest": {
2077 | "symfony/dependency-injection": "",
2078 | "symfony/http-kernel": ""
2079 | },
2080 | "type": "library",
2081 | "extra": {
2082 | "branch-alias": {
2083 | "dev-master": "3.4-dev"
2084 | }
2085 | },
2086 | "autoload": {
2087 | "psr-4": {
2088 | "Symfony\\Component\\EventDispatcher\\": ""
2089 | },
2090 | "exclude-from-classmap": [
2091 | "/Tests/"
2092 | ]
2093 | },
2094 | "notification-url": "https://packagist.org/downloads/",
2095 | "license": [
2096 | "MIT"
2097 | ],
2098 | "authors": [
2099 | {
2100 | "name": "Fabien Potencier",
2101 | "email": "fabien@symfony.com"
2102 | },
2103 | {
2104 | "name": "Symfony Community",
2105 | "homepage": "https://symfony.com/contributors"
2106 | }
2107 | ],
2108 | "description": "Symfony EventDispatcher Component",
2109 | "homepage": "https://symfony.com",
2110 | "time": "2018-07-26T09:06:28+00:00"
2111 | },
2112 | {
2113 | "name": "symfony/finder",
2114 | "version": "v3.4.17",
2115 | "source": {
2116 | "type": "git",
2117 | "url": "https://github.com/symfony/finder.git",
2118 | "reference": "54ba444dddc5bd5708a34bd095ea67c6eb54644d"
2119 | },
2120 | "dist": {
2121 | "type": "zip",
2122 | "url": "https://api.github.com/repos/symfony/finder/zipball/54ba444dddc5bd5708a34bd095ea67c6eb54644d",
2123 | "reference": "54ba444dddc5bd5708a34bd095ea67c6eb54644d",
2124 | "shasum": ""
2125 | },
2126 | "require": {
2127 | "php": "^5.5.9|>=7.0.8"
2128 | },
2129 | "type": "library",
2130 | "extra": {
2131 | "branch-alias": {
2132 | "dev-master": "3.4-dev"
2133 | }
2134 | },
2135 | "autoload": {
2136 | "psr-4": {
2137 | "Symfony\\Component\\Finder\\": ""
2138 | },
2139 | "exclude-from-classmap": [
2140 | "/Tests/"
2141 | ]
2142 | },
2143 | "notification-url": "https://packagist.org/downloads/",
2144 | "license": [
2145 | "MIT"
2146 | ],
2147 | "authors": [
2148 | {
2149 | "name": "Fabien Potencier",
2150 | "email": "fabien@symfony.com"
2151 | },
2152 | {
2153 | "name": "Symfony Community",
2154 | "homepage": "https://symfony.com/contributors"
2155 | }
2156 | ],
2157 | "description": "Symfony Finder Component",
2158 | "homepage": "https://symfony.com",
2159 | "time": "2018-10-03T08:46:40+00:00"
2160 | },
2161 | {
2162 | "name": "symfony/polyfill-ctype",
2163 | "version": "v1.9.0",
2164 | "source": {
2165 | "type": "git",
2166 | "url": "https://github.com/symfony/polyfill-ctype.git",
2167 | "reference": "e3d826245268269cd66f8326bd8bc066687b4a19"
2168 | },
2169 | "dist": {
2170 | "type": "zip",
2171 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19",
2172 | "reference": "e3d826245268269cd66f8326bd8bc066687b4a19",
2173 | "shasum": ""
2174 | },
2175 | "require": {
2176 | "php": ">=5.3.3"
2177 | },
2178 | "suggest": {
2179 | "ext-ctype": "For best performance"
2180 | },
2181 | "type": "library",
2182 | "extra": {
2183 | "branch-alias": {
2184 | "dev-master": "1.9-dev"
2185 | }
2186 | },
2187 | "autoload": {
2188 | "psr-4": {
2189 | "Symfony\\Polyfill\\Ctype\\": ""
2190 | },
2191 | "files": [
2192 | "bootstrap.php"
2193 | ]
2194 | },
2195 | "notification-url": "https://packagist.org/downloads/",
2196 | "license": [
2197 | "MIT"
2198 | ],
2199 | "authors": [
2200 | {
2201 | "name": "Symfony Community",
2202 | "homepage": "https://symfony.com/contributors"
2203 | },
2204 | {
2205 | "name": "Gert de Pagter",
2206 | "email": "BackEndTea@gmail.com"
2207 | }
2208 | ],
2209 | "description": "Symfony polyfill for ctype functions",
2210 | "homepage": "https://symfony.com",
2211 | "keywords": [
2212 | "compatibility",
2213 | "ctype",
2214 | "polyfill",
2215 | "portable"
2216 | ],
2217 | "time": "2018-08-06T14:22:27+00:00"
2218 | },
2219 | {
2220 | "name": "symfony/process",
2221 | "version": "v3.4.17",
2222 | "source": {
2223 | "type": "git",
2224 | "url": "https://github.com/symfony/process.git",
2225 | "reference": "1dc2977afa7d70f90f3fefbcd84152813558910e"
2226 | },
2227 | "dist": {
2228 | "type": "zip",
2229 | "url": "https://api.github.com/repos/symfony/process/zipball/1dc2977afa7d70f90f3fefbcd84152813558910e",
2230 | "reference": "1dc2977afa7d70f90f3fefbcd84152813558910e",
2231 | "shasum": ""
2232 | },
2233 | "require": {
2234 | "php": "^5.5.9|>=7.0.8"
2235 | },
2236 | "type": "library",
2237 | "extra": {
2238 | "branch-alias": {
2239 | "dev-master": "3.4-dev"
2240 | }
2241 | },
2242 | "autoload": {
2243 | "psr-4": {
2244 | "Symfony\\Component\\Process\\": ""
2245 | },
2246 | "exclude-from-classmap": [
2247 | "/Tests/"
2248 | ]
2249 | },
2250 | "notification-url": "https://packagist.org/downloads/",
2251 | "license": [
2252 | "MIT"
2253 | ],
2254 | "authors": [
2255 | {
2256 | "name": "Fabien Potencier",
2257 | "email": "fabien@symfony.com"
2258 | },
2259 | {
2260 | "name": "Symfony Community",
2261 | "homepage": "https://symfony.com/contributors"
2262 | }
2263 | ],
2264 | "description": "Symfony Process Component",
2265 | "homepage": "https://symfony.com",
2266 | "time": "2018-10-02T12:28:39+00:00"
2267 | },
2268 | {
2269 | "name": "symfony/yaml",
2270 | "version": "v3.4.17",
2271 | "source": {
2272 | "type": "git",
2273 | "url": "https://github.com/symfony/yaml.git",
2274 | "reference": "640b6c27fed4066d64b64d5903a86043f4a4de7f"
2275 | },
2276 | "dist": {
2277 | "type": "zip",
2278 | "url": "https://api.github.com/repos/symfony/yaml/zipball/640b6c27fed4066d64b64d5903a86043f4a4de7f",
2279 | "reference": "640b6c27fed4066d64b64d5903a86043f4a4de7f",
2280 | "shasum": ""
2281 | },
2282 | "require": {
2283 | "php": "^5.5.9|>=7.0.8",
2284 | "symfony/polyfill-ctype": "~1.8"
2285 | },
2286 | "conflict": {
2287 | "symfony/console": "<3.4"
2288 | },
2289 | "require-dev": {
2290 | "symfony/console": "~3.4|~4.0"
2291 | },
2292 | "suggest": {
2293 | "symfony/console": "For validating YAML files using the lint command"
2294 | },
2295 | "type": "library",
2296 | "extra": {
2297 | "branch-alias": {
2298 | "dev-master": "3.4-dev"
2299 | }
2300 | },
2301 | "autoload": {
2302 | "psr-4": {
2303 | "Symfony\\Component\\Yaml\\": ""
2304 | },
2305 | "exclude-from-classmap": [
2306 | "/Tests/"
2307 | ]
2308 | },
2309 | "notification-url": "https://packagist.org/downloads/",
2310 | "license": [
2311 | "MIT"
2312 | ],
2313 | "authors": [
2314 | {
2315 | "name": "Fabien Potencier",
2316 | "email": "fabien@symfony.com"
2317 | },
2318 | {
2319 | "name": "Symfony Community",
2320 | "homepage": "https://symfony.com/contributors"
2321 | }
2322 | ],
2323 | "description": "Symfony Yaml Component",
2324 | "homepage": "https://symfony.com",
2325 | "time": "2018-10-02T16:33:53+00:00"
2326 | },
2327 | {
2328 | "name": "webmozart/assert",
2329 | "version": "1.3.0",
2330 | "source": {
2331 | "type": "git",
2332 | "url": "https://github.com/webmozart/assert.git",
2333 | "reference": "0df1908962e7a3071564e857d86874dad1ef204a"
2334 | },
2335 | "dist": {
2336 | "type": "zip",
2337 | "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a",
2338 | "reference": "0df1908962e7a3071564e857d86874dad1ef204a",
2339 | "shasum": ""
2340 | },
2341 | "require": {
2342 | "php": "^5.3.3 || ^7.0"
2343 | },
2344 | "require-dev": {
2345 | "phpunit/phpunit": "^4.6",
2346 | "sebastian/version": "^1.0.1"
2347 | },
2348 | "type": "library",
2349 | "extra": {
2350 | "branch-alias": {
2351 | "dev-master": "1.3-dev"
2352 | }
2353 | },
2354 | "autoload": {
2355 | "psr-4": {
2356 | "Webmozart\\Assert\\": "src/"
2357 | }
2358 | },
2359 | "notification-url": "https://packagist.org/downloads/",
2360 | "license": [
2361 | "MIT"
2362 | ],
2363 | "authors": [
2364 | {
2365 | "name": "Bernhard Schussek",
2366 | "email": "bschussek@gmail.com"
2367 | }
2368 | ],
2369 | "description": "Assertions to validate method input/output with nice error messages.",
2370 | "keywords": [
2371 | "assert",
2372 | "check",
2373 | "validate"
2374 | ],
2375 | "time": "2018-01-29T19:49:41+00:00"
2376 | }
2377 | ],
2378 | "aliases": [],
2379 | "minimum-stability": "stable",
2380 | "stability-flags": [],
2381 | "prefer-stable": false,
2382 | "prefer-lowest": false,
2383 | "platform": {
2384 | "php": ">=5.3.0"
2385 | },
2386 | "platform-dev": []
2387 | }
2388 |
--------------------------------------------------------------------------------
/examples/.bog.example:
--------------------------------------------------------------------------------
1 | merchant_id='' # Merchant ID in format XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2 | account_id='' # Account ID in format XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3 | page_id='' # Page ID in format XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4 | http_auth_user='' # Username for HTTP Authorization
5 | http_auth_pass='' # Password for HTTP Authorization
6 | shop_name='' # Shop Name
7 | payment_url='https://sb3d.georgiancard.ge/payment/start.wsm' # Payment init url
8 | lang='ka' # ka, en
9 | currency='981' # 981 - GEL, 840 - USD, 978 - EUR
10 | cert_path='/path/to/certificate' # Path to certificate for checking signature
11 | log_path='/path/to/logs' # Path to logs folder
12 | allowed_ips='127.0.0.1,192.168.1.*' # Comma separated of allowed IP list. (possible specify ip ranges too)
13 |
--------------------------------------------------------------------------------
/examples/.cartu.example:
--------------------------------------------------------------------------------
1 | CountryCode='268' # 268 - Georgia
2 | CurrencyCode='981' # 981 - GEL, 840 - USD, 978 - EUR
3 | MerchantName='' # Merchant name and url in format: shop_name!www.shopurl.ge
4 | MerchantURL='' # URL for redirect after payment
5 | MerchantCity='Tbilisi' # Merchant city
6 | MerchantID='' # Merchant ID in format 0000000XXXXXXXX-00000001
7 | xDDDSProxy.Language='01' # 01 - GEO, 02 - ENG, 03 - RUS, 04 - DEU, 05 - TUR
8 | payment_url='https://e-commerce.cartubank.ge/servlet/Process3DSServlet/3dsproxy_init.jsp' # Payment init url
9 | cert_path='/path/to/certificate' # Path to certificate for checking signature
10 | log_path='/path/to/logs' # Path to logs folder
11 | allowed_ips='127.0.0.1,192.168.1.*' # Comma separated of allowed IP list. (possible specify ip ranges too)
12 |
--------------------------------------------------------------------------------
/examples/.tbcpay.example:
--------------------------------------------------------------------------------
1 | http_auth_user='' # Username for HTTP Authorization
2 | http_auth_pass='' # Password for HTTP Authorization
3 | log_path='/path/to/logs' # Path to logs folder
4 | allowed_ips='127.0.0.1,192.168.1.*' # Comma separated of allowed IP list. (possible specify ip ranges too)
5 |
--------------------------------------------------------------------------------
/phpcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP Code Sniffer
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | warning
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | warning
41 |
42 |
43 | warning
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | Please review this TODO comment: %s
63 | warning
64 |
65 |
66 | Please review this FIXME comment: %s
67 | warning
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
102 |
103 |
104 |
105 |
106 | warning
107 |
108 |
109 |
110 |
113 |
114 |
115 |
116 |
117 |
118 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
25 |
26 |
27 |
28 | ./tests/
29 |
30 |
31 |
32 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/Contracts/Logger.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 |
11 | namespace Longman\GeoPayment\Contracts;
12 |
13 | interface Logger
14 | {
15 | /**
16 | * Log an alert message to the logs.
17 | *
18 | * @param string $message
19 | * @param array $context
20 | * @return void
21 | */
22 | public function alert($message, array $context = []);
23 |
24 | /**
25 | * Log a critical message to the logs.
26 | *
27 | * @param string $message
28 | * @param array $context
29 | * @return void
30 | */
31 | public function critical($message, array $context = []);
32 |
33 | /**
34 | * Log an error message to the logs.
35 | *
36 | * @param string $message
37 | * @param array $context
38 | * @return void
39 | */
40 | public function error($message, array $context = []);
41 |
42 | /**
43 | * Log a warning message to the logs.
44 | *
45 | * @param string $message
46 | * @param array $context
47 | * @return void
48 | */
49 | public function warning($message, array $context = []);
50 |
51 | /**
52 | * Log a notice to the logs.
53 | *
54 | * @param string $message
55 | * @param array $context
56 | * @return void
57 | */
58 | public function notice($message, array $context = []);
59 |
60 | /**
61 | * Log an informational message to the logs.
62 | *
63 | * @param string $message
64 | * @param array $context
65 | * @return void
66 | */
67 | public function info($message, array $context = []);
68 |
69 | /**
70 | * Log a debug message to the logs.
71 | *
72 | * @param string $message
73 | * @param array $context
74 | * @return void
75 | */
76 | public function debug($message, array $context = []);
77 |
78 | /**
79 | * Log a message to the logs.
80 | *
81 | * @param string $level
82 | * @param string $message
83 | * @param array $context
84 | * @return void
85 | */
86 | public function log($level, $message, array $context = []);
87 |
88 | /**
89 | * Register a file log handler.
90 | *
91 | * @param string $path
92 | * @param string $level
93 | * @return void
94 | */
95 | public function useFiles($path, $level = 'debug');
96 |
97 | /**
98 | * Register a daily file log handler.
99 | *
100 | * @param string $path
101 | * @param int $days
102 | * @param string $level
103 | * @return void
104 | */
105 | public function useDailyFiles($path, $days = 0, $level = 'debug');
106 | }
107 |
--------------------------------------------------------------------------------
/src/Contracts/Options.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 |
11 | namespace Longman\GeoPayment\Contracts;
12 |
13 | interface Options
14 | {
15 |
16 | /**
17 | * Constructor
18 | *
19 | * @param array $data Options
20 | *
21 | * @return void
22 | */
23 | public function __construct($data = []);
24 |
25 | /**
26 | * Get option
27 | *
28 | * @param string $name Option name
29 | * @param mixed $default Default value
30 | *
31 | * @return mixed
32 | */
33 | public function get($name, $default = null);
34 |
35 | /**
36 | * Set option
37 | *
38 | * @param string $name Option name
39 | * @param array $value Option value
40 | *
41 | * @return void
42 | */
43 | public function set($name, $value);
44 | }
45 |
--------------------------------------------------------------------------------
/src/Logger.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 |
11 | namespace Longman\GeoPayment;
12 |
13 | use InvalidArgumentException;
14 | use Longman\GeoPayment\Contracts\Logger as LoggerContract;
15 | use Monolog\Handler\SyslogHandler;
16 | use Monolog\Handler\StreamHandler;
17 | use Monolog\Logger as MonologLogger;
18 | use Monolog\Formatter\LineFormatter;
19 | use Monolog\Handler\ErrorLogHandler;
20 | use Monolog\Handler\RotatingFileHandler;
21 | use Psr\Log\LoggerInterface as PsrLoggerInterface;
22 |
23 | /**
24 | * Logger class.
25 | *
26 | */
27 | class Logger implements LoggerContract, PsrLoggerInterface
28 | {
29 | /**
30 | * The Monolog logger instance.
31 | *
32 | * @var \Monolog\Logger
33 | */
34 | protected $monolog;
35 |
36 | /**
37 | * The Log levels.
38 | *
39 | * @var array
40 | */
41 | protected $levels = [
42 | 'debug' => MonologLogger::DEBUG,
43 | 'info' => MonologLogger::INFO,
44 | 'notice' => MonologLogger::NOTICE,
45 | 'warning' => MonologLogger::WARNING,
46 | 'error' => MonologLogger::ERROR,
47 | 'critical' => MonologLogger::CRITICAL,
48 | 'alert' => MonologLogger::ALERT,
49 | 'emergency' => MonologLogger::EMERGENCY,
50 | ];
51 |
52 | /**
53 | * Create a new log writer instance.
54 | *
55 | * @param \Monolog\Logger $monolog
56 | * @return void
57 | */
58 | public function __construct(MonologLogger $monolog)
59 | {
60 | $this->monolog = $monolog;
61 | }
62 |
63 | /**
64 | * Log an emergency message to the logs.
65 | *
66 | * @param string $message
67 | * @param array $context
68 | * @return void
69 | */
70 | public function emergency($message, array $context = [])
71 | {
72 | return $this->writeLog(__FUNCTION__, $message, $context);
73 | }
74 |
75 | /**
76 | * Log an alert message to the logs.
77 | *
78 | * @param string $message
79 | * @param array $context
80 | * @return void
81 | */
82 | public function alert($message, array $context = [])
83 | {
84 | return $this->writeLog(__FUNCTION__, $message, $context);
85 | }
86 |
87 | /**
88 | * Log a critical message to the logs.
89 | *
90 | * @param string $message
91 | * @param array $context
92 | * @return void
93 | */
94 | public function critical($message, array $context = [])
95 | {
96 | return $this->writeLog(__FUNCTION__, $message, $context);
97 | }
98 |
99 | /**
100 | * Log an error message to the logs.
101 | *
102 | * @param string $message
103 | * @param array $context
104 | * @return void
105 | */
106 | public function error($message, array $context = [])
107 | {
108 | return $this->writeLog(__FUNCTION__, $message, $context);
109 | }
110 |
111 | /**
112 | * Log a warning message to the logs.
113 | *
114 | * @param string $message
115 | * @param array $context
116 | * @return void
117 | */
118 | public function warning($message, array $context = [])
119 | {
120 | return $this->writeLog(__FUNCTION__, $message, $context);
121 | }
122 |
123 | /**
124 | * Log a notice to the logs.
125 | *
126 | * @param string $message
127 | * @param array $context
128 | * @return void
129 | */
130 | public function notice($message, array $context = [])
131 | {
132 | return $this->writeLog(__FUNCTION__, $message, $context);
133 | }
134 |
135 | /**
136 | * Log an informational message to the logs.
137 | *
138 | * @param string $message
139 | * @param array $context
140 | * @return void
141 | */
142 | public function info($message, array $context = [])
143 | {
144 | return $this->writeLog(__FUNCTION__, $message, $context);
145 | }
146 |
147 | /**
148 | * Log a debug message to the logs.
149 | *
150 | * @param string $message
151 | * @param array $context
152 | * @return void
153 | */
154 | public function debug($message, array $context = [])
155 | {
156 | return $this->writeLog(__FUNCTION__, $message, $context);
157 | }
158 |
159 | /**
160 | * Log a message to the logs.
161 | *
162 | * @param string $level
163 | * @param string $message
164 | * @param array $context
165 | * @return void
166 | */
167 | public function log($level, $message, array $context = [])
168 | {
169 | return $this->writeLog($level, $message, $context);
170 | }
171 |
172 | /**
173 | * Dynamically pass log calls into the writer.
174 | *
175 | * @param string $level
176 | * @param string $message
177 | * @param array $context
178 | * @return void
179 | */
180 | public function write($level, $message, array $context = [])
181 | {
182 | return $this->writeLog($level, $message, $context);
183 | }
184 |
185 | /**
186 | * Write a message to Monolog.
187 | *
188 | * @param string $level
189 | * @param string $message
190 | * @param array $context
191 | * @return void
192 | */
193 | protected function writeLog($level, $message, $context)
194 | {
195 | $this->monolog->{$level}($message, $context);
196 | }
197 |
198 | /**
199 | * Register a file log handler.
200 | *
201 | * @param string $path
202 | * @param string $level
203 | * @return void
204 | */
205 | public function useFiles($path, $level = 'debug')
206 | {
207 | $this->monolog->pushHandler($handler = new StreamHandler($path, $this->parseLevel($level)));
208 |
209 | $handler->setFormatter($this->getDefaultFormatter());
210 | }
211 |
212 | /**
213 | * Register a daily file log handler.
214 | *
215 | * @param string $path
216 | * @param int $days
217 | * @param string $level
218 | * @return void
219 | */
220 | public function useDailyFiles($path, $days = 0, $level = 'debug')
221 | {
222 | $this->monolog->pushHandler(
223 | $handler = new RotatingFileHandler($path, $days, $this->parseLevel($level))
224 | );
225 |
226 | $handler->setFormatter($this->getDefaultFormatter());
227 | }
228 |
229 | /**
230 | * Register a Syslog handler.
231 | *
232 | * @param string $name
233 | * @param string $level
234 | * @return \Psr\Log\LoggerInterface
235 | */
236 | public function useSyslog($name = 'laravel', $level = 'debug')
237 | {
238 | return $this->monolog->pushHandler(new SyslogHandler($name, LOG_USER, $level));
239 | }
240 |
241 | /**
242 | * Register an error_log handler.
243 | *
244 | * @param string $level
245 | * @param int $messageType
246 | * @return void
247 | */
248 | public function useErrorLog($level = 'debug', $messageType = ErrorLogHandler::OPERATING_SYSTEM)
249 | {
250 | $this->monolog->pushHandler(
251 | $handler = new ErrorLogHandler($messageType, $this->parseLevel($level))
252 | );
253 |
254 | $handler->setFormatter($this->getDefaultFormatter());
255 | }
256 |
257 | /**
258 | * Parse the string level into a Monolog constant.
259 | *
260 | * @param string $level
261 | * @return int
262 | *
263 | * @throws \InvalidArgumentException
264 | */
265 | protected function parseLevel($level)
266 | {
267 | if (isset($this->levels[$level])) {
268 | return $this->levels[$level];
269 | }
270 |
271 | throw new InvalidArgumentException('Invalid log level.');
272 | }
273 |
274 | /**
275 | * Get the underlying Monolog instance.
276 | *
277 | * @return \Monolog\Logger
278 | */
279 | public function getMonolog()
280 | {
281 | return $this->monolog;
282 | }
283 |
284 | /**
285 | * Get a defaut Monolog formatter instance.
286 | *
287 | * @return \Monolog\Formatter\LineFormatter
288 | */
289 | protected function getDefaultFormatter()
290 | {
291 | return new LineFormatter("[%datetime%] [%ip%] %channel%.%level_name%: %message% %context% %extra%\n", null, false, true);
292 | }
293 | }
294 |
--------------------------------------------------------------------------------
/src/Options.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 |
11 | namespace Longman\GeoPayment;
12 |
13 | use Longman\GeoPayment\Contracts\Options as OptionsContract;
14 |
15 | /**
16 | * Class for holding options data
17 | *
18 | */
19 | class Options implements OptionsContract
20 | {
21 |
22 | /**
23 | * @var array
24 | */
25 | protected $data;
26 |
27 | /**
28 | * Constructor
29 | *
30 | * @param array $data Options
31 | *
32 | * @return void
33 | */
34 | public function __construct($data = [])
35 | {
36 | $this->data = $data;
37 | }
38 |
39 | /**
40 | * Get option
41 | *
42 | * @param string $name Option name
43 | * @param mixed $default Default value
44 | *
45 | * @return mixed
46 | */
47 | public function get($name, $default = null)
48 | {
49 | if (isset($this->data[$name])) {
50 | return $this->data[$name];
51 | }
52 |
53 | if (isset($_ENV[$name])) {
54 | return $_ENV[$name];
55 | }
56 |
57 | return $default;
58 | }
59 |
60 | /**
61 | * Set option
62 | *
63 | * @param string $name Option name
64 | * @param array $value Option value
65 | *
66 | * @return void
67 | */
68 | public function set($name, $value)
69 | {
70 | $this->data[$name] = $value;
71 | return $this;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/Payment.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 |
11 | namespace Longman\GeoPayment;
12 |
13 | use Dotenv\Dotenv;
14 | use InvalidArgumentException;
15 | use Longman\GeoPayment\Contracts\Options as OptionsContract;
16 | use Longman\GeoPayment\Contracts\Logger as LoggerContract;
17 | use Longman\GeoPayment\Provider\AbstractProvider;
18 | use RuntimeException;
19 | use Symfony\Component\HttpFoundation\Request;
20 | use Monolog\Logger as MonologLogger;
21 |
22 | /**
23 | * Universal payment class.
24 | *
25 | */
26 | class Payment
27 | {
28 |
29 | /**
30 | * @var \Longman\GeoPayment\Provider\Pay\AbstractProvider
31 | */
32 | protected $provider;
33 |
34 | /**
35 | * Payment type
36 | *
37 | * @var string
38 | */
39 | protected $type = 'card';
40 |
41 | /**
42 | * @var \Longman\GeoPayment\Logger
43 | */
44 | protected $logger;
45 |
46 | /**
47 | * @var \Longman\GeoPayment\Options
48 | */
49 | protected $options;
50 |
51 | /**
52 | * @var \Symfony\Component\HttpFoundation\Request
53 | */
54 | protected $request;
55 |
56 | /**
57 | * @var bool
58 | */
59 | protected $debug;
60 |
61 | /**
62 | * @var string
63 | */
64 | const TYPE_CARD = 'Card';
65 |
66 | /**
67 | * @var string
68 | */
69 | const TYPE_PAY = 'Pay';
70 |
71 |
72 | /**
73 | * Constructor
74 | *
75 | * @param string $provider Provider name
76 | * @param array $options Options
77 | *
78 | * @return void
79 | */
80 | public function __construct($provider = null, $type = self::TYPE_CARD, array $options = [])
81 | {
82 | $this->type = $type;
83 |
84 | $this->createOptionsInstance($options);
85 |
86 | $this->createRequestInstance();
87 |
88 | if ($config_path = $this->options->get('config_path')) {
89 | $this->setConfigFile($config_path);
90 | }
91 |
92 | if ($log_path = $this->options->get('log_path')) {
93 | $this->createLoggerInstance($log_path, $provider);
94 | }
95 |
96 | if ($provider) {
97 | $this->createProviderInstance($provider);
98 | }
99 |
100 | }
101 |
102 | /**
103 | * Create Request instance
104 | *
105 | * @return \Longman\GeoPayment\Payment
106 | */
107 | protected function createRequestInstance()
108 | {
109 | $this->setRequestInstance(Request::createFromGlobals());
110 | return $this;
111 | }
112 |
113 | /**
114 | * Set Request instance
115 | *
116 | * @param \Symfony\Component\HttpFoundation\Request $request Request instance
117 | *
118 | * @return \Longman\GeoPayment\Payment
119 | */
120 | public function setRequestInstance(Request $request)
121 | {
122 | $this->request = $request;
123 | return $this;
124 | }
125 |
126 |
127 | /**
128 | * Create Options instance
129 | *
130 | * @param array $options Options array
131 | *
132 | * @return \Longman\GeoPayment\Payment
133 | */
134 | protected function createOptionsInstance(array $options)
135 | {
136 | $this->setOptionsInstance(new Options($options));
137 | return $this;
138 | }
139 |
140 | /**
141 | * Set Options instance
142 | *
143 | * @param \Longman\GeoPayment\Contracts\Options $options Options instance
144 | *
145 | * @return \Longman\GeoPayment\Payment
146 | */
147 | public function setOptionsInstance(OptionsContract $options)
148 | {
149 | $this->options = $options;
150 | return $this;
151 | }
152 |
153 | /**
154 | * Configure logger object
155 | *
156 | * @param string $path Path to log folder
157 | * @param string $provider Provider name
158 | *
159 | * @return \Longman\GeoPayment\Payment
160 | */
161 | protected function createLoggerInstance($path, $provider = null)
162 | {
163 | if (!$provider) {
164 | $provider = 'default';
165 | }
166 |
167 | $log_path = $path . '/' . $provider . '.log';
168 | $log_level = $this->options->get('log_level', 'debug');
169 |
170 | $logger = new Logger(new MonologLogger($log_level));
171 |
172 | $logger->getMonolog()->pushProcessor(function ($record) {
173 | $record['ip'] = $this->request->server->get('REMOTE_ADDR');
174 | $record['extra']['GET'] = $this->request->query->all();
175 | $record['extra']['POST'] = $this->request->request->all();
176 | return $record;
177 | });
178 |
179 | $logger->useDailyFiles($log_path, 0);
180 |
181 | $this->setLoggerInstance($logger);
182 |
183 | return $this;
184 | }
185 |
186 | /**
187 | * Set Logger instance
188 | *
189 | * @param \Longman\GeoPayment\Contracts\Logger $logger Logger instance
190 | *
191 | * @return \Longman\GeoPayment\Payment
192 | */
193 | public function setLoggerInstance(LoggerContract $logger)
194 | {
195 | $this->logger = $logger;
196 | return $this;
197 | }
198 |
199 |
200 | /**
201 | * Parse config dotfile
202 | *
203 | * @param string $path Config file path
204 | *
205 | * @return \Longman\GeoPayment\Payment
206 | */
207 | public function setConfigFile($path)
208 | {
209 | if (!is_file($path)) {
210 | throw new InvalidArgumentException('Config path "' . $path . '" is not a file');
211 | }
212 |
213 | $folder = dirname($path);
214 | $file = pathinfo($path, PATHINFO_BASENAME);
215 | $dotenv = new Dotenv($folder, $file);
216 | $dotenv->load();
217 | return $this;
218 | }
219 |
220 | /**
221 | * Create provider instance
222 | *
223 | * @param string $provider Provider name
224 | *
225 | * @return \Longman\GeoPayment\Payment
226 | *
227 | * @throws \InvalidArgumentException When the provider not found
228 | */
229 | protected function createProviderInstance($provider)
230 | {
231 | $class = '\Longman\GeoPayment\Provider\\'.ucfirst($this->type).'\\' . ucfirst($provider) . '\Provider';
232 | if (!class_exists($class)) {
233 | throw new InvalidArgumentException('Provider "' . $provider . '" not found!');
234 | }
235 |
236 | $this->setProviderInstance(new $class($this->options, $this->request, $this->logger));
237 |
238 | return $this;
239 | }
240 |
241 | /**
242 | * Set provider instance
243 | *
244 | * @param \Longman\GeoPayment\Provider\Pay\AbstractProvider $provider Provider instance
245 | *
246 | * @return \Longman\GeoPayment\Payment
247 | */
248 | public function setProviderInstance(AbstractProvider $provider)
249 | {
250 | $this->provider = $provider;
251 | return $this;
252 | }
253 |
254 |
255 | /**
256 | * Get Option value
257 | *
258 | * @param string $name Option name
259 | * @param mixed $default Default value
260 | *
261 | * @return mixed
262 | */
263 | public function getOption($name = null, $default = null)
264 | {
265 | return $this->options->get($name, $default);
266 | }
267 |
268 |
269 | /**
270 | * Get Options object
271 | *
272 | * @return mixed|\Longman\GeoPayment\Options
273 | */
274 | public function getOptions()
275 | {
276 | return $this->options;
277 | }
278 |
279 | /**
280 | * Get request instance
281 | *
282 | * @return \Symfony\Component\HttpFoundation\Request
283 | */
284 | public function getRequest()
285 | {
286 | return $this->request;
287 | }
288 |
289 | /**
290 | * Get provider instance
291 | *
292 | * @return \Longman\GeoPayment\Provider\Pay\AbstractProvider
293 | */
294 | public function getProvider()
295 | {
296 | return $this->provider;
297 | }
298 |
299 | /**
300 | * Pass function calls to provider instance
301 | *
302 | * @return mixed
303 | *
304 | * @throws \RuntimeException When the provider can not call method
305 | */
306 | public function __call($method, $args)
307 | {
308 | if (!$this->provider instanceof AbstractProvider) {
309 | throw new RuntimeException('Provider not initialized');
310 | }
311 |
312 | if (!is_callable([$this->provider, $method])) {
313 | throw new RuntimeException('Provider "' . $this->provider->getName() . '" does not have callable method "' . $method . '"');
314 | }
315 |
316 | return call_user_func_array([$this->provider, $method], $args);
317 | }
318 | }
319 |
--------------------------------------------------------------------------------
/src/Provider/AbstractProvider.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 |
11 | namespace Longman\GeoPayment\Provider;
12 |
13 | use Longman\GeoPayment\Logger;
14 | use Longman\GeoPayment\Options;
15 | use Symfony\Component\HttpFoundation\RedirectResponse;
16 | use Symfony\Component\HttpFoundation\Request;
17 | use Symfony\Component\HttpFoundation\Response;
18 | use UnexpectedValueException;
19 |
20 | /**
21 | * Abstract Provider class
22 | *
23 | */
24 | abstract class AbstractProvider
25 | {
26 |
27 | /**
28 | * Provider name
29 | *
30 | * @var string
31 | */
32 | protected $name;
33 |
34 | /**
35 | * Mode (depends on bank)
36 | *
37 | * @var string
38 | */
39 | protected $mode;
40 |
41 | /**
42 | * @var \Longman\GeoPayment\Logger
43 | */
44 | protected $logger;
45 |
46 | /**
47 | * @var \Longman\GeoPayment\Options
48 | */
49 | protected $options;
50 |
51 | /**
52 | * @var \Symfony\Component\HttpFoundation\Request
53 | */
54 | protected $request;
55 |
56 | /**
57 | * Custom parameters
58 | *
59 | * @var array
60 | */
61 | protected $params = [];
62 |
63 | /**
64 | * Constructor
65 | *
66 | * @param \Longman\GeoPayment\Options $options Options object
67 | * @param \Symfony\Component\HttpFoundation\Request $request Request object
68 | * @param \Longman\GeoPayment\Logger $logger Logger object
69 | *
70 | * @return void
71 | */
72 | public function __construct(Options $options, Request $request, Logger $logger)
73 | {
74 | $this->options = $options;
75 | $this->request = $request;
76 | $this->logger = $logger;
77 | }
78 |
79 | /**
80 | * Get provider name
81 | *
82 | * @return string
83 | */
84 | public function getName()
85 | {
86 | return $this->name;
87 | }
88 |
89 | /**
90 | * Add custom parameter to url
91 | *
92 | * @param string $name Parameter name
93 | * @param mixed $value Parameter value
94 | *
95 | * @return \Longman\GeoPayment\Provider\Pay\AbstractProvider
96 | */
97 | public function addParam($name, $value)
98 | {
99 | $this->params[$name] = $value;
100 | return $this;
101 | }
102 |
103 | /**
104 | * Get parameter from params, otherwise get request field
105 | *
106 | * @param string $name Parameter name
107 | * @param mixed $default Parameter default value
108 | *
109 | * @return mixed
110 | */
111 | public function getParam($name, $default = null)
112 | {
113 | if (isset($this->params[$name])) {
114 | return $this->params[$name];
115 | }
116 | $name = str_replace('.', '_', $name);
117 | return $this->request->get($name, $default);
118 | }
119 |
120 | /**
121 | * Redirect to url
122 | *
123 | * @param string $url Url to redirect
124 | *
125 | * @return void
126 | */
127 | public function redirect($url = null)
128 | {
129 | if (is_null($url)) {
130 | $url = $this->getPaymentUrl();
131 | }
132 |
133 | RedirectResponse::create($url)->send();
134 |
135 | exit();
136 | }
137 |
138 | /**
139 | * Set mode
140 | *
141 | * @param string $mode
142 | *
143 | * @return \Longman\GeoPayment\Provider\Pay\AbstractProvider
144 | */
145 | public function setMode($mode)
146 | {
147 | $this->mode = $mode;
148 | return $this;
149 | }
150 |
151 | /**
152 | * Get mode
153 | *
154 | * @return string
155 | */
156 | public function getMode()
157 | {
158 | return $this->mode;
159 | }
160 |
161 | /**
162 | * Check HTTP Authorization
163 | *
164 | * @return void
165 | */
166 | public function checkHttpAuth()
167 | {
168 | if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) {
169 | header('WWW-Authenticate: Basic realm="' . $this->options->get('shop_name', 'Online Shop') . '"');
170 | header('HTTP/1.0 401 Unauthorized');
171 | $this->logger->warning('HTTP Authorization cancelled');
172 | echo 'Access denied';
173 | exit;
174 | } else {
175 | if ($_SERVER['PHP_AUTH_USER'] != $this->options->get('http_auth_user')
176 | || $_SERVER['PHP_AUTH_PW'] != $this->options->get('http_auth_pass')
177 | ) {
178 | $this->logger->warning('HTTP Authorization error: wrong username or password');
179 | header('HTTP/1.0 401 Unauthorized');
180 | echo 'Access denied';
181 | exit;
182 | }
183 | }
184 | }
185 |
186 |
187 | /**
188 | * Check if IP Address Allowed
189 | *
190 | * @return void
191 | */
192 | public function checkIpAllowed()
193 | {
194 | $ip_list = $this->options->get('allowed_ips');
195 | if ($ip_list) {
196 | $client_ip = $this->request->getClientIp();
197 | $status = Ip::match($client_ip, explode(',', $ip_list));
198 | if (!$status) {
199 | $this->logger->warning('IP Not Allowed');
200 | $response = Response::create('Access denied for IP: '.$client_ip, 403);
201 | $response->send();
202 | exit();
203 | }
204 | }
205 | }
206 |
207 | /**
208 | * Parse XML string
209 | *
210 | * @param string $xml
211 | *
212 | * @return \SimpleXMLElement
213 | *
214 | * @throws \UnexpectedValueException
215 | */
216 | protected function parseXml($xml)
217 | {
218 | libxml_use_internal_errors(true);
219 | $object = simplexml_load_string($xml);
220 | $errors = libxml_get_errors();
221 | libxml_clear_errors();
222 | if ($errors) {
223 | $err = [];
224 | foreach ($errors as $err_obj) {
225 | $err[] = $err_obj->message;
226 | }
227 | $err_str = implode(', ', $err);
228 |
229 | $this->logger->error('XML parsing error. ' . $err_str);
230 | throw new UnexpectedValueException('XML string is invalid. libXML Errors: ' . $err_str);
231 | }
232 |
233 | return $object;
234 | }
235 |
236 | /**
237 | * Perform amount to minor (eg. cents)
238 | *
239 | * @param float $amount Amount in major units (eg. dollars)
240 | *
241 | * @return int
242 | */
243 | public function amtToMinor($amount)
244 | {
245 | if ($amount == 0) {
246 | return 0;
247 | }
248 | $amount = str_replace([',', ' '], ['.', ''], trim($amount));
249 | $amount *= 100;
250 |
251 | return intval($amount);
252 | }
253 |
254 |
255 | /**
256 | * Perform amount to major (dollars)
257 | *
258 | * @param int $amount Amount in minor units (eg. cents)
259 | *
260 | * @return float
261 | */
262 | public function amtToMajor($amount)
263 | {
264 | if ($amount == 0) {
265 | return $this->format($amount);
266 | }
267 | $amount = $amount / 100;
268 | return $this->format($amount);
269 | }
270 |
271 |
272 |
273 | /**
274 | * Format amount
275 | *
276 | * @param mixed $amount Amount
277 | * @param int $decimals Sets the number of decimal points.
278 | *
279 | * @return float
280 | */
281 | public function format($amount = 0, $decimals = 2)
282 | {
283 | $amount = str_replace([',', ' '], ['.', ''], trim($amount));
284 | $amount = (float) $amount;
285 | $amount = ($amount * 100) / 100;
286 | $amount = number_format($amount, $decimals, '.', '');
287 | return (float) $amount;
288 | }
289 |
290 | /**
291 | * Get request url
292 | *
293 | * @return string
294 | */
295 | protected function getRequestUrl()
296 | {
297 | return $this->request->getUri();
298 | }
299 |
300 | /**
301 | * Encode url string
302 | *
303 | * @param string $str
304 | *
305 | * @return string Encoded string
306 | */
307 | protected function encode($str)
308 | {
309 | return rawurlencode($str);
310 | }
311 | }
312 |
--------------------------------------------------------------------------------
/src/Provider/AbstractXMLResponse.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 | namespace Longman\GeoPayment\Provider;
11 |
12 | use Symfony\Component\HttpFoundation\Response;
13 |
14 | /**
15 | * Abstract XML response class
16 | *
17 | */
18 | abstract class AbstractXMLResponse
19 | {
20 |
21 | /**
22 | * Response mode (Depends on bank)
23 | *
24 | * @var string
25 | */
26 | protected $mode;
27 |
28 | /**
29 | * Response body
30 | *
31 | * @var string
32 | */
33 | protected $content;
34 |
35 | /**
36 | * Response object
37 | *
38 | * @var \Symfony\Component\HttpFoundation\Response
39 | */
40 | protected $response;
41 |
42 | /**
43 | * Constructor
44 | *
45 | * @param string $mode Response mode
46 | *
47 | * @return void
48 | */
49 | public function __construct($mode)
50 | {
51 | $this->mode = $mode;
52 | $this->response = new Response('', Response::HTTP_OK, ['content-type' => 'text/xml']);
53 | }
54 |
55 | /**
56 | * Get response body
57 | *
58 | * @return string
59 | */
60 | public function getContent()
61 | {
62 | return $this->content;
63 | }
64 |
65 | /**
66 | * Get response object
67 | *
68 | * @return \Symfony\Component\HttpFoundation\Response
69 | */
70 | public function getResponse()
71 | {
72 | return $this->response;
73 | }
74 |
75 | /**
76 | * Send response to browser
77 | *
78 | * @return void
79 | */
80 | public function send()
81 | {
82 | $this->response->setContent($this->content);
83 |
84 | $this->response->send();
85 |
86 | exit;
87 | }
88 |
89 | /**
90 | * Prepare response body
91 | *
92 | * @return string Response body
93 | */
94 | protected function prepare($string)
95 | {
96 | $string = preg_replace('##', '', $string);
97 | return $string;
98 | }
99 |
100 | /**
101 | * Clean string
102 | *
103 | * @return string
104 | */
105 | protected function clean($var, $substr = null)
106 | {
107 | $var = htmlspecialchars($var);
108 | if ($substr) {
109 | $var = mb_substr($var, 0, $substr, 'UTF-8');
110 | }
111 |
112 | return $var;
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/Provider/Card/Bog/Provider.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 |
11 | namespace Longman\GeoPayment\Provider\Card\Bog;
12 |
13 | use Longman\GeoPayment\Options;
14 | use Longman\GeoPayment\Provider\AbstractProvider;
15 | use Longman\GeoPayment\Provider\Card\Bog\XMLResponse;
16 | use InvalidArgumentException;
17 |
18 | class Provider extends AbstractProvider
19 | {
20 | protected $name = 'bog';
21 |
22 | protected $mode = 'redirect';
23 |
24 | const DEF_PAYMENT_URL = 'https://sb3d.georgiancard.ge/payment/start.wsm';
25 | const DEF_CURRENCY = '981';
26 | const DEF_LANG = 'ka';
27 |
28 | public function setSuccessUrl($url)
29 | {
30 | $this->options->set('back_url_s', $url);
31 | return $this;
32 | }
33 |
34 | public function setFailUrl($url)
35 | {
36 | $this->options->set('back_url_f', $url);
37 | return $this;
38 | }
39 |
40 | public function checkSignature()
41 | {
42 | $signature = $this->request->get('signature');
43 | if (!$signature) {
44 | $this->sendErrorResponse('Signature is missing!');
45 | }
46 |
47 | $request_url = $url = $this->getRequestUrl();
48 |
49 | $url = preg_replace('#&signature=.*$#', '', $url);
50 | $url = rawurldecode($url);
51 |
52 | $cert_file = $this->options->get('cert_path');
53 | $cert = file_get_contents($cert_file);
54 | $key = openssl_pkey_get_public($cert);
55 | //dump(openssl_pkey_get_details($key));
56 |
57 | $signature = base64_decode($signature);
58 | $valid = openssl_verify($url, $signature, $key, OPENSSL_ALGO_SHA1);
59 |
60 | if ($valid !== 1) {
61 | $this->sendErrorResponse('Signature is invalid!');
62 | }
63 |
64 | //$this->logger->info('url: '.$url);
65 |
66 | return $this;
67 | }
68 |
69 | public function getPaymentUrl()
70 | {
71 | $gateway = $this->options->get('payment_url', self::DEF_PAYMENT_URL);
72 |
73 | $gateway .= '?lang=' . $this->encode($this->options->get('lang', self::DEF_LANG));
74 |
75 | $gateway .= '&page_id=' . $this->encode($this->options->get('page_id'));
76 | $gateway .= '&merch_id=' . $this->encode($this->options->get('merchant_id'));
77 |
78 | $gateway .= '&back_url_s=' . $this->encode($this->options->get('back_url_s'));
79 | $gateway .= '&back_url_f=' . $this->encode($this->options->get('back_url_f'));
80 |
81 | foreach ($this->params as $key => $value) {
82 | $gateway .= '&o.' . $key . '=' . $this->encode($value);
83 | }
84 |
85 | return $gateway;
86 | }
87 |
88 | public function sendSuccessResponse($data = [])
89 | {
90 | $response = new XMLResponse($this->mode);
91 |
92 | if ($this->mode == 'check') {
93 | $data['account_id'] = $this->options->get('account_id');
94 | $data['currency'] = $this->options->get('currency', self::DEF_CURRENCY);
95 |
96 | if (empty($data['amount'])) {
97 | $this->logger->debug('amount not defined', ['data' => $data]);
98 | throw new InvalidArgumentException('amount not defined');
99 | }
100 |
101 | if (empty($data['short_desc'])) {
102 | $this->logger->debug('short_desc not defined', ['data' => $data]);
103 | throw new InvalidArgumentException('short_desc not defined');
104 | }
105 |
106 | if (empty($data['long_desc'])) {
107 | $this->logger->debug('long_desc not defined', ['data' => $data]);
108 | throw new InvalidArgumentException('long_desc not defined');
109 | }
110 | }
111 |
112 | $this->logger->debug('sendSuccessResponse: ' . $this->mode, ['data' => $data]);
113 |
114 | $response->success($data)->send();
115 | }
116 |
117 | public function sendErrorResponse($error = 'Unable to accept this payment')
118 | {
119 | $this->logger->debug('sendErrorResponse: ' . $error);
120 | $response = new XMLResponse($this->mode);
121 | $response->error(2, $error)->send();
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/Provider/Card/Bog/XMLResponse.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 | namespace Longman\GeoPayment\Provider\Card\Bog;
11 |
12 | use Longman\GeoPayment\Provider\AbstractXMLResponse;
13 |
14 | class XMLResponse extends AbstractXMLResponse
15 | {
16 |
17 | public function error($code = 2, $desc = 'Unable to accept this payment')
18 | {
19 | if ($this->mode == 'check') {
20 | $this->content = $this->getCheckErrorBody($code, $desc);
21 | } elseif ($this->mode == 'reg') {
22 | $this->content = $this->getRegErrorBody($code, $desc);
23 | }
24 | return $this;
25 | }
26 |
27 | public function success($data = [])
28 | {
29 | if ($this->mode == 'check') {
30 | $this->content = $this->getCheckSuccessBody($data);
31 | } elseif ($this->mode == 'reg') {
32 | $this->content = $this->getRegSuccessBody($data);
33 | }
34 | return $this;
35 | }
36 |
37 | protected function getCheckSuccessBody($data)
38 | {
39 | $trx_id = $this->clean($data['trx_id'], 50);
40 | $short_desc = $this->clean($data['short_desc'], 30);
41 | $long_desc = $this->clean($data['long_desc'], 125);
42 | $account_id = $this->clean($data['account_id'], 32);
43 | $amount = intval($data['amount']);
44 | $currency = $this->clean($data['currency']);
45 |
46 | $content = <<
48 |
49 | 1
50 | OK
51 |
52 |
53 | {$trx_id}
54 |
55 |
56 | {$short_desc}
57 |
58 | {$long_desc}
59 |
60 |
61 |
62 |
63 | {$account_id}
64 |
65 | {$amount}
66 |
67 | {$currency}
68 |
69 | 2
70 |
71 |
72 |
73 | XML;
74 |
75 | return $content;
76 | }
77 |
78 | protected function getCheckErrorBody($code, $desc = 'Unable to accept this payment')
79 | {
80 | $desc = $this->clean($desc, 125);
81 |
82 | $content = <<
84 |
85 | 2
86 | {$desc}
87 |
88 |
89 | XML;
90 | return $content;
91 | }
92 |
93 | protected function getRegSuccessBody($data)
94 | {
95 | $content = <<
97 |
98 | 1
99 | OK
100 |
101 |
102 | XML;
103 |
104 | return $content;
105 | }
106 |
107 | protected function getRegErrorBody($code, $desc = 'Unable to accept this payment')
108 | {
109 | $desc = $this->clean($desc, 125);
110 |
111 | $content = <<
113 |
114 | 2
115 | {$desc}
116 |
117 |
118 | XML;
119 | return $content;
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/Provider/Card/Cartu/Provider.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 |
11 | namespace Longman\GeoPayment\Provider\Card\Cartu;
12 |
13 | use Carbon\Carbon;
14 | use Longman\GeoPayment\Options;
15 | use Longman\GeoPayment\Provider\AbstractProvider;
16 | use Longman\GeoPayment\Provider\Card\Cartu\XMLResponse;
17 | use Symfony\Component\HttpFoundation\Request;
18 | use InvalidArgumentException;
19 |
20 | class Provider extends AbstractProvider
21 | {
22 | protected $name = 'cartu';
23 |
24 | protected $mode = 'redirect'; // redirect, response
25 |
26 | protected $xml_request = '';
27 |
28 | const DEF_PAYMENT_URL = 'https://e-commerce.cartubank.ge/servlet/Process3DSServlet/3dsproxy_init.jsp';
29 | const DEF_CURRENCY = '840';
30 | const DEF_LANG = '01';
31 |
32 | public function setMode($mode)
33 | {
34 | parent::setMode($mode);
35 |
36 | if ($mode == 'response') {
37 | $ConfirmRequest = $this->request->get('ConfirmRequest');
38 | if ($ConfirmRequest) {
39 | $this->xml_request = $this->parseXml($ConfirmRequest);
40 | }
41 | }
42 | return $this;
43 | }
44 |
45 | public function getTransactionId()
46 | {
47 | return (string) $this->xml_request->TransactionId;
48 | }
49 |
50 | public function getPaymentId()
51 | {
52 | return (string) $this->xml_request->PaymentId;
53 | }
54 |
55 | public function getPaymentDate()
56 | {
57 | $date = (string) $this->xml_request->PaymentDate;
58 | $date = Carbon::createFromFormat('d.m.Y H:i:s', $date);
59 | return $date;
60 | }
61 |
62 | public function getAmount()
63 | {
64 | return (string) $this->xml_request->Amount;
65 | }
66 |
67 | public function getCardType()
68 | {
69 | return (string) $this->xml_request->CardType;
70 | }
71 |
72 | public function getReason()
73 | {
74 | return (string) $this->xml_request->Reason;
75 | }
76 |
77 | public function getStatus()
78 | {
79 | return (string) $this->xml_request->Status;
80 | }
81 |
82 | public function checkSignature()
83 | {
84 | $signature = $this->request->get('signature');
85 | if (!$signature) {
86 | $this->sendErrorResponse('Signature is missing!');
87 | }
88 |
89 | $ConfirmRequest = $this->request->get('ConfirmRequest');
90 |
91 | $request_url = $url = $this->getRequestUrl();
92 |
93 | $url = preg_replace('#&signature=.*$#', '', $url);
94 | $url = rawurldecode($url);
95 |
96 | $cert_file = $this->options->get('cert_path');
97 | $cert = file_get_contents($cert_file);
98 | $key = openssl_pkey_get_public($cert);
99 | //dump(openssl_pkey_get_details($key));
100 |
101 | $signature = base64_decode($signature);
102 | $valid = openssl_verify($url, $signature, $key, OPENSSL_ALGO_SHA1);
103 |
104 | if ($valid !== 1) {
105 | $this->sendErrorResponse('Signature is invalid!');
106 | }
107 |
108 | //$this->logger->info('url: '.$url);
109 |
110 | return $this;
111 | }
112 |
113 | public function getPaymentUrl()
114 | {
115 | $gateway = $this->options->get('payment_url', self::DEF_PAYMENT_URL);
116 |
117 | $gateway .= '?CountryCode=' . $this->encode($this->options->get('CountryCode', self::DEF_LANG));
118 |
119 | $gateway .= '&CurrencyCode=' . $this->encode($this->options->get('CurrencyCode', self::DEF_CURRENCY));
120 |
121 | $gateway .= '&MerchantName=' . $this->encode($this->options->get('MerchantName'));
122 | $gateway .= '&MerchantURL=' . $this->encode($this->options->get('MerchantURL'));
123 | $gateway .= '&MerchantCity=' . $this->encode($this->options->get('MerchantCity'));
124 | $gateway .= '&MerchantID=' . $this->encode($this->options->get('MerchantID'));
125 | $gateway .= '&xDDDSProxy.Language=' . $this->encode($this->options->get('xDDDSProxy.Language'));
126 |
127 | foreach ($this->params as $key => $value) {
128 | $gateway .= '&' . $key . '=' . $this->encode($value);
129 | }
130 |
131 | return $gateway;
132 | }
133 |
134 | public function sendSuccessResponse($data = [])
135 | {
136 | $response = new XMLResponse($this->mode);
137 |
138 | if (empty($data['TransactionId'])) {
139 | $this->logger->debug('TransactionId not defined', ['data' => $data]);
140 | throw new InvalidArgumentException('TransactionId not defined');
141 | }
142 |
143 | if (empty($data['PaymentId'])) {
144 | $this->logger->debug('PaymentId not defined', ['data' => $data]);
145 | throw new InvalidArgumentException('PaymentId not defined');
146 | }
147 |
148 | $this->logger->debug('sendSuccessResponse: ' . $this->mode, ['data' => $data]);
149 |
150 | $response->success($data)->send();
151 | }
152 |
153 | public function sendErrorResponse($data = [])
154 | {
155 | $this->logger->debug('sendErrorResponse: ' . $this->mode, ['data' => $data]);
156 | $response = new XMLResponse($this->mode);
157 | $response->error($data)->send();
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/src/Provider/Card/Cartu/XMLResponse.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 | namespace Longman\GeoPayment\Provider\Card\Cartu;
11 |
12 | use Longman\GeoPayment\Provider\AbstractXMLResponse;
13 |
14 | class XMLResponse extends AbstractXMLResponse
15 | {
16 |
17 | public function error($data)
18 | {
19 | $this->content = $this->getCheckErrorBody($code, $desc);
20 | return $this;
21 | }
22 |
23 | public function success($data = [])
24 | {
25 | $this->content = $this->getCheckSuccessBody($data);
26 | return $this;
27 | }
28 |
29 | protected function getCheckSuccessBody($data)
30 | {
31 | $TransactionId = $this->clean($data['TransactionId'], 32);
32 | $PaymentId = $this->clean($data['PaymentId'], 12);
33 |
34 | $content = <<
36 | {$TransactionId}
37 | {$PaymentId}
38 | ACCEPTED
39 |
40 | XML;
41 | return $content;
42 | }
43 |
44 | protected function getCheckErrorBody($data)
45 | {
46 | $TransactionId = $this->clean($data['TransactionId'], 32);
47 | $PaymentId = $this->clean($data['PaymentId'], 12);
48 |
49 | $content = <<
51 | {$TransactionId}
52 | {$PaymentId}
53 | DECLINED
54 |
55 | XML;
56 |
57 | return $content;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/Provider/Pay/Tbcpay/Provider.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 |
11 | namespace Longman\GeoPayment\Provider\Pay\Tbcpay;
12 |
13 | use Longman\GeoPayment\Options;
14 | use Longman\GeoPayment\Provider\AbstractProvider;
15 | use Longman\GeoPayment\Provider\Pay\Tbcpay\XMLResponse;
16 | use InvalidArgumentException;
17 |
18 | class Provider extends AbstractProvider
19 | {
20 | protected $name = 'tbcpay';
21 |
22 | protected $mode = 'check';
23 |
24 |
25 | public function sendSuccessResponse($data = [])
26 | {
27 | $response = new XMLResponse($this->mode);
28 |
29 | if ($this->mode == 'check') {
30 | if (empty($data)) {
31 | $this->logger->debug('extra data not defined', ['data' => $data]);
32 | throw new InvalidArgumentException('extra data not defined');
33 | }
34 | }
35 |
36 | $this->logger->debug('sendSuccessResponse: ' . $this->mode, ['data' => $data]);
37 |
38 | $response->success($data)->send();
39 | }
40 |
41 | public function sendErrorResponse($code = 1, $error = 'Unable to accept this payment')
42 | {
43 | $this->logger->debug('sendErrorResponse: "' . $error .'" with code: '.$code);
44 | $response = new XMLResponse($this->mode);
45 | $response->error($code, $error)->send();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Provider/Pay/Tbcpay/XMLResponse.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 | namespace Longman\GeoPayment\Provider\Pay\Tbcpay;
11 |
12 | use Longman\GeoPayment\Provider\AbstractXMLResponse;
13 |
14 | class XMLResponse extends AbstractXMLResponse
15 | {
16 |
17 | public function error($code = 2, $desc = 'Unable to accept this payment')
18 | {
19 | $this->content = $this->getErrorBody($code, $desc);
20 | return $this;
21 | }
22 |
23 | public function success($data = [])
24 | {
25 | $this->content = $this->getSuccessBody($data);
26 | return $this;
27 | }
28 |
29 | protected function getSuccessBody(array $data = [])
30 | {
31 | $extra_str = '';
32 | foreach ($data as $k => $v) {
33 | $extra_str .= ''.$this->clean($v).''.PHP_EOL;
34 | }
35 |
36 | if ($extra_str) {
37 | $content = <<
39 |
40 | 0
41 |
42 | {$extra_str}
43 |
44 | OK
45 |
46 | XML;
47 | } else {
48 | $content = <<
50 |
51 | 0
52 | OK
53 |
54 | XML;
55 | }
56 |
57 | return $content;
58 | }
59 |
60 | protected function getErrorBody($code, $desc = 'Unable to accept this payment')
61 | {
62 | $desc = $this->clean($desc, 125);
63 |
64 | $content = <<
66 |
67 | {$code}
68 | {$desc}
69 |
70 | XML;
71 | return $content;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/tests/Bootstrap.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 |
11 | /*
12 | * Set error reporting to the level to which Mockery code must comply.
13 | */
14 | error_reporting(-1);
15 |
16 | /*
17 | * Set UTC timezone.
18 | */
19 | date_default_timezone_set('UTC');
20 |
21 |
22 |
23 | $root = realpath(dirname(dirname(__FILE__)));
24 | /**
25 | * Check that --dev composer installation was done
26 | */
27 | if (!file_exists($root . '/vendor/autoload.php')) {
28 | throw new Exception(
29 | 'Please run "php composer.phar install --dev" in root directory '
30 | . 'to setup unit test dependencies before running the tests'
31 | );
32 | }
33 |
34 | // Include the Composer autoloader
35 | $loader = require __DIR__ . '/../vendor/autoload.php';
36 |
37 | /*
38 | * Unset global variables that are no longer needed.
39 | */
40 | unset($root, $loader);
41 |
--------------------------------------------------------------------------------
/tests/Unit/LoggerTest.php:
--------------------------------------------------------------------------------
1 | shouldReceive('pushHandler')->once()->with(m::type('Monolog\Handler\StreamHandler'));
19 | $writer->useFiles(__DIR__);
20 | }
21 |
22 | public function testRotatingFileHandlerCanBeAdded()
23 | {
24 | $writer = new Logger($monolog = m::mock('Monolog\Logger'));
25 | $monolog->shouldReceive('pushHandler')->once()->with(m::type('Monolog\Handler\RotatingFileHandler'));
26 | $writer->useDailyFiles(__DIR__, 5);
27 | }
28 |
29 | public function testErrorLogHandlerCanBeAdded()
30 | {
31 | $writer = new Logger($monolog = m::mock('Monolog\Logger'));
32 | $monolog->shouldReceive('pushHandler')->once()->with(m::type('Monolog\Handler\ErrorLogHandler'));
33 | $writer->useErrorLog();
34 | }
35 |
36 | public function testMethodsPassErrorAdditionsToMonolog()
37 | {
38 | $writer = new Logger($monolog = m::mock('Monolog\Logger'));
39 | $monolog->shouldReceive('error')->once()->with('foo', []);
40 | $writer->error('foo');
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/tests/Unit/OptionsTest.php:
--------------------------------------------------------------------------------
1 | 'value1']);
14 | $this->assertEquals('value1', $options->get('param1'));
15 | }
16 |
17 | public function testGetParamDefault()
18 | {
19 | $options = new Options([]);
20 | $this->assertEquals('value1', $options->get('param1', 'value1'));
21 | }
22 |
23 | public function testGetParamFromEnv()
24 | {
25 | $options = new Options([]);
26 | $_ENV['param1'] = 'value1';
27 | $this->assertEquals('value1', $options->get('param1'));
28 | }
29 |
30 | public function testSetParam()
31 | {
32 | $options = new Options([]);
33 | $options->set('param1', 'value1');
34 | $this->assertEquals('value1', $options->get('param1'));
35 | }
36 |
37 | public function testSetMixedParam()
38 | {
39 | $options = new Options([]);
40 | $object = new \stdClass;
41 | $object->param1 = 'value1';
42 | $options->set('object', $object);
43 | $this->assertEquals($object, $options->get('object'));
44 | }
45 |
46 | public function testDottedParamName()
47 | {
48 | $options = new Options(['param.1' => 'value.1']);
49 | $this->assertEquals('value.1', $options->get('param.1'));
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/tests/Unit/PaymentTest.php:
--------------------------------------------------------------------------------
1 | ')) {
29 | $this->markTestSkipped(
30 | 'Skipping test that can run only on a PHP 7.'
31 | );
32 | }
33 |
34 | $this->setExpectedException('\TypeError');
35 | $payment = new Payment(null, 'type', 'aaa');
36 | }
37 |
38 | /**
39 | * @expectedException \InvalidArgumentException
40 | */
41 | public function testSetWrongConfigFile()
42 | {
43 | $payment = new Payment();
44 | $payment->setConfigFile('/test/path/.file');
45 | }
46 |
47 |
48 | public function testSetValidConfigFile()
49 | {
50 | $payment = new Payment();
51 | $payment->setConfigFile(__DIR__.'/../../examples/.bog.example');
52 | $currency = $payment->getOption('currency');
53 | $this->assertNotNull($currency);
54 | }
55 |
56 |
57 | public function testSetAndGetParameter()
58 | {
59 | $payment = new Payment();
60 |
61 | $options = new Options(['param1' => 'value1']);
62 | $request = Request::createFromGlobals();
63 | $logger = new Logger($monolog = m::mock('Monolog\Logger'));
64 |
65 | $provider = $this->getMockForAbstractClass('Longman\GeoPayment\Provider\AbstractProvider', [$options, $request, $logger]);
66 |
67 | $provider->addParam('test1', 'value1');
68 |
69 | $this->assertEquals('value1', $provider->getParam('test1'));
70 | }
71 |
72 |
73 | public function testSetAndGetMode()
74 | {
75 | $payment = new Payment();
76 |
77 | $options = new Options([]);
78 | $request = Request::createFromGlobals();
79 | $logger = new Logger($monolog = m::mock('Monolog\Logger'));
80 |
81 | $provider = $this->getMockForAbstractClass('Longman\GeoPayment\Provider\AbstractProvider', [$options, $request, $logger]);
82 |
83 | $provider->setMode('test');
84 |
85 | $this->assertEquals('test', $provider->getMode());
86 | }
87 |
88 | public function testAmtToMinor()
89 | {
90 | $payment = new Payment();
91 |
92 | $options = new Options([]);
93 | $request = Request::createFromGlobals();
94 | $logger = new Logger($monolog = m::mock('Monolog\Logger'));
95 |
96 | $provider = $this->getMockForAbstractClass('Longman\GeoPayment\Provider\AbstractProvider', [$options, $request, $logger]);
97 |
98 | $this->assertSame(10000, $provider->amtToMinor(100));
99 | $this->assertSame(150000, $provider->amtToMinor(1500));
100 | }
101 |
102 |
103 | public function testAmtToMajor()
104 | {
105 | $payment = new Payment();
106 |
107 | $options = new Options([]);
108 | $request = Request::createFromGlobals();
109 | $logger = new Logger($monolog = m::mock('Monolog\Logger'));
110 |
111 | $provider = $this->getMockForAbstractClass('Longman\GeoPayment\Provider\AbstractProvider', [$options, $request, $logger]);
112 |
113 | $this->assertSame(100.00, $provider->amtToMajor(10000));
114 | $this->assertSame(1500.00, $provider->amtToMajor(150000));
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/tests/Unit/TestCase.php:
--------------------------------------------------------------------------------
1 | markTestSkipped(
13 | 'Skipping test that can run only on a 64-bit build of PHP.'
14 | );
15 | }
16 | }
17 |
18 | protected function callMethod($obj, $name, array $args)
19 | {
20 | $class = new ReflectionClass($obj);
21 | $method = $class->getMethod($name);
22 | $method->setAccessible(true);
23 | return $method->invokeArgs($obj, $args);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------