Completed
Push — master ( 80fd4c...ece9a3 )
by Paweł
03:01
created

AccountManager   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 127
rs 10
c 0
b 0
f 0
wmc 17

5 Methods

Rating   Name   Duplication   Size   Complexity  
A saveUsernames() 0 16 1
B updateTags() 0 15 5
B update() 0 41 5
A monitor() 0 14 2
A monitorMultiple() 0 18 4
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\instagram\AccountDetails;
12
use app\components\instagram\AccountScraper;
13
use app\components\instagram\AccountStats;
14
use app\models\Account;
15
use app\models\AccountTag;
16
use app\models\Tag;
17
use yii\base\Component;
18
use yii\db\IntegrityException;
19
use yii\web\NotFoundHttpException;
20
21
class AccountManager extends Component
22
{
23
    public $scraper = AccountScraper::class;
24
25
    /**
26
     * Fetch data from API, update details and stats.
27
     *
28
     * @param \app\models\Account $account
29
     * @throws \Throwable
30
     * @throws \yii\base\Exception
31
     * @throws \yii\base\InvalidConfigException
32
     * @throws \yii\db\Exception
33
     * @throws \yii\web\NotFoundHttpException
34
     */
35
    public function update(Account $account)
36
    {
37
        /** @var AccountScraper $scraper */
38
        $scraper = \Yii::createObject($this->scraper);
39
        /** @var AccountDetails $details */
40
        $details = \Yii::createObject(AccountDetails::class);
41
        /** @var AccountStats $stats */
42
        $stats = \Yii::createObject(AccountStats::class);
43
44
        try {
45
            $data = $scraper->fetchDetails($account);
46
47
        } catch (NotFoundHttpException $exception) {
48
49
            $account->disabled = 1;
0 ignored issues
show
Documentation Bug introduced by
The property $disabled 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...
50
            $account->update(false);
51
52
            throw $exception;
53
        } catch (\Throwable $exception) {
54
            throw $exception;
55
        }
56
57
        // update account details
58
        $details->updateDetails($account, $data);
59
60
        // update profile pic
61
        if ($details->profilePicNeedUpdate($account, $data)) {
62
            $content = $scraper->fetchProfilePic($account, $data->profilePicUrl);
63
            $details->updateProfilePic($account, $data, $content);
64
        }
65
66
        // update account stats
67
        if ($stats->statsNeedUpdate($account, $data)) {
68
            $stats->updateStats($account, $data);
69
        }
70
71
        $posts = $scraper->fetchMedia($account);
72
        // update account media
73
        $details->updateMedia($account, $posts);
74
        // update account er
75
        $stats->updateEr($account);
76
    }
77
78
    public function monitorMultiple(array $usernames, Account $parent)
79
    {
80
        $usernames = array_filter(array_unique($usernames));
81
        foreach ($usernames as $username) {
82
            $account = $this->monitor($username);
83
            $account->proxy_id = $parent->proxy_id;
84
            $account->proxy_tag_id = $parent->proxy_tag_id;
85
86
            //calculation monitoring level
87
            if ($parent->accounts_monitoring_level > 1) {
88
                $level = $parent->accounts_monitoring_level - 1;
89
                if ($level > $account->accounts_monitoring_level) {
90
                    $account->accounts_monitoring_level = $level;
91
                }
92
            }
93
            $account->save();
94
95
            $this->updateTags($account, $parent->tags);
96
        }
97
    }
98
99
    public function monitor(string $username, $proxyId = null, $proxyTagId = null): Account
100
    {
101
        $account = Account::findOne(['username' => $username]);
102
        if ($account === null) {
103
            $account = new Account(['username' => $username]);
104
        }
105
106
        $account->proxy_id = $proxyId;
107
        $account->proxy_tag_id = $proxyTagId;
108
        $account->monitoring = 1;
0 ignored issues
show
Documentation Bug introduced by
The property $monitoring 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...
109
110
        $account->save();
111
112
        return $account;
113
    }
114
115
    public function saveUsernames(array $usernames)
116
    {
117
        $createdAt = (new \DateTime())->format('Y-m-d H:i:s');
118
        $rows = array_map(function ($username) use ($createdAt) {
119
            return [
120
                $username,
121
                $createdAt,
122
                $createdAt,
123
            ];
124
        }, $usernames);
125
126
        $sql = \Yii::$app->db->getQueryBuilder()
127
            ->batchInsert(Account::tableName(), ['username', 'updated_at', 'created_at'], $rows);
128
        $sql = str_replace('INSERT INTO ', 'INSERT IGNORE INTO ', $sql);
129
        \Yii::$app->db->createCommand($sql)
130
            ->execute();
131
    }
132
133
    public function updateTags(Account $account, array $tags)
134
    {
135
        foreach ($tags as $tag) {
136
            if (is_string($tag)) {
137
                $name = $tag;
138
                $tag = Tag::findOne(['name' => $name]);
139
                if ($tag === null) {
140
                    $tag = new Tag(['name' => $name]);
141
                    $tag->insert();
142
                }
143
            }
144
            try {
145
                $account->link('tags', $tag);
146
            } catch (IntegrityException $exception) {
147
                continue;
148
            }
149
        }
150
    }
151
}