Completed
Push — master ( 9003e7...f2c4d3 )
by ReliQ
04:59
created

Publisher::publish()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 24

Duplication

Lines 24
Ratio 100 %

Importance

Changes 0
Metric Value
dl 24
loc 24
rs 9.536
c 0
b 0
f 0
cc 3
nc 3
nop 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ReliQArts\Docweaver\Services\Documentation;
6
7
use Illuminate\Console\Command;
8
use ReliQArts\Docweaver\Contracts\ConfigProvider;
9
use ReliQArts\Docweaver\Contracts\Documentation\Publisher as PublisherContract;
10
use ReliQArts\Docweaver\Contracts\Exception;
11
use ReliQArts\Docweaver\Contracts\Filesystem;
12
use ReliQArts\Docweaver\Contracts\Logger;
13
use ReliQArts\Docweaver\Contracts\Product\Maker as ProductFactory;
14
use ReliQArts\Docweaver\Contracts\Product\Publisher as ProductPublisher;
15
use ReliQArts\Docweaver\Exceptions\BadImplementation;
16
use ReliQArts\Docweaver\Services\Publisher as BasePublisher;
17
use ReliQArts\Docweaver\VO\Result;
18
19
/**
20
 * Publishes and updates documentation.
21
 */
22
final class Publisher extends BasePublisher implements PublisherContract
23
{
24
    /**
25
     * Documentation resource directory.
26
     *
27
     * @var string
28
     */
29
    private $documentationDirectory;
30
31
    /**
32
     * @var ProductPublisher
33
     */
34
    private $productPublisher;
35
36
    /**
37
     * @var ProductFactory
38
     */
39
    private $productFactory;
40
41
    /**
42
     * Working directory.
43
     *
44
     * @var string
45
     */
46
    private $workingDirectory;
47
48
    /**
49
     * Create a new DocumentationPublisher.
50
     *
51
     * @param Filesystem       $filesystem
52
     * @param Logger           $logger
53
     * @param ConfigProvider   $configProvider
54
     * @param ProductPublisher $productPublisher
55
     * @param ProductFactory   $productFactory
56
     *
57
     * @throws BadImplementation
58
     */
59
    public function __construct(
60
        Filesystem $filesystem,
61
        Logger $logger,
62
        ConfigProvider $configProvider,
63
        ProductPublisher $productPublisher,
64
        ProductFactory $productFactory
65
    ) {
66
        parent::__construct($filesystem, $logger);
67
68
        $this->productPublisher = $productPublisher;
69
        $this->productFactory = $productFactory;
70
        $this->documentationDirectory = $configProvider->getDocumentationDirectory();
71
        $this->workingDirectory = base_path($this->documentationDirectory);
72
73
        if (!$this->readyResourceDirectory($this->workingDirectory)) {
74
            throw new BadImplementation(
75
                sprintf(
76
                    'Could not ready document resource directory `%s`. Please ensure file system is writable.',
77
                    $this->documentationDirectory
78
                )
79
            );
80
        }
81
    }
82
83
    /**
84
     * @param string       $productName
85
     * @param string       $source
86
     * @param null|Command $callingCommand
87
     *
88
     * @throws Exception
89
     *
90
     * @return Result
91
     */
92 View Code Duplication
    public function publish(string $productName, string $source = '', Command &$callingCommand = null): Result
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
93
    {
94
        $result = new Result();
95
        $commonName = strtolower($productName);
96
        $productDirectory = sprintf('%s/%s', $this->workingDirectory, $commonName);
97
98
        $this->setExecutionStartTime();
99
        if (!$this->readyResourceDirectory($productDirectory)) {
100
            return $result->setError(sprintf('Product directory %s is not writable.', $productDirectory))
101
                ->setData((object)['executionTime' => $this->getExecutionTime()]);
102
        }
103
104
        $product = $this->productFactory->create($productDirectory);
105
        $result = $this->productPublisher->publish($product, $source);
106
107
        foreach ($result->getMessages() as $message) {
108
            $this->tell($message);
109
        }
110
111
        $data = $result->getData() ?? (object)[];
112
        $data->executionTime = $this->getExecutionTime();
113
114
        return $result->setData($data);
115
    }
116
117
    /**
118
     * @param string       $productName
119
     * @param null|Command $callingCommand
120
     *
121
     * @throws Exception
122
     *
123
     * @return Result
124
     */
125 View Code Duplication
    public function update(string $productName, Command &$callingCommand = null): Result
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
126
    {
127
        $this->callingCommand = $callingCommand;
128
        $result = new Result();
129
        $commonName = strtolower($productName);
130
        $productDirectory = sprintf('%s/%s', $this->workingDirectory, $commonName);
131
132
        $this->setExecutionStartTime();
133
        if (!$this->readyResourceDirectory($productDirectory)) {
134
            return $result->setError(sprintf('Product directory %s is not writable.', $productDirectory))
135
                ->setData((object)['executionTime' => $this->getExecutionTime()]);
136
        }
137
138
        $product = $this->productFactory->create($productDirectory);
139
        $result = $this->productPublisher->update($product);
140
141
        foreach ($result->getMessages() as $message) {
142
            $this->tell($message);
143
        }
144
145
        $data = $result->getData() ?? (object)[];
146
        $data->executionTime = $this->getExecutionTime();
147
148
        return $result->setData($data);
149
    }
150
151
    /**
152
     * @param null|Command $callingCommand
153
     *
154
     * @throws Exception
155
     *
156
     * @return Result
157
     */
158
    public function updateAll(Command &$callingCommand = null): Result
159
    {
160
        $this->callingCommand = $callingCommand;
161
        $result = new Result();
162
        $productDirectories = $this->filesystem->directories($this->workingDirectory);
163
        $products = [];
164
        $productsUpdated = [];
165
166
        $this->setExecutionStartTime();
167
168
        foreach ($productDirectories as $productDirectory) {
169
            $productName = basename($productDirectory);
170
171
            $this->tell(sprintf('Updating %s...', $productName), self::TELL_DIRECTION_FLAT);
172
173
            $productResult = $this->update($productName, $callingCommand);
174
            $products[] = $productName;
175
176
            if ($productResult->isSuccess()) {
177
                $productsUpdated[] = $productName;
178
            }
179
        }
180
181
        return $result->setData((object)[
182
            'products' => $products,
183
            'productsUpdated' => $productsUpdated,
184
            'executionTime' => $this->getExecutionTime(),
185
        ]);
186
    }
187
}
188