ArticlesImport::import()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 2
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of laravel.su package.
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace App\Console\Commands;
11
12
use Carbon\Carbon;
13
use App\Models\Bot;
14
use App\Models\Article;
15
use Illuminate\Console\Command;
16
use App\Services\DataProviders\Manager;
17
use App\Services\DataProviders\ExternalArticle;
18
use App\Services\DataProviders\DataProviderInterface;
19
use Illuminate\Database\Eloquent\Relations\MorphMany;
20
21
/**
22
 * Class ArticlesImport.
23
 */
24
class ArticlesImport extends Command
25
{
26
    /**
27
     * The name and signature of the console command.
28
     * @var string
29
     */
30
    protected $signature = 'articles:import';
31
32
    /**
33
     * The console command description.
34
     * @var string
35
     */
36
    protected $description = 'Run import articles from external services';
37
38
    /**
39
     * @var array
40
     */
41
    private $published = [];
42
43
    /**
44
     * @param  Manager                   $manager
45
     * @throws \InvalidArgumentException
46
     */
47
    public function handle(Manager $manager)
48
    {
49
        $this->importPublished($manager);
50
51
        $this->importNotPublished($manager);
52
    }
53
54
    /**
55
     * @param  Manager                   $manager
56
     * @throws \InvalidArgumentException
57
     * @return void
58
     */
59
    private function importPublished(Manager $manager): void
60
    {
61
        /** @var Article $article */
62
        foreach ($this->getLatestBotArticles() as $article) {
63
            /** @var Bot $bot */
64
            $bot = $article->user;
65
66
            $this->import($article->published_at, $manager->get($bot->provider));
67
68
            $this->published[] = $bot->provider;
69
        }
70
    }
71
72
    /**
73
     * @return \Generator|Article[]
74
     */
75
    private function getLatestBotArticles(): \Generator
76
    {
77
        $bots = Bot::query()
78
            ->with(['articles' => function (MorphMany $relation) {
79
                return $relation->latest('published_at')->take(1);
80
            }])
81
            ->get();
82
83
        foreach ($bots as $bot) {
84
            $article = $bot->articles->first();
85
86
            if ($article) {
87
                yield $article;
88
            }
89
        }
90
    }
91
92
    /**
93
     * @param \DateTime             $time
94
     * @param DataProviderInterface $provider
95
     */
96
    private function import(\DateTime $time, DataProviderInterface $provider)
97
    {
98
        /** @var ExternalArticle[] $latest */
99
        $latest = $provider->getLatest($time);
100
101
        foreach ($latest as $external) {
102
            $article = new Article();
103
104
            $article->user_id = 1;
105
            $article->user_type = Bot::class;
106
107
            $external->fill($article);
108
109
            $article->save();
110
        }
111
    }
112
113
    /**
114
     * @param  Manager $manager
115
     * @return void
116
     */
117
    private function importNotPublished(Manager $manager): void
118
    {
119
        foreach ($manager as $alias => $provider) {
120
            if (in_array($alias, $this->published, true)) {
121
                continue;
122
            }
123
124
            $this->import(Carbon::createFromTimestamp(0), $provider);
125
        }
126
    }
127
}
128