TypeChecker::convertStringToPrimType()   C
last analyzed

Complexity

Conditions 9
Paths 9

Size

Total Lines 23
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 90

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 23
ccs 0
cts 18
cp 0
rs 5.8541
cc 9
eloc 20
nc 9
nop 2
crap 90
1
<?php
2
/**
3
 * Copyright (c) 2015-present, Facebook, Inc. All rights reserved.
4
 *
5
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
6
 * use, copy, modify, and distribute this software in source code or binary
7
 * form for use in connection with the web services and APIs provided by
8
 * Facebook.
9
 *
10
 * As with any software that integrates with the Facebook platform, your use
11
 * of this software is subject to the Facebook Developer Principles and
12
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
13
 * shall be included in all copies or substantial portions of the software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 * DEALINGS IN THE SOFTWARE.
22
 *
23
 */
24
25
namespace FacebookAds;
26
27
class TypeChecker {
28
29
  const ABSTRACT_OBJECT_PREFIX = "FacebookAds\\Object\\";
30
  private $type_data;
0 ignored issues
show
Coding Style introduced by
$type_data does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
31
  private $enum_data;
0 ignored issues
show
Coding Style introduced by
$enum_data does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
32
  private $primitive_types = ["unsigned int", "int", "bool", "string",
0 ignored issues
show
Coding Style introduced by
$primitive_types does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
33
    "Object", "datetime", "float"];
34
35 24
  public function __construct($type_check_info, $type_check_enum) {
36 24
    $this->type_data = $type_check_info;
37 24
    $this->enum_data = $type_check_enum;
38 24
  }
39
40
  public function isPrimitiveType($param) {
41
    return (in_array($param, $this->primitive_types) ||
42
      array_key_exists($param, $this->enum_data));
43
  }
44
45
  public function convertStringToPrimType($primitive_type, $value) {
46
    if (array_key_exists($primitive_type, $this->enum_data)) {
47
      return $value;
48
    } elseif (in_array($primitive_type, array("unsigned int", "int"))) {
49
      return intval($value);
50
    } elseif ($primitive_type === "bool") {
51
      return boolval($value);
52
    } elseif ($primitive_type === "float") {
53
      return floatval($value);
54
    } elseif ($primitive_type === "datetime") {
55
      return $value;
56
    } elseif ($primitive_type === "string") {
57
      return $value;
58
    } elseif ($primitive_type === "Object") {
59
      return $value;
60
    } else {
61
      if (ApiConfig::TYPE_CHECKER_STRICT_MODE) {
62
        throw new \Exception("Not a primitive type");
63
      } else {
64
        return $value;
65
      }
66
    }
67
  }
68
69
  public function getType($param) {
70
    if (array_key_exists($param, $this->type_data)) {
71
      return $this->type_data[$param];
72
    } else {
73
      return null;
74
    }
75
  }
76
77
  public function isValidParam($param) {
78
    return array_key_exists($param, $this->type_data);
79
  }
80
81
  public function isValidParamPair($param, $value) {
82
    if ($this->isValidParam($param)) {
83
      $type = $this->type_data[$param];
84
      return $this->checkType($type, $value);
85
    }
86
    return false;
87
  }
88
89
  public function checkType($type, $value, $allow_array_for_obj = true) {
90
    if ($value === null || $type === null || $type === "Object") {
91
      return true;
92
    } else if (array_key_exists($type, $this->enum_data)) {
93
      return in_array($value, $this->enum_data[$type]);
94
    } else if ($type === "file") {
95
      return file_exists($value);
96
    } else if ($type === "list" || $type === "map") {
97
      return is_array($value);
98
    } else if ($type === "bool") {
99
      return is_bool($value);
100
    } else if ($type === "int" || $type === "unsigned int" || $type === "float") {
101
      return is_numeric($value);
102
    } else if ($type === "string" || $type === "datetime") {
103
      return is_string($value) || is_numeric($value) || is_bool($value);
104
    } else if ($this->isTypeCollection($type, "list")) {
105
      $sub_types = $this->getTypeFromCollection($type, "list");
106
      $sub_type = $sub_types[0];
107
      if (is_array($value)) {
108
        if (empty($value)) {
109
          return true;
110
        }
111
        $all_object_same_type = true;
112
        foreach ($value as $key => $sub_value) {
113
          $all_object_same_type = ($all_object_same_type &&
114
            $this->checkType($sub_type, $sub_value));
115
        }
116
        return $all_object_same_type;
117
      } else {
118
        return $this->checkType($sub_type, $value);
119
      }
120
    } else if ($this->isTypeCollection($type, "map")) {
121
      if (is_array($value)) {
122
        $sub_types = $this->getTypeFromCollection($type, "map");
123
        if (count($sub_types) === 1) {
124
          $sub_key_type = 'string';
125
          $sub_value_type = $sub_types[0];
126
        } else {
127
          $sub_key_type = $sub_types[0];
128
          $sub_value_type = $sub_types[1];
129
        }
130
        $all_object_same_type = true;
131
        foreach ($value as $key => $sub_value) {
132
          $all_object_same_type = ($all_object_same_type &&
133
            $this->checkType($sub_key_type, $key) &&
134
            $this->checkType($sub_value_type, $sub_value));
135
        }
136
        return $all_object_same_type;
137
      }
138
    } else {
139
      // the type is an object
140
      if ($allow_array_for_obj && is_array($value)) {
141
        return true;
142
      }
143
      if (!$this->startsWith($type, self::ABSTRACT_OBJECT_PREFIX)) {
144
        $type = self::ABSTRACT_OBJECT_PREFIX.$type;
145
      }
146
      return is_a($value, $type);
147
    }
148
    return false;
149
  }
150
151
  public function isAbstractObject($value) {
152
    if (is_object($value)) {
153
      $cls_name = get_class($value);
154
      return $this->startsWith($cls_name, self::ABSTRACT_OBJECT_PREFIX);
155
    }
156
    return false;
157
  }
158
159
  private function startsWith($string, $prefix) {
160
    return $prefix === "" ||
161
      strrpos($string, $prefix, -strlen($string)) !== false;
162
  }
163
164
  public function isListParam($param) {
165
    if ($this->isValidParam($param)) {
166
      return $this->isTypeCollection($this->type_data[$param], "list");
167
    }
168
    return false;
169
  }
170
171
  public function isMapParam($param) {
172
    if ($this->isValidParam($param)) {
173
      return $this->isTypeCollection($this->type_data[$param], "map");
174
    }
175
    return false;
176
  }
177
178
  public function isFileParam($param) {
179
    if ($this->isValidParam($param)) {
180
      return ($this->type_data[$param] === "file");
181
    }
182
    return false;
183
  }
184
185
  public function isTypeCollection($type, $collection) {
186
    $len_of_collection = strlen($collection);
187
    $typeCollection = substr($type, 0, $len_of_collection);
0 ignored issues
show
Coding Style introduced by
$typeCollection does not seem to conform to the naming convention (^[a-z][a-z0-9]*(_[a-z0-9]+)*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
188
    return ($collection === $typeCollection);
0 ignored issues
show
Coding Style introduced by
$typeCollection does not seem to conform to the naming convention (^[a-z][a-z0-9]*(_[a-z0-9]+)*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
189
  }
190
191
  public function getTypeFromCollection($type, $collection) {
192
    return explode(",", trim(substr($type, strlen($collection)), "<>"));
193
  }
194
}
195