Passed
Push — master ( fa3dfe...661634 )
by Paweł
04:54
created

AccountManager::updateInvalidation()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
c 0
b 0
f 0
nc 2
nop 2
dl 0
loc 10
rs 10
1
<?php
2
/**
3
 * Created for IG Monitoring.
4
 * User: jakim <[email protected]>
5
 * Date: 28.04.2018
6
 */
7
8
namespace app\components;
9
10
11
use app\components\traits\FindOrCreate;
12
use app\models\Account;
13
use app\models\AccountTag;
14
use app\models\Media;
15
use app\models\MediaAccount;
16
use yii\base\Component;
17
use yii\db\Expression;
18
use yii\helpers\StringHelper;
19
20
class AccountManager extends Component
21
{
22
    use FindOrCreate;
23
24
    /**
25
     * @param \app\models\Account $account
26
     * @param int $nextUpdateInterval In hours from now.
27
     */
28
    public function markAsValid(Account $account, int $nextUpdateInterval = 24)
29
    {
30
        $account->invalidation_count = 0;
31
        $account->is_valid = 1;
0 ignored issues
show
Documentation Bug introduced by
The property $is_valid was declared of type boolean, but 1 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
32
        $account->invalidation_type_id = null;
33
34
        $this->setDateOfNextStatsUpdate($account, $nextUpdateInterval);
35
    }
36
37
    public function updateInvalidation(Account $account, ?int $invalidationType)
38
    {
39
        $account->invalidation_count = (int)$account->invalidation_count + 1;
40
        $account->is_valid = 0;
0 ignored issues
show
Documentation Bug introduced by
The property $is_valid was declared of type boolean, but 0 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
41
        $account->invalidation_type_id = $invalidationType;
42
        $interval = 1;
43
        for ($i = 1; $i <= $account->invalidation_count; $i++) {
44
            $interval *= $i;
45
        }
46
        $this->setDateOfNextStatsUpdate($account, $interval);
47
    }
48
49
    /**
50
     * @param \app\models\Account $account
51
     * @param int $interval In hours from now.
52
     */
53
    public function setDateOfNextStatsUpdate(Account $account, int $interval = 24)
54
    {
55
        $account->update_stats_after = new Expression('DATE_ADD(NOW(), INTERVAL :interval HOUR)', [
56
            'interval' => $interval,
57
        ]);
58
        $account->save();
59
    }
60
61
    public function monitorRelatedAccounts(Account $parent, array $accounts)
62
    {
63
        foreach ($accounts as $account) {
64
            if (\is_string($account)) {
65
                /** @var Account $account */
66
                $account = $this->findOrCreate(['username' => $account], Account::class);
67
                if ($account->disabled) {
68
                    continue;
69
                }
70
            }
71
            //calculation monitoring level
72
            if ($parent->accounts_monitoring_level > 1) {
73
                $level = $parent->accounts_monitoring_level - 1;
74
                if ($level > $account->accounts_monitoring_level) {
75
                    $account->accounts_monitoring_level = $level;
76
                }
77
            }
78
79
            $this->monitor($account, $parent->proxy_id, $parent->proxy_tag_id);
80
81
            $tags = empty($parent->accounts_default_tags) ? $parent->tags : StringHelper::explode($parent->accounts_default_tags, ',', true, true);
82
            $tagManager = \Yii::createObject(TagManager::class);
83
            $tagManager->saveForAccount($account, $tags);
84
        }
85
    }
86
87
    public function monitor($account, $proxyId = null, $proxyTagId = null): Account
88
    {
89
        if (\is_string($account)) {
90
            /** @var Account $account */
91
            $account = $this->findOrCreate(['username' => $account], Account::class);
92
        }
93
94
        $account->proxy_id = $proxyId;
95
        $account->proxy_tag_id = $proxyTagId;
96
        $account->monitoring = 1;
97
98
        $account->save();
99
100
        return $account;
101
    }
102
103
    public function saveForMedia(Media $media, array $usernames)
104
    {
105
        $this->saveUsernames($usernames);
106
107
        $createdAt = (new \DateTime())->format('Y-m-d H:i:s');
108
        $rows = array_map(function ($id) use ($media, $createdAt) {
109
            return [
110
                $media->id,
111
                $id,
112
                $createdAt,
113
            ];
114
        }, Account::find()
115
            ->andWhere(['username' => $usernames])
116
            ->column());
117
118
        $sql = \Yii::$app->db->queryBuilder
119
            ->batchInsert(MediaAccount::tableName(), ['media_id', 'account_id', 'created_at'], $rows);
120
        $sql = str_replace('INSERT INTO ', 'INSERT IGNORE INTO ', $sql);
121
        \Yii::$app->db->createCommand($sql)
122
            ->execute();
123
    }
124
125
    /**
126
     * @param array|string[] $usernames
127
     * @throws \yii\db\Exception
128
     */
129
    public function saveUsernames(array $usernames)
130
    {
131
        $createdAt = (new \DateTime())->format('Y-m-d H:i:s');
132
        $rows = array_map(function ($username) use ($createdAt) {
133
            return [
134
                $username,
135
                $createdAt,
136
                $createdAt,
137
            ];
138
        }, $usernames);
139
140
        $sql = \Yii::$app->db->getQueryBuilder()
141
            ->batchInsert(Account::tableName(), ['username', 'updated_at', 'created_at'], $rows);
142
        $sql = str_replace('INSERT INTO ', 'INSERT IGNORE INTO ', $sql);
143
        \Yii::$app->db->createCommand($sql)
144
            ->execute();
145
    }
146
147
    /**
148
     * @param string|string[] $tags
149
     * @param null|int $userId
150
     * @return array|int[]
151
     */
152
    public function findByTags($tags, $userId = null): array
153
    {
154
        if (is_string($tags)) {
155
            $tags = StringHelper::explode($tags, ',', true, true);
156
            $tags = array_unique($tags);
157
        }
158
159
        $ids = [];
160
        foreach ($tags as $tag) {
161
            $ids[] = AccountTag::find()
162
                ->distinct()
163
                ->select('account_id')
164
                ->innerJoinWith('tag')
165
                ->andFilterWhere(['user_id' => $userId])
166
                ->andFilterWhere(['like', 'tag.name', $tag])
167
                ->column();
168
        }
169
170
        return array_intersect(...$ids, ...$ids);
171
    }
172
}