Completed
Push — 15.x ( 1a7f4e...53b7d0 )
by Tim
65:00 queued 61:58
created

SubjectPlugin   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 166
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Test Coverage

Coverage 60%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 11
dl 0
loc 166
rs 10
c 0
b 0
f 0
ccs 27
cts 45
cp 0.6

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 13 1
B process() 0 60 7
A processSubject() 0 34 2
1
<?php
2
3
/**
4
 * TechDivision\Import\Plugins\SubjectPlugin
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 2016 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\Plugins;
22
23
use TechDivision\Import\Utils\RegistryKeys;
24
use TechDivision\Import\ApplicationInterface;
25
use TechDivision\Import\Exceptions\MissingFilesException;
26
use TechDivision\Import\Exceptions\MissingOkFileException;
27
use TechDivision\Import\Subjects\SubjectExecutorInterface;
28
use TechDivision\Import\Subjects\FileResolver\FileResolverFactoryInterface;
29
use TechDivision\Import\Configuration\SubjectConfigurationInterface;
30
31
/**
32
 * Plugin that processes the subjects.
33
 *
34
 * @author    Tim Wagner <[email protected]>
35
 * @copyright 2016 TechDivision GmbH <[email protected]>
36
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
37
 * @link      https://github.com/techdivision/import
38
 * @link      http://www.techdivision.com
39
 */
40
class SubjectPlugin extends AbstractPlugin implements SubjectAwarePluginInterface
41
{
42
43
    /**
44
     * The matches for the last processed CSV filename.
45
     *
46
     * @var array
47
     */
48
    protected $matches = array();
49
50
    /**
51
     * The number of imported bunches.
52
     *
53
     * @var integer
54
     */
55
    protected $bunches = 0;
56
57
    /**
58
     * The subject executor instance.
59
     *
60
     * @var \TechDivision\Import\Subjects\SubjectExecutorInterface
61
     */
62
    protected $subjectExecutor;
63
64
    /**
65
     * The file resolver factory instance.
66
     *
67
     * @var \TechDivision\Import\Subjects\FileResolver\FileResolverFactoryInterface
68
     */
69
    protected $fileResolverFactory;
70
71
    /**
72
     * Initializes the plugin with the application instance.
73
     *
74
     * @param \TechDivision\Import\ApplicationInterface                               $application         The application instance
75
     * @param \TechDivision\Import\Subjects\SubjectExecutorInterface                  $subjectExecutor     The subject executor instance
76
     * @param \TechDivision\Import\Subjects\FileResolver\FileResolverFactoryInterface $fileResolverFactory The file resolver instance
77
     */
78 3
    public function __construct(
79
        ApplicationInterface $application,
80
        SubjectExecutorInterface $subjectExecutor,
81
        FileResolverFactoryInterface $fileResolverFactory
82
    ) {
83
84
        // call the parent constructor
85 3
        parent::__construct($application);
86
87
        // set the subject executor and the file resolver factory
88 3
        $this->subjectExecutor = $subjectExecutor;
89 3
        $this->fileResolverFactory = $fileResolverFactory;
90 3
    }
91
92
93
    /**
94
     * Process the plugin functionality.
95
     *
96
     * @return void
97
     * @throws \Exception Is thrown, if the plugin can not be processed
98
     */
99 1
    public function process()
100
    {
101
102
        try {
103
            // immediately add the PID to lock this import process
104 1
            $this->lock();
105
106
            // load the plugin's subjects
107 1
            $subjects = $this->getPluginConfiguration()->getSubjects();
108
109
            // initialize the array for the status
110 1
            $status = array();
111
112
            // initialize the status information for the subjects
113
            /** @var \TechDivision\Import\Configuration\SubjectConfigurationInterface $subject */
114 1
            foreach ($subjects as $subject) {
115
                $status[$subject->getPrefix()] = array();
116
            }
117
118
            // and update it in the registry
119 1
            $this->getRegistryProcessor()->mergeAttributesRecursive(RegistryKeys::STATUS, $status);
120
121
            // process all the subjects found in the system configuration
122
            /** @var \TechDivision\Import\Configuration\SubjectConfigurationInterface $subject */
123 1
            foreach ($subjects as $subject) {
124
                $this->processSubject($subject);
125
            }
126
127
            // update the number of imported bunches
128 1
            $this->getRegistryProcessor()->mergeAttributesRecursive(
129 1
                RegistryKeys::STATUS,
130 1
                array(RegistryKeys::BUNCHES => $this->bunches)
131
            );
132
133
            // stop the application, because we didn't process any file
134 1
            if ($this->bunches === 0) {
135 1
                throw new MissingFilesException(
136 1
                    sprintf(
137 1
                        'Operation %s has been stopped because no import files can be found in directory %s',
138 1
                        $this->getConfiguration()->getOperationName(),
139 1
                        $this->getConfiguration()->getSourceDir()
140
                    )
141
                );
142
            }
143
144 1
        } catch (MissingOkFileException $mofe) {
145
            // stop the application if we can't find the mandatory OK file
146
            $this->getApplication()->stop($mofe->getMessage());
147 1
        } catch (MissingFilesException $mfe) {
148
            // stop the application if can't find at least one file to process
149 1
            $this->getApplication()->stop($mfe->getMessage());
150
        } catch (\Exception $e) {
151
            // re-throw the exception
152
            throw $e;
153 1
        } finally {
154
            // finally, if a PID has been set, remove it
155
            // from the PID file to unlock the importer
156 1
            $this->unlock();
157
        }
158 1
    }
159
160
    /**
161
     * Process the subject with the passed name/identifier.
162
     *
163
     * We create a new, fresh and separate subject for EVERY file here, because this would be
164
     * the starting point to parallelize the import process in a multithreaded/multiprocessed
165
     * environment.
166
     *
167
     * @param \TechDivision\Import\Configuration\SubjectConfigurationInterface $subject The subject configuration
168
     *
169
     * @return void
170
     */
171
    protected function processSubject(SubjectConfigurationInterface $subject)
172
    {
173
174
        // initialize the bunch number
175
        $bunches = 0;
176
177
        // load the file resolver for the subject with the passed configuration
178
        $fileResolver = $this->fileResolverFactory->createFileResolver($subject);
179
180
        // load the files
181
        $files = $fileResolver->loadFiles($serial = $this->getSerial());
182
183
        // load the matches (must match the number of the found files)
184
        $matches = $fileResolver->getMatches();
185
186
        // iterate through all CSV files and process the subjects
187
        foreach ($files as $key => $filename) {
188
            // initialize the subject and import the bunch
189
            $this->subjectExecutor->execute($subject, $matches[$key], $serial, $filename);
190
            // raise the number of the imported bunches
191
            $bunches++;
192
        }
193
194
        // raise the bunch number by the imported bunches
195
        $this->bunches = $this->bunches + $bunches;
196
197
        // reset the file resolver for making it ready parsing the files of the next subject
198
        $fileResolver->reset();
199
200
        // and and log a message that the subject has been processed
201
        $this->getSystemLogger()->debug(
202
            sprintf('Successfully processed subject %s with %d bunches)!', $subject->getId(), $bunches)
203
        );
204
    }
205
}
206