ConfigReader::serviceOptions()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 4.125

Importance

Changes 0
Metric Value
cc 3
nc 2
nop 2
dl 0
loc 14
rs 9.7998
c 0
b 0
f 0
ccs 5
cts 10
cp 0.5
crap 4.125
1
<?php
2
/**
3
 * Copyright 2016 - 2018, Cake Development Corporation (http://cakedc.com)
4
 *
5
 * Licensed under The MIT License
6
 * Redistributions of files must retain the above copyright notice.
7
 *
8
 * @copyright Copyright 2016 - 2018, Cake Development Corporation (http://cakedc.com)
9
 * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
10
 */
11
namespace CakeDC\Api\Service;
12
13
use Cake\Core\Configure;
14
use Cake\Utility\Hash;
15
use Cake\Utility\Inflector;
16
17
class ConfigReader
18
{
19
20
    /**
21
     * Builds service options.
22
     *
23
     * @param string $serviceName Service name.
24
     * @param int $version Version number.
25
     * @return array
26
     */
27 57
    public function serviceOptions($serviceName, $version = null)
28
    {
29 57
        $defaults = $this->_checkServiceOptions('default.options');
30 57
        if (Configure::read('Api.useVersioning') && $version) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $version of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
31
            $version = Configure::read('Api.versionPrefix') . $version;
32
            $versionDefaults = $this->_checkServiceOptions("$version.default.options");
33
            $options = $this->_checkServiceOptions("$version.$serviceName.options");
34
            $options = $this->_mergeWithDefaults($options, $versionDefaults, true);
0 ignored issues
show
Bug introduced by
It seems like $options can also be of type object<ArrayAccess>; however, CakeDC\Api\Service\Confi...r::_mergeWithDefaults() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Bug introduced by
It seems like $versionDefaults defined by $this->_checkServiceOpti...sion}.default.options") on line 32 can also be of type object<ArrayAccess>; however, CakeDC\Api\Service\Confi...r::_mergeWithDefaults() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
35
        } else {
36 57
            $options = $this->_checkServiceOptions("$serviceName.options");
37
        }
38
39 57
        return $this->_mergeWithDefaults($options, $defaults, true);
0 ignored issues
show
Bug introduced by
It seems like $options defined by $this->_checkServiceOpti...$serviceName}.options") on line 36 can also be of type object<ArrayAccess>; however, CakeDC\Api\Service\Confi...r::_mergeWithDefaults() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Bug introduced by
It seems like $defaults defined by $this->_checkServiceOptions('default.options') on line 29 can also be of type object<ArrayAccess>; however, CakeDC\Api\Service\Confi...r::_mergeWithDefaults() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
40
    }
41
42
    /**
43
     * Builds action options.
44
     *
45
     * @param string $serviceName A Service name.
46
     * @param string $actionName An Action name.
47
     * @param int $version Version number.
48
     * @return array
49
     */
50 64
    public function actionOptions($serviceName, $actionName, $version = null)
51
    {
52 64
        $actionName = Inflector::camelize($actionName);
53 64
        $defaults = $this->_checkServiceOptions('default.Action.default');
54 64
        $defaultByName = $this->_checkServiceOptions("default.Action.$actionName");
55 64
        if (Configure::read('Api.useVersioning') && $version) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $version of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
56
            $version = Configure::read('Api.versionPrefix') . $version;
57
            $versionDefaults = $this->_checkServiceOptions("$version.default.Action.default");
58
            $versionDefaultsByName = $this->_checkServiceOptions("$version.default.Action.$actionName");
59
60
            $byServiceDefault = $this->_checkServiceOptions("$version.$serviceName.Action.default");
61
            $byServiceOptions = $this->_checkServiceOptions("$version.$serviceName.Action.$actionName");
62
63
            $options = $this->_mergeWithDefaults($byServiceOptions, $byServiceDefault);
0 ignored issues
show
Bug introduced by
It seems like $byServiceOptions defined by $this->_checkServiceOpti....Action.{$actionName}") on line 61 can also be of type object<ArrayAccess>; however, CakeDC\Api\Service\Confi...r::_mergeWithDefaults() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Bug introduced by
It seems like $byServiceDefault defined by $this->_checkServiceOpti...eName}.Action.default") on line 60 can also be of type object<ArrayAccess>; however, CakeDC\Api\Service\Confi...r::_mergeWithDefaults() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
64
            $options = $this->_mergeWithDefaults($options, $versionDefaultsByName);
0 ignored issues
show
Bug introduced by
It seems like $versionDefaultsByName defined by $this->_checkServiceOpti....Action.{$actionName}") on line 58 can also be of type object<ArrayAccess>; however, CakeDC\Api\Service\Confi...r::_mergeWithDefaults() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
65
            $options = $this->_mergeWithDefaults($options, $versionDefaults);
0 ignored issues
show
Bug introduced by
It seems like $versionDefaults defined by $this->_checkServiceOpti...efault.Action.default") on line 57 can also be of type object<ArrayAccess>; however, CakeDC\Api\Service\Confi...r::_mergeWithDefaults() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
66
        } else {
67 64
            $byServiceDefault = $this->_checkServiceOptions("$serviceName.Action.default");
68 64
            $byServiceOptions = $this->_checkServiceOptions("$serviceName.Action.$actionName");
69
70 64
            $options = $this->_mergeWithDefaults($byServiceOptions, $byServiceDefault);
0 ignored issues
show
Bug introduced by
It seems like $byServiceOptions defined by $this->_checkServiceOpti....Action.{$actionName}") on line 68 can also be of type object<ArrayAccess>; however, CakeDC\Api\Service\Confi...r::_mergeWithDefaults() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Bug introduced by
It seems like $byServiceDefault defined by $this->_checkServiceOpti...eName}.Action.default") on line 67 can also be of type object<ArrayAccess>; however, CakeDC\Api\Service\Confi...r::_mergeWithDefaults() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
71
        }
72
73 64
        $options = $this->_mergeWithDefaults($defaultByName, $options);
0 ignored issues
show
Bug introduced by
It seems like $defaultByName defined by $this->_checkServiceOpti....Action.{$actionName}") on line 54 can also be of type object<ArrayAccess>; however, CakeDC\Api\Service\Confi...r::_mergeWithDefaults() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
74
75 64
        return $this->_mergeWithDefaults($defaults, $options);
0 ignored issues
show
Bug introduced by
It seems like $defaults defined by $this->_checkServiceOpti...efault.Action.default') on line 53 can also be of type object<ArrayAccess>; however, CakeDC\Api\Service\Confi...r::_mergeWithDefaults() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
76
    }
77
78
    /**
79
     * Check options existence by prefix.
80
     *
81
     * @param string $prefix Path prefix.
82
     * @return array
83
     */
84 64
    protected function _checkServiceOptions($prefix)
85
    {
86 64
        $data = Configure::read('Api.Service');
87 64
        if (is_array($data) && Hash::check($data, $prefix)) {
88 53
            return Hash::extract($data, $prefix);
89
        }
90
91 64
        return [];
92
    }
93
94
    /**
95
     * Merge with defaults
96
     *
97
     * @param array $options An options.
98
     * @param array $defaults Default options.
99
     * @param bool $overwrite Overwrite flag.
100
     * @return array
101
     */
102 64
    protected function _mergeWithDefaults($options, $defaults, $overwrite = false)
103
    {
104 64
        if ($overwrite) {
105 57
            foreach ($options as $key => $value) {
106 1
                if ($value !== null) {
107 1
                    unset($defaults[$key]);
108 1
                }
109 57
            }
110 57
        }
111
112 64
        return Hash::merge($options, $defaults);
113
    }
114
}
115