Passed
Push — master ( 2d5d29...0740c8 )
by ReliQ
04:50 queued 13s
created

Publisher   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 48
dl 0
loc 130
rs 10
c 0
b 0
f 0
wmc 11

5 Methods

Rating   Name   Duplication   Size   Complexity  
A update() 0 16 2
A __construct() 0 16 2
A publish() 0 16 2
A getProductForPublishing() 0 9 2
A updateAll() 0 27 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ReliqArts\Docweaver\Service\Documentation;
6
7
use Illuminate\Console\Command;
8
use ReliqArts\Docweaver\Contract\ConfigProvider;
9
use ReliqArts\Docweaver\Contract\Documentation\Publisher as PublisherContract;
10
use ReliqArts\Docweaver\Contract\Exception;
11
use ReliqArts\Docweaver\Contract\Filesystem;
12
use ReliqArts\Docweaver\Contract\Logger;
13
use ReliqArts\Docweaver\Contract\Product\Maker as ProductFactory;
14
use ReliqArts\Docweaver\Contract\Product\Publisher as ProductPublisher;
15
use ReliqArts\Docweaver\Exception\BadImplementation;
16
use ReliqArts\Docweaver\Exception\DirectoryNotWritable;
17
use ReliqArts\Docweaver\Model\Product;
18
use ReliqArts\Docweaver\Result;
19
use ReliqArts\Docweaver\Service\Publisher as BasePublisher;
20
21
/**
22
 * Publishes and updates documentation.
23
 */
24
final class Publisher extends BasePublisher implements PublisherContract
25
{
26
    /**
27
     * @var ProductPublisher
28
     */
29
    private ProductPublisher $productPublisher;
30
31
    /**
32
     * @var ProductFactory
33
     */
34
    private ProductFactory $productFactory;
35
36
    /**
37
     * Working directory.
38
     *
39
     * @var string
40
     */
41
    private string $workingDirectory;
42
43
    /**
44
     * Create a new DocumentationPublisher.
45
     *
46
     * @throws BadImplementation
47
     */
48
    public function __construct(
49
        Filesystem $filesystem,
50
        Logger $logger,
51
        ConfigProvider $configProvider,
52
        ProductPublisher $productPublisher,
53
        ProductFactory $productFactory
54
    ) {
55
        parent::__construct($filesystem, $logger);
56
57
        $this->productPublisher = $productPublisher;
58
        $this->productFactory = $productFactory;
59
        $documentationDirectory = $configProvider->getDocumentationDirectory();
60
        $this->workingDirectory = base_path($documentationDirectory);
61
62
        if (!$this->readyResourceDirectory($this->workingDirectory)) {
63
            throw new BadImplementation(sprintf('Could not ready document resource directory `%s`. Please ensure file system is writable.', $documentationDirectory));
64
        }
65
    }
66
67
    /**
68
     * @throws Exception
69
     */
70
    public function publish(string $productName, string $source = '', Command &$callingCommand = null): Result
71
    {
72
        $this->callingCommand = $callingCommand;
73
74
        $this->setExecutionStartTime();
75
76
        $result = $this->productPublisher->publish($this->getProductForPublishing($productName), $source);
77
78
        foreach ($result->getMessages() as $message) {
79
            $this->tell($message);
80
        }
81
82
        $data = $result->getExtra() ?? (object)[];
83
        $data->executionTime = $this->getExecutionTime();
84
85
        return $result->setExtra($data);
86
    }
87
88
    /**
89
     * @throws Exception
90
     */
91
    public function update(string $productName, Command &$callingCommand = null): Result
92
    {
93
        $this->callingCommand = $callingCommand;
94
95
        $this->setExecutionStartTime();
96
97
        $result = $this->productPublisher->update($this->getProductForPublishing($productName));
98
99
        foreach ($result->getMessages() as $message) {
100
            $this->tell($message);
101
        }
102
103
        $data = $result->getExtra() ?? (object)[];
104
        $data->executionTime = $this->getExecutionTime();
105
106
        return $result->setExtra($data);
107
    }
108
109
    /**
110
     * @throws Exception
111
     */
112
    public function updateAll(Command &$callingCommand = null): Result
113
    {
114
        $this->callingCommand = $callingCommand;
115
        $result = new Result();
116
        $productDirectories = $this->filesystem->directories($this->workingDirectory);
117
        $products = [];
118
        $productsUpdated = [];
119
120
        $this->setExecutionStartTime();
121
122
        foreach ($productDirectories as $productDirectory) {
123
            $productName = basename($productDirectory);
124
125
            $this->tell(sprintf('Updating %s...', $productName), self::TELL_DIRECTION_FLAT);
126
127
            $productResult = $this->update($productName, $callingCommand);
128
            $products[] = $productName;
129
130
            if ($productResult->isSuccess()) {
131
                $productsUpdated[] = $productName;
132
            }
133
        }
134
135
        return $result->setExtra((object)[
136
            'products' => $products,
137
            'productsUpdated' => $productsUpdated,
138
            'executionTime' => $this->getExecutionTime(),
139
        ]);
140
    }
141
142
    /**
143
     * @throws Exception
144
     */
145
    private function getProductForPublishing(string $productName): Product
146
    {
147
        $productDirectory = sprintf('%s/%s', $this->workingDirectory, strtolower($productName));
148
149
        if (!$this->readyResourceDirectory($productDirectory)) {
150
            throw DirectoryNotWritable::forDirectory($productDirectory);
151
        }
152
153
        return $this->productFactory->create($productDirectory);
154
    }
155
}
156