Completed
Branch develop (59ab9a)
by
unknown
27:43
created

MyObjectApi::_validate()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 1
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/* Copyright (C) 2015   Jean-François Ferry     <[email protected]>
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
 */
17
18
use Luracast\Restler\RestException;
19
20
/**
21
 * \file    htdocs/modulebuilder/template/class/myobject_api_class.class.php
22
 * \ingroup mymodule
23
 * \brief   File for API management of myobject.
24
 */
25
 
26
/**
27
 * API class for mymodule myobject
28
 *
29
 * @smart-auto-routing false
30
 * @access protected 
31
 * @class  DolibarrApiAccess {@requires user,external}
32
 */
33
class MyObjectApi extends DolibarrApi
34
{
35
    /**
36
     * @var array   $FIELDS     Mandatory fields, checked when create and update object 
37
     */
38
    static $FIELDS = array(
39
        'name'
40
    );
41
42
    /**
43
     * @var MyObject $myobject {@type MyObject}
44
     */
45
    public $myobject;
46
47
    /**
48
     * Constructor
49
     *
50
     * @url     GET myobject/
51
     * 
52
     */
53
    function __construct()
54
    {
55
		global $db, $conf;
56
		$this->db = $db;
57
        $this->myobject = new MyObject($this->db);
58
    }
59
60
    /**
61
     * Get properties of a myobject object
62
     *
63
     * Return an array with myobject informations
64
     *
65
     * @param 	int 	$id ID of myobject
66
     * @return 	array|mixed data without useless information
67
	 * 
68
     * @url	GET myobject/{id}
69
     * @throws 	RestException
70
     */
71
    function get($id)
72
    {		
73
		if(! DolibarrApiAccess::$user->rights->myobject->read) {
74
			throw new RestException(401);
75
		}
76
			
77
        $result = $this->myobject->fetch($id);
78
        if( ! $result ) {
79
            throw new RestException(404, 'MyObject not found');
80
        }
81
		
82
		if( ! DolibarrApi::_checkAccessToResource('myobject',$this->myobject->id)) {
83
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
84
		}
85
86
		return $this->_cleanObjectDatas($this->myobject);
87
    }
88
89
    /**
90
     * List myobjects
91
     * 
92
     * Get a list of myobjects
93
     * 
94
     * @param int		$mode		Use this param to filter list
95
     * @param string	$sortfield	Sort field
96
     * @param string	$sortorder	Sort order
97
     * @param int		$limit		Limit for list
98
     * @param int		$page		Page number
99
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101') or (t.import_key:=:'20160101')"
100
     * @return array Array of myobject objects
101
     *
102
     * @url	GET /myobjects/
103
     */
104
    function index($mode, $sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $sqlfilters = '') {
105
        global $db, $conf;
106
        
107
        $obj_ret = array();
108
        
109
        $socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : '';
110
            
111
        // If the internal user must only see his customers, force searching by him
112
        if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id;
113
114
        $sql = "SELECT s.rowid";
115
        if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects)
0 ignored issues
show
Bug introduced by
The variable $search_sale does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
116
        $sql.= " FROM ".MAIN_DB_PREFIX."myobject as s";
117
        
118
        if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
119
        $sql.= ", ".MAIN_DB_PREFIX."c_stcomm as st";
120
        $sql.= " WHERE s.fk_stcomm = st.id";
121
        
122
		// Example of use $mode
123
        //if ($mode == 1) $sql.= " AND s.client IN (1, 3)";
124
        //if ($mode == 2) $sql.= " AND s.client IN (2, 3)";
125
126
        $sql.= ' AND s.entity IN ('.getEntity('myobject', 1).')';
127
        if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND s.fk_soc = sc.fk_soc";
128
        if ($socid) $sql.= " AND s.fk_soc = ".$socid;
129
        if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc";		// Join for the needed table to filter by sale
130
        // Insert sale filter
131
        if ($search_sale > 0)
132
        {
133
            $sql .= " AND sc.fk_user = ".$search_sale;
134
        }
135
        if ($sqlfilters)
136
        {
137
            if (! DolibarrApi::_checkFilters($sqlfilters))
138
            {
139
                throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
140
            }
141
	        $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
142
            $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
143
        }
144
145
        $sql.= $db->order($sortfield, $sortorder);
146
        if ($limit)	{
147
            if ($page < 0)
148
            {
149
                $page = 0;
150
            }
151
            $offset = $limit * $page;
152
153
            $sql.= $db->plimit($limit + 1, $offset);
154
        }
155
156
        $result = $db->query($sql);
157
        if ($result)
158
        {
159
            $num = $db->num_rows($result);
160
            while ($i < $num)
0 ignored issues
show
Bug introduced by
The variable $i does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
161
            {
162
                $obj = $db->fetch_object($result);
163
                $myobject_static = new MyObject($db);
164
                if($myobject_static->fetch($obj->rowid)) {
165
                    $obj_ret[] = parent::_cleanObjectDatas($myobject_static);
166
                }
167
                $i++;
168
            }
169
        }
170
        else {
171
            throw new RestException(503, 'Error when retrieve myobject list');
172
        }
173
        if( ! count($obj_ret)) {
174
            throw new RestException(404, 'No myobject found');
175
        }
176
		return $obj_ret;
177
    }
178
    
179
    /**
180
     * Create myobject object
181
     *
182
     * @param array $request_data   Request datas
183
     * @return int  ID of myobject
184
     * 
185
     * @url	POST myobject/
186
     */
187
    function post($request_data = NULL)
188
    {
189
        if(! DolibarrApiAccess::$user->rights->myobject->create) {
190
			throw new RestException(401);
191
		}
192
        // Check mandatory fields
193
        $result = $this->_validate($request_data);
1 ignored issue
show
Bug introduced by
It seems like $request_data defined by parameter $request_data on line 187 can also be of type null; however, MyObjectApi::_validate() does only seem to accept array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
194
        
195
        foreach($request_data as $field => $value) {
196
            $this->myobject->$field = $value;
197
        }
198
        if( ! $this->myobject->create(DolibarrApiAccess::$user)) {
199
            throw new RestException(500);
200
        }
201
        return $this->myobject->id;
202
    }
203
204
    /**
205
     * Update myobject
206
     *
207
     * @param int   $id             Id of myobject to update
208
     * @param array $request_data   Datas   
209
     * @return int 
210
     * 
211
     * @url	PUT myobject/{id}
212
     */
213
    function put($id, $request_data = NULL)
214
    {
215
        if(! DolibarrApiAccess::$user->rights->myobject->create) {
216
			throw new RestException(401);
217
		}
218
        
219
        $result = $this->myobject->fetch($id);
220
        if( ! $result ) {
221
            throw new RestException(404, 'MyObject not found');
222
        }
223
		
224
		if( ! DolibarrApi::_checkAccessToResource('myobject',$this->myobject->id)) {
225
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
226
		}
227
228
        foreach($request_data as $field => $value) {
229
            $this->myobject->$field = $value;
230
        }
231
        
232
        if($this->myobject->update($id, DolibarrApiAccess::$user))
233
            return $this->get ($id);
234
        
235
        return false;
236
    }
237
    
238
    /**
239
     * Delete myobject
240
     *
241
     * @param   int     $id   MyObject ID
242
     * @return  array
243
     * 
244
     * @url	DELETE myobject/{id}
245
     */
246
    function delete($id)
247
    {
248
        if(! DolibarrApiAccess::$user->rights->myobject->supprimer) {
249
			throw new RestException(401);
250
		}
251
        $result = $this->myobject->fetch($id);
252
        if( ! $result ) {
253
            throw new RestException(404, 'MyObject not found');
254
        }
255
		
256
		if( ! DolibarrApi::_checkAccessToResource('myobject',$this->myobject->id)) {
257
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
258
		}
259
        
260
        if( !$this->myobject->delete($id))
261
        {
262
            throw new RestException(500);
263
        }
264
        
265
         return array(
266
            'success' => array(
267
                'code' => 200,
268
                'message' => 'MyObject deleted'
269
            )
270
        );
271
        
272
    }
273
    
274
    /**
275
     * Validate fields before create or update object
276
     * 
277
     * @param array $data   Data to validate
278
     * @return array
279
     * 
280
     * @throws RestException
281
     */
282
    function _validate($data)
283
    {
284
        $myobject = array();
285
        foreach (MyObjectApi::$FIELDS as $field) {
286
            if (!isset($data[$field]))
287
                throw new RestException(400, "$field field missing");
288
            $myobject[$field] = $data[$field];
289
        }
290
        return $myobject;
291
    }
292
}
293