Completed
Push — master ( b5c840...3d5461 )
by Marcus
04:46
created

ProposedOkFilenameLoader::removeLineFromFile()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
ccs 0
cts 4
cp 0
rs 10
cc 1
nc 1
nop 2
crap 2
1
<?php
2
3
/**
4
 * TechDivision\Import\Loaders\ProposedOkFilenameLoader
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
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Loaders;
22
23
use TechDivision\Import\Utils\BunchKeys;
24
use TechDivision\Import\Loaders\Sorters\UasortImpl;
25
use TechDivision\Import\Loaders\Filters\PregMatchFilter;
26
use TechDivision\Import\Loaders\Filters\FilterImplInterface;
27
use TechDivision\Import\Loaders\Sorters\SorterImplInterface;
28
use TechDivision\Import\Configuration\Subject\FileResolverConfigurationInterface;
29
30
/**
31
 * Loader implementation that loads a list of proposed .OK filenames and their
32
 * matching CSV files, based on the found CSV files that'll be loaded by the
33
 * passed loader instance.
34
 *
35
 * @author    Tim Wagner <[email protected]>
36
 * @copyright 2020 TechDivision GmbH <[email protected]>
37
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
38
 * @link      https://github.com/techdivision/import
39
 * @link      http://www.techdivision.com
40
 * @link      https://www.php.net/array_filter
41
 */
42
class ProposedOkFilenameLoader extends FilteredLoader implements FilteredLoaderInterface, SortedLoaderInterface
43
{
44
45
    /**
46
     * The regular expression used to load the files with.
47
     *
48
     * @var string
49
     */
50
    private $regex = '/^.*\/%s\\.%s$/';
51
52
    /**
53
     * The actual source directory to use.
54
     *
55
     * @var string
56
     */
57
    private $sourceDir;
58
59
    /**
60
     * The file resolver configuration instance.
61
     *
62
     * @var \TechDivision\Import\Configuration\Subject\FileResolverConfigurationInterface
63
     */
64
    private $fileResolverConfiguration;
65
66
    /**
67
     * The sorter instance to use.
68
     *
69
     * @var \TechDivision\Import\Loaders\Sorters\SorterImplInterface
70
     */
71
    private $sorterImpl;
72
73
    /**
74
     * Initializes the file handler instance.
75
     *
76
     * @param \TechDivision\Import\Loaders\FilteredLoaderInterface     $loader     The parent loader instance
77
     * @param \TechDivision\Import\Loaders\Filters\FilterImplInterface $filterImpl The filter instance to use
78
     * @param \TechDivision\Import\Loaders\Sorters\SorterImplInterface $sorterImpl The sorter instance to use
79
     */
80
    public function __construct(
81
        FilteredLoaderInterface $loader,
82
        FilterImplInterface $filterImpl = null,
83
        SorterImplInterface $sorterImpl = null
84
    ) {
85
86
        // initialize the sorter instance
87
        $this->sorterImpl = $sorterImpl ?? new UasortImpl();
88
89
        // pass parent loader and filter instance to the parent constructor
90
        parent::__construct($loader, $filterImpl);
91
    }
92
93
    /**
94
     * Returns the file resolver configuration instance.
95
     *
96
     * @return \TechDivision\Import\Configuration\Subject\FileResolverConfigurationInterface The configuration instance
97
     */
98
    protected function getFileResolverConfiguration() : FileResolverConfigurationInterface
99
    {
100
        return $this->fileResolverConfiguration;
101
    }
102
103
    /**
104
     * Return's the sorter instance to use.
105
     *
106
     * @return \TechDivision\Import\Loaders\Sorters\SorterImplInterface The sorter instance to use
107
     */
108
    protected function getSorterImpl() : SorterImplInterface
109
    {
110
        return $this->sorterImpl;
111
    }
112
113
    /**
114
     * Returns the regular expression used to load the files with.
115
     *
116
     * @return string The regular expression
117
     */
118
    protected function getRegex() : string
119
    {
120
        return $this->regex;
121
    }
122
123
    /**
124
     * Remove's the passed line from the file with the passed name.
125
     *
126
     * @param string $line     The line to be removed
127
     * @param string $filename The name of the file the line has to be removed
128
     *
129
     * @return void
130
     * @throws \Exception Is thrown, if the file doesn't exists, the line is not found or can not be removed
131
     */
132
    protected function removeLineFromFile(string $line, string $filename) : void
133
    {
134
        $this->getGenericFileHandler()->removeLineFromFile($line, $filename);
0 ignored issues
show
Bug introduced by
The method getGenericFileHandler() does not seem to exist on object<TechDivision\Impo...oposedOkFilenameLoader>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
135
    }
136
137
    /**
138
     * Query whether or not the basename, without suffix, of the passed filenames are equal.
139
     *
140
     * @param string $filename1 The first filename to compare
141
     * @param string $filename2 The second filename to compare
142
     *
143
     * @return boolean TRUE if the passed files basename are equal, else FALSE
144
     * @todo Refactorig required, because of duplicate method
145
     * @see \TechDivision\Import\Loaders\Filters\OkFileFilter::isEqualFilename()
146
     */
147
    protected function isEqualFilename(string $filename1, string $filename2) : bool
148
    {
149
        return $this->stripSuffix($filename1, $this->getSuffix()) === $this->stripSuffix($filename2, $this->getOkFileSuffix());
150
    }
151
152
    /**
153
     * Strips the passed suffix, including the (.), from the filename and returns it.
154
     *
155
     * @param string $filename The filename to return the suffix from
156
     * @param string $suffix   The suffix to return
157
     *
158
     * @return string The filname without the suffix
159
     * @todo Refactorig required, because of duplicate method
160
     * @see \TechDivision\Import\Loaders\Filters\OkFileFilter::stripSuffix()
161
     */
162
    protected function stripSuffix(string $filename, string $suffix) : string
163
    {
164
        return basename($filename, sprintf('.%s', $suffix));
165
    }
166
167
    /**
168
     * Prepares and returns an OK filename from the passed parts.
169
     *
170
     * @param array $parts The parts to concatenate the OK filename from
171
     *
172
     * @return string The OK filename
173
     * @todo Refactorig required, because of duplicate method
174
     * @see \TechDivision\Import\Loaders\Filters\OkFileFilter::prepareOkFilename()
175
     */
176
    protected function prepareOkFilename(array $parts) : string
177
    {
178
        return sprintf('%s/%s.%s', $this->getSourceDir(), implode($this->getElementSeparator(), $parts), $this->getOkFileSuffix());
179
    }
180
181
    /**
182
     * Returns the delement separator char.
183
     *
184
     *  @return string The element separator char
185
     */
186
    protected function getElementSeparator() : string
187
    {
188
        return $this->getFileResolverConfiguration()->getElementSeparator();
189
    }
190
191
    /**
192
     * Returns the elements the filenames consists of.
193
     *
194
     * @return array The array with the filename elements
195
     * @todo Refactorig required, because of duplicate method
196
     * @see \TechDivision\Import\Loaders\Filters\OkFileFilter::getPatternElements()
197
     */
198
    protected function getPatternElements() : array
199
    {
200
        return $this->getFileResolverConfiguration()->getPatternElements();
201
    }
202
203
    /**
204
     * Returns the suffix for the import files.
205
     *
206
     * @return string The suffix
207
     */
208
    protected function getSuffix() : string
209
    {
210
        return $this->getFileResolverConfiguration()->getSuffix();
211
    }
212
213
    /**
214
     * Returns the elements the filenames consists of.
215
     *
216
     * @return array The array with the filename elements
217
     * @todo Refactorig required, because of duplicate method
218
     * @see \TechDivision\Import\Loaders\Filters\OkFileFilter::getOkFileSuffix()
219
     */
220
    protected function getOkFileSuffix() : string
221
    {
222
        return $this->getFileResolverConfiguration()->getOkFileSuffix();
223
    }
224
225
    /**
226
     * Returns the actual source directory to load the files from.
227
     *
228
     * @return string The actual source directory
229
     */
230
    protected function getSourceDir() : string
231
    {
232
        return $this->sourceDir;
233
    }
234
235
    /**
236
     * Returns the elements the filenames consists of, converted to lowercase.
237
     *
238
     * @return array The array with the filename elements
239
     * @todo Refactorig required, because of duplicate method
240
     * @see \TechDivision\Import\Loaders\Filters\OkFileFilter::getPatternKeys()
241
     */
242
    protected function getPatternKeys() : array
243
    {
244
245
        // load the pattern keys from the configuration
246
        $patternKeys = $this->getPatternElements();
247
248
        // make sure that they are all lowercase
249
        array_walk($patternKeys, function (&$value) {
250
            $value = strtolower($value);
251
        });
252
253
        // return the pattern keys
254
        return $patternKeys;
255
    }
256
257
    /**
258
     * Resolves the pattern value for the given element name.
259
     *
260
     * @param string $element The element name to resolve the pattern value for
261
     *
262
     * @return string The resolved pattern value
263
     * @throws \InvalidArgumentException Is thrown, if the element value can not be loaded from the file resolver configuration
264
     * @todo Refactorig required, because of duplicate method
265
     * @see \TechDivision\Import\Loaders\Filters\OkFileFilter::resolvePatternValue()
266
     */
267 View Code Duplication
    protected function resolvePatternValue(string $element) : string
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...
268
    {
269
270
        // query whether or not matches has been found OR the counter element has been passed
271
        if ($this->getLoader()->countMatches() === 0 || BunchKeys::COUNTER === $element) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface TechDivision\Import\Loaders\LoaderInterface as the method countMatches() does only exist in the following implementations of said interface: TechDivision\Import\Load...PregMatchFilteredLoader.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
272
            // prepare the method name for the callback to load the pattern value with
273
            $methodName = sprintf('get%s', ucfirst($element));
274
275
            // load the pattern value
276
            if (in_array($methodName, get_class_methods($this->getFileResolverConfiguration()))) {
277
                return call_user_func(array($this->getFileResolverConfiguration(), $methodName));
278
            }
279
280
            // stop processing and throw an exception
281
            throw new \InvalidArgumentException('Can\'t load pattern value for element "%s" from file resolver configuration', $element);
282
        }
283
284
        // try to load the pattern value from the matches
285
        return $this->getLoader()->getMatch($element);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface TechDivision\Import\Loaders\LoaderInterface as the method getMatch() does only exist in the following implementations of said interface: TechDivision\Import\Load...PregMatchFilteredLoader.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
286
    }
287
288
    /**
289
     * Returns the values to create the regex pattern from.
290
     *
291
     * @return array The array with the pattern values
292
     * @todo Refactorig required, because of duplicate method
293
     * @see \TechDivision\Import\Loaders\Filters\OkFileFilter::resolvePatternValues()
294
     */
295 View Code Duplication
    protected function resolvePatternValues() : array
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...
296
    {
297
298
        // initialize the array
299
        $elements = array();
300
301
        // prepare the pattern values
302
        foreach ($this->getPatternKeys() as $element) {
303
            $elements[] = sprintf('(?<%s>%s)', $element, $this->resolvePatternValue($element));
304
        }
305
306
        // return the pattern values
307
        return $elements;
308
    }
309
310
    /**
311
     * Prepares and returns the pattern for the regex to load the files from the
312
     * source directory for the passed subject.
313
     *
314
     * @return string The prepared regex pattern
315
     */
316
    protected function getPattern() : string
317
    {
318
        return sprintf(
319
            $this->getRegex(),
320
            implode($this->getElementSeparator(), $this->resolvePatternValues()),
321
            $this->getSuffix()
322
        );
323
    }
324
325
    /**
326
     * Returns the match with the passed name.
327
     *
328
     * @param array $keys The keys of the match to return
329
     *
330
     * @return string|null The match itself
331
     */
332
    protected function proposedOkFilenamesByKeys(array $keys) : array
333
    {
334
335
        // intialize the array for the .OK filename => .CSV filenames
336
        $result = array();
337
338
        // load the matches from the preg match filesystem loader
339
        $matches = $this->getLoader()->getMatches();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface TechDivision\Import\Loaders\LoaderInterface as the method getMatches() does only exist in the following implementations of said interface: TechDivision\Import\Load...PregMatchFilteredLoader.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
340
341
        // process the matches
342
        foreach ($matches as $i => $match) {
343
            // initialize the array for the values of the match elements
344
            $elements = array();
345
            // load the values from the matches
346
            foreach ($keys as $key) {
347
                if (array_key_exists($key, $match)) {
348
                    $elements[$i][] = $match[$key];
349
                }
350
            }
351
352
            // use the values to create the proposed .OK filenames
353
            foreach ($elements as $element) {
354
                // load the source directory
355
                $sourceDir = dirname($csvPath = $match[0]);
356
                // create the filename by concatenating the element values
357
                $okFilename = implode($this->getElementSeparator(), $element);
358
                // create the path to the .OK file
359
                $okPath = sprintf('%s/%s.%s', $sourceDir, $okFilename, $this->getOkFileSuffix());
360
                // register the proposed .OK file in the array
361
                $result[$okPath][] = basename($csvPath);
362
            }
363
        }
364
365
        // return the array with the result
366
        return $result;
367
    }
368
369
    /**
370
     * Return's an array with the proposed .OK filenames as key and the matching CSV
371
     * files as values for the import with the passed serial.
372
     *
373
     * Based on the passed serial, the files with the configured prefix from the also
374
     * configured source directory will be loaded and processed to return the array
375
     * with the proposed .OK filenames.
376
     *
377
     * @return array The array with key => value pairs of the proposed .OK and the matching CSV files
378
     */
379
    protected function propsedOkFilenames() : array
380
    {
381
382
        // initialize the array for the available okFilenames
383
        $okFilenames = array();
384
385
        // load the pattern keys (prefix, filename and suffix),
386
        // that has to be used from the configuration
387
        $patternKeys = $this->getPatternKeys();
388
389
        // prepare the .OK filenames based on the found CSV file information
390 View Code Duplication
        for ($i = 1; $i <= sizeof($patternKeys); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function sizeof() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
Duplication introduced by
This code seems to be duplicated across 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...
391
            // initialize the array for the pattern that has to used to load
392
            // the propsed .OK file for
393
            $keys = array();
394
            // load the parts from the matches
395
            for ($z = 0; $z < $i; $z++) {
396
                $keys[] = $patternKeys[$z];
397
            }
398
            // merge the proposed .OK filenames for the passed keys into the array
399
            $okFilenames = array_merge_recursive($okFilenames, $this->proposedOkFilenamesByKeys($keys));
400
        }
401
402
        // prepare and return the pattern for the OK file
403
        return $okFilenames;
404
    }
405
406
    /**
407
     * Return's the actual source directory.
408
     *
409
     * @param string $sourceDir The actual source directory
410
     *
411
     * @return void
412
     */
413
    public function setSourceDir(string $sourceDir) : void
414
    {
415
        $this->sourceDir = $sourceDir;
416
    }
417
418
    /**
419
     * Add's the passed sorter to the loader instance.
420
     *
421
     * @param callable $sorter The sorter to add
422
     *
423
     * @return void
424
     */
425
    public function addSorter(callable $sorter) : void
426
    {
427
        $this->getSorterImpl()->addSorter($sorter);
428
    }
429
430
    /**
431
     * Return's the array with the sorter callbacks.
432
     *
433
     * @return callable[] The sorter callbacks
434
     */
435
    public function getSorters() : array
436
    {
437
        return $this->getSorterImpl()->getSorters();
438
    }
439
440
    /**
441
     * Set's the file resolver configuration.
442
     *
443
     * @param \TechDivision\Import\Configuration\Subject\FileResolverConfigurationInterface $fileResolverConfiguration The file resolver configuration
444
     *
445
     * @return void
446
     */
447
    public function setFileResolverConfiguration(FileResolverConfigurationInterface $fileResolverConfiguration) : void
448
    {
449
        $this->fileResolverConfiguration = $fileResolverConfiguration;
450
    }
451
452
    /**
453
     * Loads, sorts and returns the files by using the passed glob pattern.
454
     *
455
     * If no pattern will be passed to the `load()` method, the files of
456
     * the actual directory using `getcwd()` will be returned.
457
     *
458
     * @param string|null $pattern The pattern to load the files from the filesystem
459
     *
460
     * @return array The array with the data
461
     */
462
    public function load(string $pattern = null) : array
463
    {
464
465
        // load the pattern to filter the available CSV files with. We filter
466
        // the .CSV files to only get those that matches the prefix.
467
        $this->getLoader()->addFilter(new PregMatchFilter($this->getPattern()));
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface TechDivision\Import\Loaders\LoaderInterface as the method addFilter() does only exist in the following implementations of said interface: TechDivision\Import\Loaders\FilteredLoader, TechDivision\Import\Load...PregMatchFilteredLoader, TechDivision\Import\Load...roposedOkFilenameLoader.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
468
469
        // load the available CSV files and initialize the matches that
470
        // we need to create the list with the proposed .OK files
471
        $this->getLoader()->load($pattern);
0 ignored issues
show
Unused Code introduced by
The call to LoaderInterface::load() has too many arguments starting with $pattern.

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...
472
473
        // initialize the array for the available okFilenames
474
        $okFilenames = array();
475
476
        // load the pattern keys (prefix, filename and suffix),
477
        // that has to be used from the configuration
478
        $patternKeys = $this->getPatternKeys();
479
480
        // prepare the .OK filenames based on the found CSV file information
481 View Code Duplication
        for ($i = 1; $i <= sizeof($patternKeys); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function sizeof() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
Duplication introduced by
This code seems to be duplicated across 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...
482
            // initialize the array for the pattern that has to used to load
483
            // the propsed .OK file for
484
            $keys = array();
485
            // load the parts from the matches
486
            for ($z = 0; $z < $i; $z++) {
487
                $keys[] = $patternKeys[$z];
488
            }
489
            // merge the proposed .OK filenames for the passed keys into the array
490
            $okFilenames = array_merge_recursive($okFilenames, $this->proposedOkFilenamesByKeys($keys));
491
        }
492
493
        // finally, we filter and sort them with the configured behaviour
494
        $this->getFilterImpl()->filter($okFilenames);
495
        $this->getSorterImpl()->sort($okFilenames);
496
497
        // prepare and return the pattern for the OK file
498
        return $okFilenames;
499
    }
500
}
501