Completed
Push — master ( 36506d...dd98a7 )
by diego
04:15
created

Classes/Service/Targets/InsertUpdateTable.php (1 issue)

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
namespace HDNET\Importr\Service\Targets;
3
4
use HDNET\Importr\Domain\Model\Strategy;
5
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
6
use HDNET\Importr\Utility;
7
8
/**
9
 * Imports records from a .CSV file into the target table which you
10
 * can specify on the target section in your strategy.
11
 * If a record does not exist in the table, it will be inserted,
12
 * otherwise it will be just updated. No duplicates are created.
13
 *
14
 * complete example (strategy target):
15
 *
16
 * HDNET\Importr\Service\Targets\InsertUpdateTable:
17
 *   target_table: fe_users
18
 *   exclude_from_update:
19
 *     0: password
20
 *     1: first_name
21
 *     2: zip
22
 *   pid: 324
23
 *   identifier: username
24
 *   mapping:
25
 *     0: username
26
 *     1: password
27
 *     2: usergroup
28
 *     3: name
29
 *     4: first_name
30
 *     5: address
31
 *     6: telephone
32
 *     7: email
33
 *     8: zip
34
 *     9: city
35
 *     10: company
36
 *
37
 * Example CSV:
38
 *
39
 * username;password;usergroup;name;first_name;address;telephone;email;zip;city;company
40
 * EduardFekete;PW123;3;Fekete;Eduard; Example 21; +049123456789;[email protected];91550;Feuchtwangen;MB Connect Line GmbH
41
 * HansVader;PW1234;3;Vader;Hans; Example 22; +049123456710;[email protected];99900;Universe;Hollywood Studios
42
 *
43
 * ------------------------------------------------------------------------------------------------
44
 *
45
 *   exclude_from_update:    the elements specified in this array, are never being updated
46
 *
47
 * ------------------------------------------------------------------------------------------------
48
 * @author Eduard Fekete
49
 */
50
class InsertUpdateTable extends DbRecord implements TargetInterface
51
{
52
    /**
53
     * @var int
54
     */
55
    protected $identifierField;
56
57
    /**
58
     * @param Strategy $strategy
59
     */
60
    public function start(Strategy $strategy)
61
    {
62
        parent::start($strategy);
63
        if (!isset($this->getConfiguration()['identifier'])) {
64
            throw new \RuntimeException('Identifier field is missing!');
65
        }
66
        $identifier = $this->getConfiguration()['identifier'];
67
        $identifierField = array_search($identifier, $this->getConfiguration()['mapping']);
68
        if ($identifierField === false) {
69
            throw new \RuntimeException('Identifier field not found in mapping.');
70
        }
71
        $this->identifierField = $identifierField;
72
    }
73
74
    /**
75
     * Process every entry in the .csv
76
     *
77
     * @param array $entry
78
     *
79
     * @return int|void
80
     */
81
    public function processEntry(array $entry)
82
    {
83
        $record_exists = false;
84
        $entry_identifier = $entry[$this->identifierField];
85
        $records = $this->getRecords("*");
86
        $fieldName = $this->getConfiguration()['mapping'][$this->identifierField];
87
88
        foreach ($records as $record) {
89
            if ($record['deleted'] == 0) {
90
                if ($record[$fieldName] == $entry_identifier) {
91
                    $record_exists = true;
92
                    break;
93
                }
94
            } else {
95
                continue;
96
            }
97
        }
98
99
        if ($record_exists) {
100
            $this->updateRecord($entry);
101
            return TargetInterface::RESULT_UPDATE;
102
        }
103
104
        $this->insertRecord($entry);
105
        return TargetInterface::RESULT_INSERT;
106
    }
107
108
    /**
109
     *
110
     * Fetch all records from the target table, where the PID equals the PID specified
111
     * in the target section of the strategy
112
     *
113
     * @param $selectFields
114
     * @return array
115
     */
116
    protected function getRecords($selectFields)
117
    {
118
        static $records = [];
119
        if ($records) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $records of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
120
            return $records;
121
        }
122
123
        $fromTable = $this->getConfiguration()['target_table'];
124
        $whereStatement = "pid = '" . $this->getConfiguration()['pid'] . "'";
125
126
        $records = Utility::getDatabaseConnection()->exec_SELECTgetRows(
127
            $selectFields,
128
            $fromTable,
129
            $whereStatement
130
        );
131
132
        return $records;
133
    }
134
135
    /**
136
     * Insert record into the target table which you have specified in the target section of the strategy
137
     *
138
     * @param array $entry
139
     *
140
     * @return void
141
     */
142
    protected function insertRecord(array $entry)
143
    {
144
        $field_values = [];
145
        $into_table = $this->getConfiguration()['target_table'];
146
147
        foreach ($this->getConfiguration()["mapping"] as $key => $value) {
148
            $field_values[$value] = $entry[$key];
149
        }
150
151
        $field_values['pid'] = $this->getConfiguration()['pid'];
152
        $time = time();
153
        $field_values['tstamp'] = $time;
154
        $field_values['crdate'] = $time;
155
156
        Utility::getDatabaseConnection()->exec_INSERTquery($into_table, $field_values);
157
    }
158
159
    /**
160
     * Update a record in the target table which you have specified in the
161
     * target section of the strategy (don't update the password)
162
     *
163
     * @param array $entry
164
     *
165
     * @return void
166
     */
167
    protected function updateRecord(array $entry)
168
    {
169
        $into_table = $this->getConfiguration()['target_table'];
170
        $fieldName = $this->getConfiguration()['mapping'][$this->identifierField];
171
        $whereStatement = "pid = '" . $this->getConfiguration()['pid'] . "' AND '" . $fieldName . "' = '" . $entry[$this->identifierField] . "'";
172
173
        $tmp_arr = [];
174
175
        foreach ($this->getConfiguration()["mapping"] as $key => $value) {
176
            $tmp_arr[$value] = $entry[$key];
177
        }
178
179
        $field_values = $this->duplicateArray($tmp_arr, $this->getConfiguration()['exclude_from_update']);
180
        $field_values['tstamp'] = time();
181
182
        Utility::getDatabaseConnection()->exec_UPDATEquery($into_table, $whereStatement, $field_values);
183
    }
184
185
    /**
186
     * This function creates a duplicate of a associative array and optionally removes
187
     * any entries which are also elements of a second array
188
     *
189
     * @param array $arr
190
     * @param array $exclude_arr
191
     *
192
     * @return array
193
     */
194
    protected function duplicateArray(array $arr, array $exclude_arr = null)
195
    {
196
        if (!is_array($exclude_arr)) {
197
            return $arr;
198
        }
199
200
        foreach ($arr as $key => $_) {
201
            if (in_array($key, $exclude_arr)) {
202
                unset($arr[$key]);
203
            }
204
        }
205
206
        return $arr;
207
    }
208
209
    /**
210
     *
211
     */
212
    public function end()
213
    {
214
        parent::end();
215
    }
216
}
217