Completed
Push — pac-89--debug-report ( 7c93c5...53bbe6 )
by Tim
02:48
created

DebugUtil::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
cc 1
nc 1
nop 4
1
<?php
2
3
/**
4
 * TechDivision\Import\Utils\DebugUtil
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2020 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/techdivision/import-cli
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Utils;
22
23
use Doctrine\Common\Collections\Collection;
24
use TechDivision\Import\SystemLoggerTrait;
25
use TechDivision\Import\ApplicationInterface;
26
use TechDivision\Import\Services\RegistryProcessorInterface;
27
use TechDivision\Import\Configuration\ConfigurationInterface;
28
use TechDivision\Import\Listeners\Renderer\RendererInterface;
29
30
/**
31
 * A utility class to create cache keys.
32
 *
33
 * @author    Tim Wagner <[email protected]>
34
 * @copyright 2020 TechDivision GmbH <[email protected]>
35
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
36
 * @link      https://github.com/techdivision/import-cli
37
 * @link      http://www.techdivision.com
38
 */
39
class DebugUtil implements DebugUtilInterface
40
{
41
42
    /**
43
     * The trait that provides basic system logger functionality.
44
     *
45
     * @var \TechDivision\Import\SystemLoggerTrait
46
     */
47
    use SystemLoggerTrait;
48
49
    /**
50
     * The import processor instance.
51
     *
52
     * @var \TechDivision\Import\Services\RegistryProcessorInterface
53
     */
54
    private $registryProcessor;
55
56
    /**
57
     * The configuration instance.
58
     *
59
     * @var \TechDivision\Import\Configuration\ConfigurationInterface
60
     */
61
    private $configuration;
62
63
    /**
64
     * The debug dump renderer.
65
     *
66
     * @var \TechDivision\Import\Listeners\Renderer\RendererInterface
67
     */
68
    private $renderer;
69
70
    /**
71
     * Initializes the plugin with the application instance.
72
     *
73
     * @param \TechDivision\Import\Services\RegistryProcessorInterface  $registryProcessor The registry processor instance
74
     * @param \TechDivision\Import\Configuration\ConfigurationInterface $configuration     The configuration instance
75
     * @param \Doctrine\Common\Collections\Collection                   $systemLoggers     The array with the system loggers instances
76
     * @param \TechDivision\Import\Listeners\Renderer\RendererInterface $renderer          The debug dump renderer instance
77
     */
78
    public function __construct(
79
        RegistryProcessorInterface $registryProcessor,
80
        ConfigurationInterface $configuration,
81
        Collection $systemLoggers,
82
        RendererInterface $renderer
83
    ) {
84
        $this->registryProcessor = $registryProcessor;
85
        $this->configuration = $configuration;
86
        $this->systemLoggers = $systemLoggers;
0 ignored issues
show
Documentation Bug introduced by
It seems like $systemLoggers of type object<Doctrine\Common\Collections\Collection> is incompatible with the declared type array of property $systemLoggers.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
87
        $this->renderer = $renderer;
88
89
    }
90
91
    /**
92
     * Return's the registry processor instance.
93
     *
94
     * @return \TechDivision\Import\Services\RegistryProcessorInterface The registry processor instance
95
     */
96
    private function getRegistryProcessor() : RegistryProcessorInterface
97
    {
98
        return $this->registryProcessor;
99
    }
100
101
    /**
102
     * Return's the configuration instance.
103
     *
104
     * @return \TechDivision\Import\Configuration\ConfigurationInterface The configuration instance
105
     */
106
    private function getConfiguration() : ConfigurationInterface
107
    {
108
        return $this->configuration;
109
    }
110
111
    /**
112
     * Return's the application instance.
113
     *
114
     * @return \TechDivision\Import\ApplicationInterface The application instance
115
     */
116
    private function getApplication() : ApplicationInterface
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
117
    {
118
        return $this->application;
0 ignored issues
show
Bug introduced by
The property application does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
119
    }
120
121
    /**
122
     * Return's the debug dump renderer instance.
123
     *
124
     * @return \TechDivision\Import\Listeners\Renderer\RendererInterface The debug dump renderer instance
125
     */
126
    private function getRenderer() : RendererInterface
127
    {
128
        return $this->renderer;
129
    }
130
131
    /**
132
     * The method to extract an archive that has already been created by a previous
133
     * import back into the source directory.
134
     *
135
     * @param string $serial The serial of the archive to extract
136
     *
137
     * @return void
138
     * @throws \Exception Is thrown, if the archive can not be extracted back into the source directory
139
     */
140
    public function extractArchive(string $serial) : void
141
    {
142
143
        // clear the filecache
144
        clearstatcache();
145
146
        // load the actual status
147
        $status = $this->getRegistryProcessor()->getAttribute(RegistryKeys::STATUS);
148
149
        // query whether or not the configured source directory is available
150
        if (isset($status[RegistryKeys::SOURCE_DIRECTORY])) {
151
            $sourceDir = $status[RegistryKeys::SOURCE_DIRECTORY];
152
        } else {
153
            throw new \Exception('Source directory is not available!');
154
        }
155
156
        // try to load the archive directory
157
        $archiveDir = $this->getConfiguration()->getArchiveDir();
158
159
        // query whether or not the specified archive directory already exists
160
        if ($archiveDir === null) {
161
            $archiveDir = sprintf('var/import_history');
162
        }
163
164
        // initialize the ZIP instance
165
        $zip = new \ZipArchive();
166
167
        // prepare the archive filename
168
        $archiveFile = sprintf('%s/%s.zip', $archiveDir, $serial);
169
170
        // query whether or not the directory already exists
171
        if (is_dir($sourceDir)) {
172
            // log a warning and stop extracting the files
173
            $this->getSystemLogger()->warning(
174
                sprintf(
175
                    'Won\'t extract artefacts of "%s" for serial "%s" to directory "%s", because directory already exists',
176
                    $archiveFile,
177
                    $serial,
178
                    $sourceDir
179
                )
180
            );
181
182
            // stop prcessing the file extraction of the ZIP file
183
            return;
184
        }
185
186
        // try to open and extract the ZIP archive
187
        if (is_file($archiveFile)) {
188
            if ($zip->open($archiveFile) === true) {
189
                $zip->extractTo($sourceDir);
190
                $zip->close();
191
            } else {
192
                throw new \Exception(sprintf('Can\'t extract archive "%s" back into source directory', $archiveFile));
193
            }
194
        } else {
195
            $this->getSystemLogger()->debug(sprintf('"%s" is not available and can not be extracted therefore', $archiveFile));
196
        }
197
198
        // log a message that the file has successfully been extracted
199
        $this->getSystemLogger()->info(sprintf('Successfully extracted artefacts for serial "%s" to directory', $serial, $sourceDir));
200
    }
201
202
    /**
203
     * The method to create the debugging artefacts in the apropriate directory.
204
     *
205
     * @param string $serial The serial to prepare the dump for
206
     *
207
     * @return void
208
     * @throws \Exception Is thrown, if the configuration can not be dumped
209
     */
210 View Code Duplication
    public function prepareDump(string $serial) : void
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...
211
    {
212
213
        // load the actual status
214
        $status = $this->getRegistryProcessor()->getAttribute(RegistryKeys::STATUS);
215
216
        // clear the filecache
217
        clearstatcache();
218
219
        // query whether or not the configured source directory is available
220
        if (!is_dir($sourceDir = $status[RegistryKeys::SOURCE_DIRECTORY])) {
221
            throw new \Exception(sprintf('Configured source directory %s is not available!', $sourceDir));
222
        }
223
224
        // render the debug artefacts
225
        $this->getRenderer()->render($serial);
0 ignored issues
show
Unused Code introduced by
The call to RendererInterface::render() has too many arguments starting with $serial.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
226
227
        // log a message that the debug artefacts has successfully been rendered
228
        $this->getSystemLogger()->info(sprintf('Successfully rendered the debug artefacts for serial "%s"', $serial));
229
    }
230
231
    /**
232
     * The method to create the debug dump with all artefacts and reports.
233
     *
234
     * @param string $serial The serial to create the dump for
235
     *
236
     * @return string $filename The name of the dumpfile
237
     * @throws \InvalidArgumentException Is thrown, if the passed serial has no matching import to create the dump for
238
     */
239
    public function createDump(string $serial) : string
240
    {
241
242
        // initialize the dump filename
243
        $dumpFile = null;
0 ignored issues
show
Unused Code introduced by
$dumpFile is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
244
245
        // load the actual status
246
        $status = $this->getRegistryProcessor()->getAttribute(RegistryKeys::STATUS);
247
248
        // clear the filecache
249
        clearstatcache();
250
251
        // query whether or not the configured source directory is available
252
        if (!is_dir($sourceDir = $status[RegistryKeys::SOURCE_DIRECTORY])) {
253
            throw new \Exception(sprintf('Configured source directory %s is not available!', $sourceDir));
254
        }
255
256
        // create the ZIP archive
257
        $dumpFile = new \ZipArchive();
258
        $dumpFile->open($dumpFilename = sprintf('%s/%s.zip', sys_get_temp_dir(), $serial), \ZipArchive::CREATE);
259
260
        // init file iterator on source directory
261
        $fileIterator = new \FilesystemIterator($sourceDir);
262
263
        // iterate through all files and add them to the ZIP archive
264
        /** @var \SplFileInfo $filename */
265
        foreach ($fileIterator as $filename) {
266
            if ($filename->isFile()) {
267
                $dumpFile->addFile($filename, basename($filename));
268
            }
269
        }
270
271
        // save the ZIP archive
272
        $dumpFile->close();
273
274
        // log a message that the dump has succesfully been created
275
        $this->getSystemLogger()->info(sprintf('Successfully created dump "%s" with artefacts for serial "%s"', $dumpFilename, $serial));
276
277
        // return the filename of the dump
278
        return $dumpFilename;
279
    }
280
}
281