Passed
Push — master ( 0db423...f9fe2f )
by Paweł
03:15
created

MediaManager::statsNeedUpdate()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 3
nop 2
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Created for IG Monitoring.
4
 * User: jakim <[email protected]>
5
 * Date: 12.01.2018
6
 */
7
8
namespace app\components;
9
10
11
use app\models\Account;
12
use app\models\Media;
13
use app\models\MediaAccount;
14
use app\models\MediaStats;
15
use app\models\MediaTag;
16
use app\models\Tag;
17
use jakim\ig\Text;
18
use Jakim\Model\Post;
19
use yii\base\Component;
20
use yii\base\Exception;
21
22
class MediaManager extends Component
23
{
24
    /**
25
     * @var \app\models\Account
26
     */
27
    public $account;
28
29
    /**
30
     * @param \app\models\Media $media
31
     * @param \Jakim\Model\Post $data
32
     * @throws \yii\base\Exception
33
     * @throws \yii\base\InvalidConfigException
34
     * @throws \yii\db\Exception
35
     */
36
    public function update(Media $media, Post $data)
37
    {
38
        $media = $this->updateDetails($media, $data);
39
40
        if (!$this->account) {
41
            $this->account = $media->account;
42
            $this->account->refresh();
43
        }
44
45
        if ($media->caption) {
46
            $tags = (array)Text::getTags($media->caption);
47
            $this->updateTags($media, $tags);
48
49
            $usernames = (array)Text::getUsernames($media->caption);
50
            // ignore owner of media
51
            ArrayHelper::removeValue($usernames, $this->account->username);
52
            $this->updateUsernames($media, $usernames);
53
        }
54
55
        $this->updateStats($media, $data);
56
    }
57
58
    /**
59
     * @param \app\models\Media $media
60
     * @param \Jakim\Model\Post $data
61
     * @return \app\models\Media
62
     * @throws \yii\base\Exception
63
     */
64
    public function updateDetails(Media $media, Post $data): Media
65
    {
66
        $media->instagram_id = $data->id;
67
        $media->shortcode = $data->shortcode;
68
        $media->is_video = $data->isVideo;
69
        $media->caption = $data->caption;
70
        $media->taken_at = (new \DateTime('@' . $data->takenAt))->format('Y-m-d H:i:s');
71
72
        if (!$media->account_id && $this->account) {
73
            $media->account_id = $this->account->id;
74
        }
75
76
        if (!$media->save()) {
77
            throw new Exception(json_encode($media->errors));
78
        }
79
80
        return $media;
81
    }
82
83
    /**
84
     * @param \app\models\Media $media
85
     * @param \Jakim\Model\Post $data
86
     * @return \app\models\MediaStats|null
87
     */
88
    public function updateStats(Media $media, Post $data): ?MediaStats
89
    {
90
        $account = $media->account ?? $this->account;
91
        if (empty($account->lastAccountStats)) {
92
            return null;
93
        }
94
        $mediaStats = null;
95
        if ($this->statsNeedUpdate($media, $data)) {
96
            $mediaStats = new MediaStats();
97
            $mediaStats->likes = $data->likes;
98
            $mediaStats->comments = $data->comments;
99
            $mediaStats->account_followed_by = $this->account->lastAccountStats->followed_by;
100
            $mediaStats->account_follows = $this->account->lastAccountStats->follows;
101
            $media->link('mediaStats', $mediaStats);
102
        }
103
104
        return $mediaStats;
105
    }
106
107
    public function updateUsernames(Media $media, array $usernames)
108
    {
109
        $manager = \Yii::createObject(AccountManager::class);
110
        $manager->saveUsernames($usernames);
111
112
        $createdAt = (new \DateTime())->format('Y-m-d H:i:s');
113
        $rows = array_map(function ($id) use ($media, $createdAt) {
114
            return [
115
                $media->id,
116
                $id,
117
                $createdAt,
118
            ];
119
        }, Account::find()
120
            ->andWhere(['username' => $usernames])
121
            ->column());
122
123
        $sql = \Yii::$app->db->queryBuilder
124
            ->batchInsert(MediaAccount::tableName(), ['media_id', 'account_id', 'created_at'], $rows);
125
        $sql = str_replace('INSERT INTO ', 'INSERT IGNORE INTO ', $sql);
126
        \Yii::$app->db->createCommand($sql)
127
            ->execute();
128
    }
129
130
    /**
131
     * @param \app\models\Media $media
132
     * @param array $tags
133
     * @throws \yii\base\InvalidConfigException
134
     * @throws \yii\db\Exception
135
     */
136
    public function updateTags(Media $media, array $tags)
137
    {
138
        $manager = \Yii::createObject(TagManager::class);
139
        $manager->saveTags($tags);
140
141
        $createdAt = (new \DateTime())->format('Y-m-d H:i:s');
142
        $rows = array_map(function ($id) use ($media, $createdAt) {
143
            return [
144
                $media->id,
145
                $id,
146
                $createdAt,
147
            ];
148
        }, Tag::find()
149
            ->andWhere(['name' => $tags])
150
            ->column());
151
152
        $sql = \Yii::$app->db->queryBuilder
153
            ->batchInsert(MediaTag::tableName(), ['media_id', 'tag_id', 'created_at'], $rows);
154
        $sql = str_replace('INSERT INTO ', 'INSERT IGNORE INTO ', $sql);
155
        \Yii::$app->db->createCommand($sql)
156
            ->execute();
157
    }
158
159
    /**
160
     * @param \app\models\Media $media
161
     * @param \Jakim\Model\Post $data
162
     * @return bool
163
     */
164
    private function statsNeedUpdate(Media $media, Post $data): bool
165
    {
166
        if (!$media->lastMediaStats) {
167
            return true;
168
        }
169
170
        return $media->lastMediaStats->likes != $data->likes ||
171
            $media->lastMediaStats->comments != $data->comments;
172
    }
173
}