Completed
Push — master ( d07a45...da6ba5 )
by
unknown
02:06
created

src/Plugins/MissingOptionValuesPlugin.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * TechDivision\Import\Plugins\MissingOptionValuesPlugin
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\ColumnKeys;
24
use TechDivision\Import\Utils\RegistryKeys;
25
use TechDivision\Import\Utils\SwiftMailerKeys;
26
use TechDivision\Import\ApplicationInterface;
27
use TechDivision\Import\Adapter\ExportAdapterInterface;
28
29
/**
30
 * Plugin that exports the missing option values to a CSV file.
31
 *
32
 * @author    Tim Wagner <[email protected]>
33
 * @copyright 2016 TechDivision GmbH <[email protected]>
34
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
35
 * @link      https://github.com/techdivision/import
36
 * @link      http://www.techdivision.com
37
 */
38
class MissingOptionValuesPlugin extends AbstractPlugin
39
{
40
41
    /**
42
     * The artefact type.
43
     *
44
     * @var string
45
     */
46
    const ARTEFACT_TYPE = 'missing-option-values';
47
48
    /**
49
     * The trait providing the export functionality.
50
     *
51
     * @var \TechDivision\Import\Plugins\ExportableTrait
52
     */
53
    use ExportableTrait;
54
55
    /**
56
     * The array containing the data for product type configuration (configurables, bundles, etc).
57
     *
58
     * @var array
59
     */
60
    protected $artefacts = array();
61
62
    /**
63
     * Initializes the plugin with the application instance.
64
     *
65
     * @param \TechDivision\Import\ApplicationInterface           $application   The application instance
66
     * @param \TechDivision\Import\Adapter\ExportAdapterInterface $exportAdapter The export adapter instance
67
     */
68
    public function __construct(ApplicationInterface $application, ExportAdapterInterface $exportAdapter)
69
    {
70
71
        // pass the application to the parent constructor
72
        parent::__construct($application);
73
74
        // set the export adapter
75
        $this->exportAdapter = $exportAdapter;
76
    }
77
78
    /**
79
     * Queries whether or not debug mode is enabled or not, default is TRUE.
80
     *
81
     * @return boolean TRUE if debug mode is enabled, else FALSE
82
     */
83
    public function isDebugMode()
84
    {
85
        return $this->getConfiguration()->isDebugMode();
86
    }
87
88
    /**
89
     * Process the plugin functionality.
90
     *
91
     * @return void
92
     * @throws \Exception Is thrown, if the plugin can not be processed
93
     */
94
    public function process()
95
    {
96
97
        // query whether or not, the debug mode has been enabled
98
        if (!$this->getConfiguration()->isDebugMode()) {
99
            $this->getSystemLogger()->info('Debug mode is not enabled, missing option values will not be exported');
100
            return;
101
        }
102
103
        // clear the filecache
104
        clearstatcache();
105
106
        // load the actual status
107
        $status = $this->getRegistryProcessor()->getAttribute(RegistryKeys::STATUS);
108
109
        // query whether or not the configured source directory is available
110 View Code Duplication
        if (!is_dir($sourceDir = $status[RegistryKeys::SOURCE_DIRECTORY])) {
0 ignored issues
show
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...
111
            throw new \Exception(sprintf('Configured source directory %s is not available!', $sourceDir));
112
        }
113
114
        // load the array with the missing option values from the status
115
        $missingOptions = $status[RegistryKeys::MISSING_OPTION_VALUES];
116
117
        // if missing option values are found, return immediately
118
        if (sizeof($missingOptions) === 0) {
119
            $this->getSystemLogger()->info('Found no missing option values');
120
            return;
121
        }
122
123
        // initialize the array with the artefacts
124
        $artefacts = array();
125
126
        // prepare the artefacts
127
        foreach ($missingOptions as $attributeCode => $options) {
128
            foreach ($options as $value => $data) {
129
                list($counter, $skus) = $data;
130
                $artefacts[] = $this->newArtefact(
131
                    array(
132
                        ColumnKeys::STORE_VIEW_CODE   => null,
133
                        ColumnKeys::ATTRIBUTE_CODE    => $attributeCode,
134
                        ColumnKeys::ADMIN_STORE_VALUE => $value,
135
                        ColumnKeys::VALUE             => $value,
136
                        ColumnKeys::COUNTER           => $counter,
137
                        ColumnKeys::UNIQUE_IDENTIFIER => implode(',', array_keys($skus)),
138
                        ColumnKeys::SORT_ORDER        => null
139
                    )
140
                );
141
            }
142
        }
143
144
        // initialize a dummy last entity ID
145
        $this->setLastEntityId(0);
146
147
        // add the artefacts (missing option values) and export them as CSV file
148
        $this->addArtefacts(MissingOptionValuesPlugin::ARTEFACT_TYPE, $artefacts);
149
        $this->export(date('Ymd-His'), $counter = '01');
150
151
        // query whether or not a swift mailer has been registered
152
        if ($swiftMailer = $this->getSwiftMailer()) {
153
            // the swift mailer configuration
154
            $swiftMailerConfiguration = $this->getPluginConfiguration()->getSwiftMailer();
155
156
            // create the message with the CSV with the missing option values
157
            $message = $swiftMailer->createMessage()
158
                                   ->setSubject(sprintf('[%s] %s', $this->getSystemName(), $swiftMailerConfiguration->getParam(SwiftMailerKeys::SUBJECT)))
159
                                   ->setFrom($swiftMailerConfiguration->getParam(SwiftMailerKeys::FROM))
160
                                   ->setTo($to = $swiftMailerConfiguration->getParam(SwiftMailerKeys::TO))
161
                                   ->setBody('The attached CSV file(s) contains the missing attribute option values');
162
163
            // load the exported filenames
164
            $exportedFilenames = $this->getExportAdapter()->getExportedFilenames();
165
166
            // attach the CSV files with the missing option values
167
            foreach ($exportedFilenames as $filename) {
168
                $message->attach(\Swift_Attachment::fromPath($filename));
169
            }
170
171
            // initialize the array with the failed recipients
172
            $failedRecipients = array();
173
            $recipientsAccepted = 0;
174
175
            // send the mail
176
            $recipientsAccepted = $swiftMailer->send($message, $failedRecipients);
177
178
            // query whether or not all recipients have been accepted
179
            if (sizeof($failedRecipients) > 0) {
180
                $this->getSystemLogger()->error(sprintf('Can\'t send mail to %s', implode(', ', $failedRecipients)));
181
            }
182
183
            // if at least one recipient has been accepted
184
            if ($recipientsAccepted > 0) {
185
                // cast 'to' into an array if not already
186
                is_array($to) ? : $to = (array) $to;
187
                // remove the NOT accepted recipients
188
                $acceptedRecipients = array_diff($to, $failedRecipients);
189
190
                // log a message with the successfull receivers
191
                $this->getSystemLogger()->info(
192
                    sprintf(
193
                        'Mail successfully sent to %d recipient(s) (%s)',
194
                        $recipientsAccepted,
195
                        implode(', ', $acceptedRecipients)
196
                    )
197
                );
198
            }
199
        }
200
201
        // load the system loggers
202
        $systemLoggers = $this->getSystemLoggers();
203
204
        // and and log a message that the missing option values has been exported
205
        foreach ($systemLoggers as $systemLogger) {
206
            $systemLogger->error(
207
                sprintf(
208
                    'Exported missing option values to file %s!',
209
                    $filename
210
                )
211
            );
212
        }
213
    }
214
215
    /**
216
     * Return's the artefacts for post-processing.
217
     *
218
     * @return array The artefacts
219
     */
220
    public function getArtefacts()
221
    {
222
        return $this->artefacts;
223
    }
224
225
    /**
226
     * Reset the array with the artefacts to free the memory.
227
     *
228
     * @return void
229
     */
230
    public function resetArtefacts()
231
    {
232
        $this->artefacts = array();
233
    }
234
235
    /**
236
     * Add the passed product type artefacts to the product with the
237
     * last entity ID.
238
     *
239
     * @param string  $type      The artefact type, e. g. configurable
240
     * @param array   $artefacts The product type artefacts
241
     * @param boolean $override  Whether or not the artefacts for the actual entity ID has to be overwritten
242
     *
243
     * @return void
244
     * @uses \TechDivision\Import\Product\Subjects\BunchSubject::getLastEntityId()
245
     */
246 View Code Duplication
    public function addArtefacts($type, array $artefacts, $override = true)
247
    {
248
249
        // query whether or not, any artefacts are available
250
        if (sizeof($artefacts) === 0) {
251
            return;
252
        }
253
254
        // serialize the original data, if we're in debug mode
255
        $keys = array_keys($artefacts);
256
        foreach ($keys as $key) {
257
            if (isset($artefacts[$key][ColumnKeys::ORIGINAL_DATA])) {
258
                $artefacts[$key][ColumnKeys::ORIGINAL_DATA] = $this->isDebugMode() ? serialize($artefacts[$key][ColumnKeys::ORIGINAL_DATA]) : null;
259
            }
260
        }
261
262
        // query whether or not, existing artefacts has to be overwritten
263
        if ($override === true) {
264
            $this->overrideArtefacts($type, $artefacts);
265
        } else {
266
            $this->appendArtefacts($type, $artefacts);
267
        }
268
    }
269
270
    /**
271
     * Add the passed product type artefacts to the product with the
272
     * last entity ID and overrides existing ones with the same key.
273
     *
274
     * @param string $type      The artefact type, e. g. configurable
275
     * @param array  $artefacts The product type artefacts
276
     *
277
     * @return void
278
     */
279
    protected function overrideArtefacts($type, array $artefacts)
280
    {
281
        foreach ($artefacts as $key => $artefact) {
282
            $this->artefacts[$type][$this->getLastEntityId()][$key] = $artefact;
283
        }
284
    }
285
286
    /**
287
     * Append's the passed product type artefacts to the product with the
288
     * last entity ID.
289
     *
290
     * @param string $type      The artefact type, e. g. configurable
291
     * @param array  $artefacts The product type artefacts
292
     *
293
     * @return void
294
     */
295
    protected function appendArtefacts($type, array $artefacts)
296
    {
297
        foreach ($artefacts as $artefact) {
298
            $this->artefacts[$type][$this->getLastEntityId()][] = $artefact;
299
        }
300
    }
301
302
    /**
303
     * Return's the systemm name to be used.
304
     *
305
     * @return string The system name to be used
306
     */
307
    protected function getSystemName()
308
    {
309
        return $this->getConfiguration()->getSystemName();
310
    }
311
312
    /**
313
     * Return's the target directory the CSV files has to be exported to.
314
     *
315
     * @return string The name of the target directory
316
     */
317
    public function getTargetDir()
318
    {
319
320
        // load the actual status
321
        $status = $this->getRegistryProcessor()->getAttribute(RegistryKeys::STATUS);
322
323
        // query whether or not the configured source directory is available
324 View Code Duplication
        if (!is_dir($sourceDir = $status[RegistryKeys::SOURCE_DIRECTORY])) {
0 ignored issues
show
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...
325
            throw new \Exception(sprintf('Configured source directory %s is not available!', $sourceDir));
326
        }
327
328
        // return the source directory where we want to export to
329
        return $sourceDir;
330
    }
331
}
332