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

ZohoDatabaseSyncZoho::pushDataToZoho()   C

Complexity

Conditions 13
Paths 52

Size

Total Lines 60
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 1 Features 1
Metric Value
c 6
b 1
f 1
dl 0
loc 60
rs 6.3453
cc 13
eloc 44
nc 52
nop 3

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
use Wabel\Zoho\CRM\Exception\ZohoCRMException;
11
use Wabel\Zoho\CRM\Exception\ZohoCRMResponseException;
12
use function Stringy\create as s;
13
14
/**
15
 * Description of ZohoDatabaseSyncZoho
16
 *
17
 * @author rbergina
18
 */
19
class ZohoDatabaseSyncZoho
20
{
21
22
    /**
23
     * @var Connection
24
     */
25
    private $connection;
26
27
    /**
28
     * @var LoggerInterface
29
     */
30
    private $logger;
31
32
    /**
33
     *
34
     * @var string
35
     */
36
    private $prefix;
37
38
    /**
39
     * @param Connection $connection
40
     * @param string $prefix
41
     * @param LoggerInterface $logger
42
     */
43
    public function __construct(Connection $connection, $prefix = 'zoho_', LoggerInterface $logger = null)
44
    {
45
        $this->connection = $connection;
46
        $this->prefix = $prefix;
47
        if ($logger === null) {
48
            $this->logger = new NullLogger();
49
        } else {
50
            $this->logger = $logger;
51
        }
52
    }
53
54
    /**
55
     *
56
     * @param AbstractZohoDao $zohoDao
57
     * @return array
58
     */
59
    private function findMethodValues(AbstractZohoDao $zohoDao){
60
        $fieldsMatching = array();
61
        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...
62
            foreach (array_values($fieldsDescriptor) as $fieldDescriptor) {
63
                $fieldsMatching[$fieldDescriptor['name']] = [
64
                    'setter' => $fieldDescriptor['setter'],
65
                    'type' => $fieldDescriptor['type']
66
                ];
67
            }
68
69
        }
70
        return $fieldsMatching;
71
    }
72
73
    /**
74
     * Insert or Update rows.
75
     * @param AbstractZohoDao $zohoDao
76
     * @param string $localTable
77
     */
78
    public function pushDataToZoho(AbstractZohoDao $zohoDao, $localTable, $update = false){
79
80
            $fieldsMatching = $this->findMethodValues($zohoDao);
81
            $tableName = $this->getTableName($zohoDao);
82
            $rowsDeleted = [];
83
            $statement = $this->connection->createQueryBuilder();
84
            $statement->select('zcrm.*');
85
            if($update){
86
                $statement->addSelect('l.field_name as updated_fieldname');
87
            }
88
            $statement->from($localTable, 'l')
89
            ->join('l', $tableName, 'zcrm', 'zcrm.uid = l.uid')
90
            ->where('l.table_name=:table_name')
91
            ->setParameters([
92
                'table_name' => $tableName
93
            ]);
94
            $results = $statement->execute();
95
            /* @var $zohoBeans ZohoBeanInterface[] */
96
            $zohoBeans = array();
97
            while ($row = $results->fetch()) {
98
                $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...
99
                /* @var $zohoBean ZohoBeanInterface */
100
                if(isset($zohoBeans[$row['uid']])){
101
                    $zohoBean = $zohoBeans[$row['uid']];
102
                }else{
103
                    $zohoBean = new $beanClassName();
104
                }
105
                if(!$update){
106
                    foreach ($row as $columnName => $columnValue) {
107
                        if (!in_array($columnName,['id','uid']) || isset($fieldsMatching[$columnName])) {
108
                            $value = $this->formatValueToBeans($zohoDao->getModule(), $fieldsMatching, $columnName, $columnValue, null, $row['uid']);
0 ignored issues
show
Bug introduced by
The method getModule() 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...
109
                           if($columnValue){
110
                               $zohoBean->{$fieldsMatching[$columnName]['setter']}($value);
111
                           }
112
                        }
113
                    }
114
                    $zohoBeans[$row['uid']] =  $zohoBean;
115
                    $rowsDeleted[] = $row['uid'];
116
                } else{
117
                    $columnName = $row['updated_fieldname'];
118
                    $zohoBean->setZohoId($row['id']);
119
                    if (!in_array($columnName,['id','uid']) || isset($fieldsMatching[$columnName])) {
120
                        $value = $this->formatValueToBeans($zohoDao->getModule(), $fieldsMatching, $columnName, $row[$columnName], $row['id']);
0 ignored issues
show
Bug introduced by
The method getModule() 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...
121
                        $zohoBean->{$fieldsMatching[$columnName]['setter']}($value);
122
                        $zohoBeans[$row['uid']] = $zohoBean;
123
                        $rowsDeleted[] = $row['uid'];
124
                    }
125
                }
126
            }
127
            $zohoDao->save($zohoBeans);
128
            if(!$update){
129
                foreach ($zohoBeans as $uid => $zohoBean) {
130
                    $this->connection->update($tableName, [ 'id'=>$zohoBean->getZohoId(),'lastActivityTime'=> date("Y-m-d H:i:s") ], ['uid'=>$uid ]);
131
                }
132
            }
133
            $statementDelete = $this->connection->prepare('delete from '.$localTable.' where uid in ( :rowsDeleted)');
134
            $statementDelete->execute([
135
                'rowsDeleted' => implode(',', $rowsDeleted)
136
            ]);
137
    }
138
139
    /**
140
     * Change the value to the good format.
141
     * @param string $moduleName
142
     * @param array $fieldsMatching
143
     * @param string $columnName
144
     * @param mixed $value
145
     * @param int $id
146
     * @return mixed
147
     * @throws ZohoCRMException
148
     */
149
    private function formatValueToBeans($moduleName, $fieldsMatching,$columnName,$value,$id=null, $uid = null)
150
    {
151
        $idrecord = $id?$id.'[ZOHO]':$uid.'[UID]';
152
        if(isset($fieldsMatching[$columnName]) && $value){
153
            switch ($fieldsMatching[$columnName]['type']) {
154
                case 'Date':
155
                    if ($dateObj = \DateTime::createFromFormat('M/d/Y', $value)) {
156
                        $value = $dateObj;
157
                    } elseif ($dateObj = \DateTime::createFromFormat('Y-m-d', $value)) {
158
                        $value = $dateObj;
159
                    } else {
160
                        throw new ZohoCRMException('Unable to convert the Date field "'.$columnName."\" into a DateTime PHP object from the the record $idrecord of the module ".$moduleName.'.');
161
                    }
162
                    break;
163
                case 'DateTime':
164
                    $value = \DateTime::createFromFormat('Y-m-d H:i:s', $value);
165
                    break;
166
                default:
167
                    break;
168
            }
169
        }
170
        return $value;
171
    }
172
173
    /**
174
     * Find the row to delete and remove to Zoho.
175
     * @param AbstractZohoDao $zohoDao
176
     * @param string $localTable
177
     */
178
    public function deleteDataToZoho(AbstractZohoDao $zohoDao, $localTable){
179
        $tableName = $this->getTableName($zohoDao);
180
        $statement = $this->connection->createQueryBuilder();
181
        $statement->select('l.id')
182
        ->from($localTable, 'l')
183
        ->where('l.table_name=:table_name')
184
        ->setParameters([
185
            'table_name' => $tableName
186
        ]);
187
        $results = $statement->execute();
188
        while ($row = $results->fetch()) {
189
            $zohoDao->delete($row['id']);
190
            $this->connection->delete($localTable, ['table_name' => $tableName,'id' => $row['id']]);
191
        }
192
}
193
    
194
    /**
195
     * Run inserted rows to Zoho : local_insert.
196
     * @param AbstractZohoDao $zohoDao
197
     */
198
    public function pushInsertedRows(AbstractZohoDao $zohoDao){
199
        return $this->pushDataToZoho($zohoDao, 'local_insert');
200
    }
201
202
    /**
203
     * Run updated rows to Zoho : local_update.
204
     * @param AbstractZohoDao $zohoDao
205
     */
206
    public function pushUpdatedRows(AbstractZohoDao $zohoDao){
207
        $this->pushDataToZoho($zohoDao, 'local_update', true);
208
    }
209
210
    /**
211
     * Run deleted rows to Zoho : local_delete.
212
     * @param AbstractZohoDao $zohoDao
213
     */
214
    public function pushDeletedRows(AbstractZohoDao $zohoDao){
215
        $this->deleteDataToZoho($zohoDao, 'local_delete');
216
    }
217
218
    /**
219
     * Computes the name of the table based on the DAO plural module name.
220
     *
221
     * @param AbstractZohoDao $dao
222
     *
223
     * @return string
224
     */
225 View Code Duplication
    private function getTableName(AbstractZohoDao $dao)
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...
226
    {
227
        $tableName = $this->prefix.$dao->getPluralModuleName();
0 ignored issues
show
Bug introduced by
The method getPluralModuleName() 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...
228
        $tableName = s($tableName)->upperCamelize()->underscored();
229
230
        return (string) $tableName;
231
    }
232
233
234
    /**
235
     * @param LoggerInterface $logger
236
     */
237
    public function setLogger(LoggerInterface $logger)
238
    {
239
        $this->logger = $logger;
240
    }
241
242
243
}