Completed
Push — 3.0 ( 154001...3d6954 )
by Raphaël
08:06 queued 06:39
created

ZohoDatabaseModelSync::setLogger()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Wabel\Zoho\CRM\Copy;
4
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\Schema\Schema;
7
use Psr\Log\LoggerInterface;
8
use Psr\Log\NullLogger;
9
use Wabel\Zoho\CRM\AbstractZohoDao;
10
use Wabel\Zoho\CRM\Request\Response;
11
12
/**
13
 * This class is in charge of synchronizing one table MODEL with Zoho.
14
 */
15
class ZohoDatabaseModelSync
16
{
17
    /**
18
     * @var Connection
19
     */
20
    private $connection;
21
22
    private $prefix;
23
24
    /**
25
     * @var LoggerInterface
26
     */
27
    private $logger;
28
29
    /**
30
     * @var LocalChangesTracker
31
     */
32
    private $localChangesTracker;
33
    /**
34
     * @var ZohoUserService
35
     */
36
    private $zohoUserService;
37
38
    /**
39
     * ZohoDatabaseCopier constructor.
40
     *
41
     * @param Connection $connection
42
     * @param string     $prefix     Prefix for the table name in DB
43
     */
44 View Code Duplication
    public function __construct(Connection $connection, ZohoUserService $zohoUserService, $prefix = 'zoho_', LoggerInterface $logger = null)
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...
45
    {
46
        $this->connection = $connection;
47
        $this->prefix = $prefix;
48
        if ($logger === null) {
49
            $this->logger = new NullLogger();
50
        } else {
51
            $this->logger = $logger;
52
        }
53
        $this->localChangesTracker = new LocalChangesTracker($connection, $this->logger);
54
        $this->zohoUserService = $zohoUserService;
55
    }
56
57
    /**
58
     * @param LoggerInterface $logger
59
     */
60
    public function setLogger(LoggerInterface $logger)
61
    {
62
        $this->logger = $logger;
63
    }
64
65
    /**
66
     * Synchronizes the DB model with Zoho.
67
     *
68
     * @param AbstractZohoDao $dao
69
     * @param bool            $twoWaysSync
70
     * @param bool            $skipCreateTrigger
71
     *
72
     * @throws \Doctrine\DBAL\DBALException
73
     * @throws \Doctrine\DBAL\Schema\SchemaException
74
     */
75
    public function synchronizeDbModel(AbstractZohoDao $dao, $twoWaysSync, $skipCreateTrigger = false)
76
    {
77
        if ($twoWaysSync === true) {
78
            $this->localChangesTracker->createTrackingTables();
79
        }
80
81
        $tableName = ZohoDatabaseHelper::getTableName($dao, $this->prefix);
82
        $this->logger->info('Synchronizing DB Model for '.$tableName);
83
84
        $schema = new Schema();
85
        $table = $schema->createTable($tableName);
86
87
        //@Temporary fix to use Mysql5.7 not strict
88
        $table->addColumn('uid', 'string', ['length' => 36,'notnull'=>false]);
89
        $table->addColumn('id', 'string', ['length' => 100,'notnull'=>false]);
90
        $table->addUniqueIndex(['id']);
91
        $table->setPrimaryKey(['uid']);
92
93
        foreach ($dao->getFields() as $field) {
94
            $columnName = $field->getName();
95
            //It seems sometime we can have the same field twice in the list of fields from the API.
96
            if($table->hasColumn($columnName)) {
97
                continue;
98
            }
99
100
            $length = null;
101
            $index = false;
102
            $options = [];
103
            // Note: full list of types available here: https://www.zoho.com/crm/help/customization/custom-fields.html
104
            switch ($field->getType()) {
105 View Code Duplication
            case 'fileupload':
0 ignored issues
show
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...
106
                $type = 'string';
107
                $length = $field->getMaxlength() && $field->getMaxlength() > 0?$field->getMaxlength() : 255;
108
                break;
109 View Code Duplication
            case 'lookup':
0 ignored issues
show
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...
110
                $type = 'string';
111
                $length = $field->getMaxlength() && $field->getMaxlength() > 0?$field->getMaxlength() : 100;
112
                $index = true;
113
                break;
114
            case 'userlookup':
115 View Code Duplication
            case 'ownerlookup':
0 ignored issues
show
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...
116
                $type = 'string';
117
                $index = true;
118
                $length = $field->getMaxlength() && $field->getMaxlength() > 0?$field->getMaxlength() : 25;
119
                break;
120 View Code Duplication
            case 'formula':
0 ignored issues
show
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...
121
                // Note: a Formula can return any type, but we have no way to know which type it returns...
122
                $type = 'string';
123
                $length = $field->getMaxlength() && $field->getMaxlength() > 0?$field->getMaxlength() : 100;
124
                break;
125
            case 'datetime':
126
                $type = 'datetime';
127
                break;
128
            case 'date':
129
                $type = 'date';
130
                break;
131
            case 'boolean':
132
                $type = 'boolean';
133
                break;
134
            case 'textarea':
135
                $type = 'text';
136
                break;
137
            case 'bigint':
138
                $type = 'bigint';
139
                break;
140
            case 'phone':
141
            case 'text':
142
            case 'url':
143
            case 'email':
144
            case 'picklist':
145 View Code Duplication
            case 'website':
0 ignored issues
show
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...
146
                $type = 'string';
147
                $length = $field->getMaxlength() && $field->getMaxlength() > 0?$field->getMaxlength() : 255;
148
                break;
149
            case 'multiselectlookup':
150
            case 'multiuserlookup':
151
            case 'multiselectpicklist':
152
                $type = 'text';
153
                break;
154
            case 'percent':
155
                $type = 'integer';
156
                break;
157
            case 'double':
158
                $type = 'float';
159
                break;
160
            case 'autonumber':
161
            case 'integer':
162
                $type = 'integer';
163
                $length = $field->getMaxlength() && $field->getMaxlength() > 0?$field->getMaxlength() : 255;
164
                break;
165
            case 'currency':
166
            case 'decimal':
167
                $type = 'decimal';
168
                $options['scale'] = 2;
169
                break;
170
            case 'consent_lookup':
171
            case 'profileimage':
172
            case 'ALARM':
173
            case 'RRULE':
174
            case 'event_reminder':
175
                continue 2;
176
                    break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
177
            default:
178
                throw new \RuntimeException('Unknown type "'.$field->getType().'"');
179
            }
180
181
182
183
            if ($length) {
184
                $options['length'] = $length;
185
            }
186
187
            $options['notnull'] = false;
188
189
            $table->addColumn($columnName, $type, $options);
190
191
            if ($index) {
192
                $table->addIndex([$columnName]);
193
            }
194
        }
195
196
        $dbalTableDiffService = new DbalTableDiffService($this->connection, $this->logger);
197
        $hasChanges = $dbalTableDiffService->createOrUpdateTable($table);
198
        if ($hasChanges || !$skipCreateTrigger) {
199
            $this->localChangesTracker->createUuidInsertTrigger($table);
200
            if ($twoWaysSync) {
201
                $this->localChangesTracker->createInsertTrigger($table);
202
                $this->localChangesTracker->createDeleteTrigger($table);
203
                $this->localChangesTracker->createUpdateTrigger($table);
204
            }
205
        }
206
207
    }
208
209
    public function synchronizeUserDbModel()
210
    {
211
        $tableName = 'users';
212
        $schema = new Schema();
213
        $table = $schema->createTable($tableName);
214
215
        $table->addColumn('id', 'string', ['length' => 100,'notnull'=>false]);
216
        $table->setPrimaryKey(['id']);
217
        foreach (\ZCRMUser::$defaultKeys as $field) {
218
            if ($field === 'id') {
219
                continue;
220
            }
221
            $columnName = $field;
222
            $length = null;
223
            $index = false;
224
            switch ($field) {
225
            case 'zuid':
226
                $type = 'string';
227
                $length = 100;
228
                $index = true;
229
                break;
230
            case 'name':
231
            case 'email':
232
                $type = 'string';
233
                $length = 255;
234
                $index = true;
235
                break;
236
            case 'phone':
237
            case 'website':
238
                $type = 'text';
239
                break;
240
            default:
241
                $type = 'string';
242
                $length = 100;
243
            }
244
245
            $options = [];
246
247
            if ($length) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $length of type null|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
248
                $options['length'] = $length;
249
            }
250
251
            $options['notnull'] = false;
252
253
            $table->addColumn($columnName, $type, $options);
254
255
            if ($index) {
256
                $table->addIndex([$columnName]);
257
            }
258
        }
259
260
        $dbalTableDiffService = new DbalTableDiffService($this->connection, $this->logger);
261
        $dbalTableDiffService->createOrUpdateTable($table);
262
    }
263
}
264