Completed
Push — master ( fb8b8a...a8d3eb )
by Zhmayev
01:10
created

Entities::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
* Vtiger Web Services PHP Client Library
4
*
5
* The MIT License (MIT)
6
*
7
* Copyright (c) 2015, Zhmayev Yaroslav <[email protected]>
8
*
9
* Permission is hereby granted, free of charge, to any person obtaining a copy
10
* of this software and associated documentation files (the "Software"), to deal
11
* in the Software without restriction, including without limitation the rights
12
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
* copies of the Software, and to permit persons to whom the Software is
14
* furnished to do so, subject to the following conditions:
15
*
16
* The above copyright notice and this permission notice shall be included in
17
* all copies or substantial portions of the Software.
18
*
19
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
* THE SOFTWARE.
26
*
27
* @author    Zhmayev Yaroslav <[email protected]>
28
* @copyright 2015-2016 Zhmayev Yaroslav
29
* @license   The MIT License (MIT)
30
*/
31
32
namespace Salaros\Vtiger\VTWSCLib;
33
34
use Salaros\Vtiger\VTWSCLib\WSClient;
35
36
/**
37
* Vtiger Web Services PHP Client Session class
38
*
39
* Class Entities
40
* @package Salaros\Vtiger\VTWSCLib
41
*/
42
class Entities
43
{
44
    private $wsClient;
45
46
    /**
47
     * Class constructor
48
     * @param object $wsClient  Parent WSClient instance
49
     */
50
    public function __construct($wsClient)
51
    {
52
        $this->wsClient = $wsClient;
53
    }
54
55
    /**
56
     * Retrieves an entity by ID
57
     * @param  string  $moduleName The name of the module / entity type
58
     * @param  string  $entityID The ID of the entity to retrieve
59
     * @return array   $select  The list of fields to select (defaults to SQL-like '*' - all the fields)
60
     * @return array  Entity data
61
     */
62
    public function findOneByID($moduleName, $entityID, array $select = [ ])
63
    {
64
        $entityID = $this->wsClient->modules->getTypedID($moduleName, $entityID);
65
        $record = $this->wsClient->invokeOperation('retrieve', ['id' => $entityID], 'GET');
66
        if (!is_array($record))
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
67
            return null;
68
69
        return (empty($select))
70
            ? $record
71
            : array_intersect_key($record, array_flip($select));
72
    }
73
74
    /**
75
     * Retrieve the entity matching a list of constraints
76
     * @param  string  $moduleName   The name of the module / entity type
77
     * @param  array   $params  Data used to find a matching entry
78
     * @return array   $select  The list of fields to select (defaults to SQL-like '*' - all the fields)
79
     * @return array  The matching record
80
     */
81
    public function findOne($moduleName, array $params, array $select = [ ])
82
    {
83
        $entityID = $this->getID($moduleName, $params);
84
        return (empty($entityID))
85
            ? null
86
            : $this->findOneByID($moduleName, $entityID, $select);
87
    }
88
89
    /**
90
     * Retrieves the ID of the entity matching a list of constraints + prepends '<module_id>x' string to it
91
     * @param  string $moduleName   The name of the module / entity type
92
     * @param  array   $params  Data used to find a matching entry
93
     * @return string  Type ID (a numeric ID + '<module_id>x')
94
     */
95
    public function getID($moduleName, array $params)
96
    {
97
        $query = self::getQueryString($moduleName, $params, [ 'id' ], 1);
98
        $records = $this->wsClient->runQuery($query);
99
        if (false === $records || !is_array($records) || empty($records)) {
100
            return null;
101
        }
102
103
        $record = $records[0];
104
        return (!is_array($record) || !isset($record[ 'id' ]) || empty($record[ 'id' ]))
105
            ? null
106
            : $record[ 'id' ];
107
    }
108
109
    /**
110
     * Retrieve a numeric ID of the entity matching a list of constraints
111
     * @param  string  $moduleName   The name of the module / entity type
112
     * @param  array   $params  Data used to find a matching entry
113
     * @return integer  Numeric ID
114
     */
115
    public function getNumericID($moduleName, array $params)
116
    {
117
        $entityID = $this->getID($moduleName, $params);
118
        $entityIDParts = explode('x', $entityID, 2);
119
        return (is_array($entityIDParts) && count($entityIDParts) === 2)
120
            ? intval($entityIDParts[ 1 ])
121
            : -1;
122
    }
123
124
    /**
125
     * Creates an entity for the giving module
126
     * @param  string  $moduleName   Name of the module / entity type for which the entry has to be created
127
     * @param  array  $params Entity data
128
     * @return array  Entity creation results
129
     */
130
    public function createOne($moduleName, array $params)
131
    {
132
        if (!is_assoc_array($params)) {
133
            throw new WSException(
134
                "You have to specify at least one search parameter (prop => value) 
135
                in order to be able to create an entity"
136
            );
137
        }
138
139
        // Assign record to logged in user if not specified
140
        if (!isset($params[ 'assigned_user_id' ])) {
141
            $currentUser = $this->wsClient->getCurrentUser();
142
            $params[ 'assigned_user_id' ] = $currentUser[ 'id' ];
143
        }
144
145
        $requestData = [
146
            'elementType' => $moduleName,
147
            'element'     => json_encode($params)
148
        ];
149
150
        return $this->wsClient->invokeOperation('create', $requestData);
151
    }
152
153
    /**
154
     * Updates an entity
155
     * @param  string $moduleName   The name of the module / entity type
156
     * @param  array $params Entity data
157
     * @return array  Entity update result
158
     */
159
    public function updateOne($moduleName, $entityID, array $params)
160
    {
161
        if (!is_assoc_array($params)) {
162
            throw new WSException(
163
                "You have to specify at least one search parameter (prop => value) 
164
                in order to be able to update the entity(ies)"
165
            );
166
        }
167
168
        // Fail if no ID was supplied
169
        if (empty($entityID)) {
170
            throw new WSException("The list of contraints must contain a valid ID");
171
        }
172
173
        // Preprend so-called moduleid if needed
174
        $entityID = $this->wsClient->modules->getTypedID($moduleName, $entityID);
175
176
        // Check if the entity exists + retrieve its data so it can be used below
177
        $entityData = $this->findOneByID($moduleName, $entityID);
178
        if ($entityData === false && !is_array($entityData)) {
179
            throw new WSException("Such entity doesn't exist, so it cannot be updated");
180
        }
181
182
        // The new data overrides the existing one needed to provide
183
        // mandatory field values to WS 'update' operation
184
        $params = array_merge(
185
            $entityData,
186
            $params
187
        );
188
189
        $requestData = [
190
            'elementType' => $moduleName,
191
            'element'     => json_encode($params)
192
        ];
193
194
        return $this->wsClient->invokeOperation('update', $requestData);
195
    }
196
197
    /**
198
     * Provides entity removal functionality
199
     * @param  string $moduleName   The name of the module / entity type
200
     * @param  string $entityID The ID of the entity to delete
201
     * @return array  Removal status object
202
     */
203
    public function deleteOne($moduleName, $entityID)
204
    {
205
        // Preprend so-called moduleid if needed
206
        $entityID = $this->wsClient->modules->getTypedID($moduleName, $entityID);
207
        return $this->wsClient->invokeOperation('delete', [ 'id' => $entityID ]);
208
    }
209
210
    /**
211
     * Retrieves multiple records using module name and a set of constraints
212
     * @param  string   $moduleName  The name of the module / entity type
213
     * @param  array    $params  Data used to find matching entries
214
     * @return array    $select  The list of fields to select (defaults to SQL-like '*' - all the fields)
215
     * @return integer      $limit  limit the list of entries to N records (acts like LIMIT in SQL)
216
     * @return array  The array containing matching entries or false if nothing was found
217
     */
218
    public function findMany($moduleName, array $params, array $select = [ ], $limit = 0)
219
    {
220
        if (!is_array($params) || (!empty($params) && !is_assoc_array($params))) {
221
            throw new WSException(
222
                "You have to specify at least one search parameter (prop => value) 
223
                in order to be able to retrieve entity(ies)"
224
            );
225
        }
226
227
        // Builds the query
228
        $query = self::getQueryString($moduleName, $params, $select, $limit);
229
230
        // Run the query
231
        $records = $this->wsClient->runQuery($query);
232
        if (false === $records || !is_array($records) || empty($records)) {
233
            return null;
234
        }
235
236
        return $records;
237
    }
238
239
    /**
240
     * Sync will return a sync result object containing details of changes after modifiedTime
241
     * @param  integer [$modifiedTime = null]    The date of the first change
242
     * @param  string [$moduleName = null]   The name of the module / entity type
243
     * @param  string [$syncType = null]   Sync type determines the scope of the query
244
     * @return array  Sync result object
245
     */
246
    public function sync($modifiedTime = null, $moduleName = null, $syncType = null)
247
    {
248
        $modifiedTime = (empty($modifiedTime))
249
            ? strtotime('today midnight')
250
            : intval($modifiedTime);
251
252
        $requestData = [
253
            'modifiedTime' => $modifiedTime
254
        ];
255
256
        if (!empty($moduleName)) {
257
            $requestData[ 'elementType' ] = $moduleName;
258
        }
259
260
        if ($syncType) {
261
            $requestData[ 'syncType' ] = $syncType;
262
        }
263
264
        return $this->wsClient->invokeOperation('sync', $requestData, 'GET');
265
    }
266
267
    /**
268
     * Builds the query using the supplied parameters
269
     * @access public
270
     * @static
271
     * @param  string   $moduleName  The name of the module / entity type
272
     * @param  array    $params  Data used to find matching entries
273
     * @return string    $select  The list of fields to select (defaults to SQL-like '*' - all the fields)
274
     * @return string      $limit  limit the list of entries to N records (acts like LIMIT in SQL)
275
     * @return string   The query build out of the supplied parameters
276
     */
277
    public static function getQueryString($moduleName, array $params, array $select = [ ], $limit = 0)
278
    {
279
        $criteria = array();
280
        $select = (empty($select)) ? '*' : implode(',', $select);
281
        $query = sprintf("SELECT %s FROM $moduleName", $select);
282
        
283
        if (!empty($params)) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
284
285
            foreach ($params as $param => $value) {
286
                $criteria[ ] = "{$param} LIKE '{$value}'";
287
            }
288
289
            $query .= sprintf(' WHERE %s', implode(" AND ", $criteria));
290
        }
291
292
        if (intval($limit) > 0) {
293
            $query .= sprintf(" LIMIT %s", intval($limit));
294
        }
295
296
        return $query;
297
    }
298
}
299