ChargeRepository::joinParent()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 7
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
/**
3
 * API for Billing
4
 *
5
 * @link      https://github.com/hiqdev/billing-hiapi
6
 * @package   billing-hiapi
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2017-2018, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\billing\hiapi\charge;
12
13
use hiqdev\php\billing\action\ActionInterface;
14
use hiqdev\php\billing\action\TemporaryAction;
15
use hiqdev\php\billing\charge\Charge;
16
use hiqdev\php\billing\charge\ChargeInterface;
17
use hiqdev\yii\DataMapper\components\ConnectionInterface;
18
use hiqdev\yii\DataMapper\components\EntityManagerInterface;
19
use hiqdev\yii\DataMapper\expressions\CallExpression;
20
use hiqdev\yii\DataMapper\expressions\HstoreExpression;
21
use hiqdev\yii\DataMapper\models\relations\Bucket;
22
use hiqdev\yii\DataMapper\query\Specification;
23
use hiqdev\yii\DataMapper\repositories\BaseRepository;
24
use League\Event\EmitterInterface;
25
use yii\db\Query;
26
27
class ChargeRepository extends BaseRepository
28
{
29
    /**
30
     * @var EmitterInterface
31
     */
32
    private $emitter;
33
34
    public function __construct(
35
        ConnectionInterface $db,
36
        EntityManagerInterface $em,
37
        EmitterInterface $emitter,
38
        array $config = []
39
    ) {
40
        parent::__construct($db, $em, $config);
0 ignored issues
show
Unused Code introduced by
The call to hiqdev\yii\DataMapper\re...pository::__construct() has too many arguments starting with $config. ( Ignorable by Annotation )

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

40
        parent::/** @scrutinizer ignore-call */ 
41
                __construct($db, $em, $config);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
41
42
        $this->emitter = $emitter;
43
    }
44
45
    /** {@inheritdoc} */
46
    public $queryClass = ChargeQuery::class;
47
48
    public function save(Charge $charge)
49
    {
50
        $action = $charge->getAction();
51
        $tariff_id = null;
52
        if ($action->hasSale($action)) {
53
            $tariff_id = $action->getSale()->getPlan()->getId();
54
            $this->saveRealAction($action);
55
        }
56
57
        $hstore = new HstoreExpression(array_filter([
58
            'id'            => $charge->getId(),
59
            'object_id'     => $charge->getTarget()->getId(),
60
            'tariff_id'     => $tariff_id,
61
            'action_id'     => $action->getId(),
62
            'buyer_id'      => $action->getCustomer()->getId(),
63
            'buyer'         => $action->getCustomer()->getLogin(),
64
            'type_id'       => $charge->getType()->getId(),
65
            'type'          => $charge->getType()->getName(),
66
            'currency'      => $charge->getSum()->getCurrency()->getCode(),
67
            'sum'           => $charge->getSum()->getAmount(),
68
            'unit'          => $charge->getUsage()->getUnit()->getName(),
69
            'quantity'      => $charge->getUsage()->getQuantity(),
70
            'bill_id'       => $charge->getBill()->getId(),
71
            'parent_id'     => $charge->getParent() !== null ? $charge->getParent()->getId() : null,
72
            'time'          => $charge->getAction()->getTime()->format('c'),
73
            'is_finished'   => $charge->isFinished(),
74
            'label'         => $charge->getComment(),
75
        ], static function ($value): bool {
76
            return $value !== null;
77
        }, ARRAY_FILTER_USE_BOTH));
78
        $call = new CallExpression('set_charge', [$hstore]);
79
        $command = (new Query())->select($call);
80
        $charge->setId($command->scalar($this->db));
81
        $events = $charge->releaseEvents();
82
        if (!empty($events)) {
83
            $this->emitter->emitBatch($events);
84
        }
85
    }
86
87
    private function saveRealAction(ActionInterface $action): void
88
    {
89
        $i = 0;
90
        while ($action instanceof TemporaryAction) {
91
            $action = $action->getParent();
92
            if ($i++ > 10) {
93
                throw new \RuntimeException('Temporary action nesting limit has been exceeded.');
94
            }
95
        }
96
97
        $this->em->save($action);
98
    }
99
100
    protected function joinParent(&$rows)
101
    {
102
        $bucket = Bucket::fromRows($rows, 'parent-id');
103
        $spec = (new Specification())->where(['id' => $bucket->getKeys()]);
104
        $charges = $this->getRepository(ChargeInterface::class)->queryAll($spec);
105
        $bucket->fill($charges, 'id');
106
        $bucket->pourOneToOne($rows, 'parent');
107
    }
108
}
109