Completed
Pull Request — 1.1 (#3)
by Raphaël
02:40
created

ZohoDatabasePusher::insertDataZohoBean()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 10
Ratio 100 %

Importance

Changes 1
Bugs 1 Features 1
Metric Value
c 1
b 1
f 1
dl 10
loc 10
rs 8.8571
cc 5
eloc 6
nc 3
nop 3
1
<?php
2
3
namespace Wabel\Zoho\CRM\Copy;
4
5
use Doctrine\DBAL\Connection;
6
use Psr\Log\LoggerInterface;
7
use Psr\Log\NullLogger;
8
use Wabel\Zoho\CRM\AbstractZohoDao;
9
use Wabel\Zoho\CRM\ZohoBeanInterface;
10
11
/**
12
 * Description of ZohoDatabasePusher
13
 *
14
 * @author rbergina
15
 */
16
class ZohoDatabasePusher
17
{
18
19
    /**
20
     * @var Connection
21
     */
22
    private $connection;
23
24
    /**
25
     * @var LoggerInterface
26
     */
27
    private $logger;
28
29
    /**
30
     *
31
     * @var string
32
     */
33
    private $prefix;
34
35
    /**
36
     * @param Connection $connection
37
     * @param string $prefix
38
     * @param LoggerInterface $logger
39
     */
40
    public function __construct(Connection $connection, $prefix = 'zoho_', LoggerInterface $logger = null)
41
    {
42
        $this->connection = $connection;
43
        $this->prefix = $prefix;
44
        if ($logger === null) {
45
            $this->logger = new NullLogger();
46
        } else {
47
            $this->logger = $logger;
48
        }
49
    }
50
51
    /**
52
     *
53
     * @param AbstractZohoDao $zohoDao
54
     * @return array
55
     */
56
    private function findMethodValues(AbstractZohoDao $zohoDao){
57
        $fieldsMatching = array();
58
        foreach ($zohoDao->getFields() as $fieldsDescriptor) {
0 ignored issues
show
Bug introduced by
The method getFields() cannot be called from this context as it is declared protected in class Wabel\Zoho\CRM\AbstractZohoDao.

This check looks for access to methods that are not accessible from the current context.

If you need to make a method accessible to another context you can raise its visibility level in the defining class.

Loading history...
59
            foreach (array_values($fieldsDescriptor) as $fieldDescriptor) {
60
                $fieldsMatching[$fieldDescriptor['name']] = [
61
                    'setter' => $fieldDescriptor['setter'],
62
                    'type' => $fieldDescriptor['type']
63
                ];
64
            }
65
66
        }
67
        return $fieldsMatching;
68
    }
69
70
    /**
71
     * Insert or Update rows.
72
     * @param AbstractZohoDao $zohoDao
73
     * @param string $localTable
0 ignored issues
show
Bug introduced by
There is no parameter named $localTable. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
74
     */
75
    public function pushDataToZoho(AbstractZohoDao $zohoDao, $update = false){
76
        $localTable = $update ? 'local_update' : 'local_insert';
77
        $fieldsMatching = $this->findMethodValues($zohoDao);
78
        $tableName = ZohoDatabaseHelper::getTableName($zohoDao,$this->prefix);
79
        $rowsDeleted = [];
80
        $statement = $this->connection->createQueryBuilder();
81
        $statement->select('zcrm.*');
82
        if($update){
83
            $statement->addSelect('l.field_name as updated_fieldname');
84
        }
85
        $statement->from($localTable, 'l')
86
        ->join('l', $tableName, 'zcrm', 'zcrm.uid = l.uid')
87
        ->where('l.table_name=:table_name')
88
        ->setParameters([
89
            'table_name' => $tableName
90
        ]);
91
        $results = $statement->execute();
92
        /* @var $zohoBeans ZohoBeanInterface[] */
93
        $zohoBeans = array();
94
        while ($row = $results->fetch()) {
95
            $beanClassName = $zohoDao->getBeanClassName();
0 ignored issues
show
Bug introduced by
The method getBeanClassName() cannot be called from this context as it is declared protected in class Wabel\Zoho\CRM\AbstractZohoDao.

This check looks for access to methods that are not accessible from the current context.

If you need to make a method accessible to another context you can raise its visibility level in the defining class.

Loading history...
96
            /* @var $zohoBean ZohoBeanInterface */
97
            if(isset($zohoBeans[$row['uid']])){
98
                $zohoBean = $zohoBeans[$row['uid']];
99
            }else{
100
                $zohoBean = new $beanClassName();
101
            }
102
 
103
            if(!$update){
104
                $this->insertDataZohoBean($zohoBean, $fieldsMatching, $row);
105
                $zohoBeans[$row['uid']] =  $zohoBean;
106
                $rowsDeleted[] = $row['uid'];
107
            }
108
            if($update && isset($row['updated_fieldname'])){
109
               $columnName = $row['updated_fieldname'];
110
               $zohoBean->getZohoId()?:$zohoBean->setZohoId($row['id']);
111
               $this->updateDataZohoBean($zohoBean, $fieldsMatching, $columnName, $row[$columnName]);
112
               $zohoBeans[$row['uid']] = $zohoBean;
113
               $rowsDeleted[] = $row['uid'];
114
            }
115
        }
116
        $zohoDao->save($zohoBeans);
117
        if(!$update){
118
            foreach ($zohoBeans as $uid => $zohoBean) {
119
                $this->connection->update($tableName, [ 'id'=>$zohoBean->getZohoId() ], ['uid'=>$uid ]);
120
            }
121
        }
122
        $this->connection->executeUpdate('delete from '.$localTable.' where uid in ( :rowsDeleted)',
0 ignored issues
show
Security introduced by
If $localTable can contain user-input, it is usually preferable to use a parameter placeholder like :paramName and pass the dynamic input as second argument array('param' => $localTable).

Instead of embedding dynamic parameters in SQL, Doctrine also allows you to pass them separately and insert a placeholder instead:

function findUser(Doctrine\DBAL\Connection $con, $email) {
    // Unsafe
    $con->executeQuery("SELECT * FROM users WHERE email = '".$email."'");

    // Safe
    $con->executeQuery(
        "SELECT * FROM users WHERE email = :email",
        array('email' => $email)
    );
}
Loading history...
123
            [
124
            'rowsDeleted' => $rowsDeleted
125
            ],
126
            [
127
            'rowsDeleted' => Connection::PARAM_INT_ARRAY
128
            ]
129
        );
130
    }
131
132
    /**
133
     * Insert data to bean in order to insert zoho records.
134
     * @param ZohoBeanInterface $zohoBean
135
     * @param array $fieldsMatching
136
     * @param array $row
137
     */
138 View Code Duplication
    private function insertDataZohoBean(ZohoBeanInterface $zohoBean, array $fieldsMatching, array $row)
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...
139
    {
140
        foreach ($row as $columnName => $columnValue) {
141
            if ((!in_array($columnName, ['id', 'uid']) || isset($fieldsMatching[$columnName])) && !is_null($columnValue)) {
142
                $type = $fieldsMatching[$columnName]['type'];
143
                $value = $this->formatValueToBeans($type, $columnValue);
144
                $zohoBean->{$fieldsMatching[$columnName]['setter']}($value);
145
            }
146
        }
147
    }
148
149
    /**
150
     * Insert data to bean in order to update zoho records.
151
     * @param ZohoBeanInterface $zohoBean
152
     * @param array $fieldsMatching
153
     * @param type $columnName
154
     * @param type $valueDb
155
     */
156 View Code Duplication
    private function updateDataZohoBean(ZohoBeanInterface $zohoBean, array $fieldsMatching, $columnName, $valueDb){
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...
157
        if (!in_array($columnName,['id','uid']) || (isset($fieldsMatching[$columnName]))) {
158
            $type = $fieldsMatching[$columnName]['type'];
159
            $value = is_null($valueDb)?$valueDb:$this->formatValueToBeans($type, $valueDb);
160
            $zohoBean->{$fieldsMatching[$columnName]['setter']}($value);
161
        }
162
    }
163
164
    /**
165
     * Change the value to the good format.
166
     * @param string $type
167
     * @param mixed $value
168
     * @return mixed
169
     */
170
    private function formatValueToBeans($type ,$value)
171
    {
172
        switch ($type) {
173
            case 'Date':
174
                $value = \DateTime::createFromFormat('Y-m-d', $value);
175
                break;
176
            case 'DateTime':
177
                $value = \DateTime::createFromFormat('Y-m-d H:i:s', $value);
178
                break;
179
        }
180
        return $value;
181
    }
182
183
    /**
184
     * Run deleted rows to Zoho : local_delete.
185
     * @param AbstractZohoDao $zohoDao
186
     */
187
    public function pushDeletedRows(AbstractZohoDao $zohoDao){
188
        $localTable = 'local_delete';
189
        $tableName = ZohoDatabaseHelper::getTableName($zohoDao,$this->prefix);
190
        $statement = $this->connection->createQueryBuilder();
191
        $statement->select('l.id')
192
        ->from($localTable, 'l')
193
        ->where('l.table_name=:table_name')
194
        ->setParameters([
195
            'table_name' => $tableName
196
        ]);
197
        $results = $statement->execute();
198
        while ($row = $results->fetch()) {
199
            $zohoDao->delete($row['id']);
200
            $this->connection->delete($localTable, ['table_name' => $tableName,'id' => $row['id']]);
201
        }
202
}
203
    
204
    /**
205
     * Run inserted rows to Zoho : local_insert.
206
     * @param AbstractZohoDao $zohoDao
207
     */
208
    public function pushInsertedRows(AbstractZohoDao $zohoDao){
209
        return $this->pushDataToZoho($zohoDao);
210
    }
211
212
    /**
213
     * Run updated rows to Zoho : local_update.
214
     * @param AbstractZohoDao $zohoDao
215
     */
216
    public function pushUpdatedRows(AbstractZohoDao $zohoDao){
217
        $this->pushDataToZoho($zohoDao,true);
218
    }
219
220
    /**
221
     * Push data from db to Zoho.
222
     * @param AbstractZohoDao $zohoDao
223
     */
224
    public function pushToZoho(AbstractZohoDao $zohoDao)
225
    {
226
        $this->logger->info(' > Insert new rows using {class_name}', ['class_name'=>get_class($zohoDao)]);
227
        $this->pushInsertedRows($zohoDao);
228
        $this->logger->info(' > Update rows using {class_name}', ['class_name'=>get_class($zohoDao)]);
229
        $this->pushUpdatedRows($zohoDao);
230
        $this->logger->info(' > Delete rows using  {class_name}', ['class_name'=>get_class($zohoDao)]);
231
        $this->pushDeletedRows($zohoDao);
232
    }
233
234
    /**
235
     * @param LoggerInterface $logger
236
     */
237
    public function setLogger(LoggerInterface $logger)
238
    {
239
        $this->logger = $logger;
240
    }
241
242
243
}