Completed
Push — master ( e5a757...47ec18 )
by Robbie
14s
created

JSONDataFormatter::convertDataObjectToJSONObject()   C

Complexity

Conditions 19
Paths 6

Size

Total Lines 77
Code Lines 44

Duplication

Lines 5
Ratio 6.49 %

Importance

Changes 0
Metric Value
dl 5
loc 77
rs 5.1697
c 0
b 0
f 0
cc 19
eloc 44
nc 6
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 SilverStripe\RestfulServer\DataFormatter;
4
5
use SilverStripe\RestfulServer\DataFormatter;
6
use SilverStripe\ORM\DataObjectInterface;
7
use SilverStripe\Core\Convert;
8
use SilverStripe\View\ArrayData;
9
use SilverStripe\Control\Director;
10
use SilverStripe\ORM\SS_List;
11
12
/**
13
 * Formats a DataObject's member fields into a JSON string
14
 */
15
class JSONDataFormatter extends DataFormatter
16
{
17
    /**
18
     * @config
19
     * @todo pass this from the API to the data formatter somehow
20
     */
21
    private static $api_base = "api/v1/";
22
23
    protected $outputContentType = 'application/json';
24
25
    public function supportedExtensions()
26
    {
27
        return array(
28
            'json',
29
            'js'
30
        );
31
    }
32
33
    public function supportedMimeTypes()
34
    {
35
        return array(
36
            'application/json',
37
            'text/x-json'
38
        );
39
    }
40
41
    /**
42
     * Generate a JSON representation of the given {@link DataObject}.
0 ignored issues
show
Bug introduced by
The type SilverStripe\RestfulServ...ataFormatter\DataObject was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
43
     *
44
     * @param DataObject $obj   The object
45
     * @param Array $fields     If supplied, only fields in the list will be returned
46
     * @param $relations        Not used
0 ignored issues
show
Bug introduced by
The type SilverStripe\RestfulServer\DataFormatter\Not was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
47
     * @return String JSON
48
     */
49
    public function convertDataObject(DataObjectInterface $obj, $fields = null, $relations = null)
50
    {
51
        return Convert::array2json($this->convertDataObjectToJSONObject($obj, $fields, $relations));
0 ignored issues
show
Bug introduced by
$this->convertDataObject...j, $fields, $relations) of type SilverStripe\RestfulServ...rmatter\EmptyJSONObject is incompatible with the type array expected by parameter $val of SilverStripe\Core\Convert::array2json(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

51
        return Convert::array2json(/** @scrutinizer ignore-type */ $this->convertDataObjectToJSONObject($obj, $fields, $relations));
Loading history...
52
    }
53
54
    /**
55
     * Internal function to do the conversion of a single data object. It builds an empty object and dynamically
56
     * adds the properties it needs to it. If it's done as a nested array, json_encode or equivalent won't use
57
     * JSON object notation { ... }.
58
     * @param DataObjectInterface $obj
59
     * @param  $fields
60
     * @param  $relations
61
     * @return EmptyJSONObject
0 ignored issues
show
Bug introduced by
The type SilverStripe\RestfulServ...rmatter\EmptyJSONObject was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
62
     */
63
    public function convertDataObjectToJSONObject(DataObjectInterface $obj, $fields = null, $relations = null)
64
    {
65
        $className = get_class($obj);
66
        $id = $obj->ID;
67
68
        $serobj = ArrayData::array_to_object();
69
70
        foreach ($this->getFieldsForObj($obj) as $fieldName => $fieldType) {
71
            // Field filtering
72
            if ($fields && !in_array($fieldName, $fields)) {
73
                continue;
74
            }
75
76
            $fieldValue = $obj->obj($fieldName)->forTemplate();
77
            $serobj->$fieldName = $fieldValue;
78
        }
79
80
        if ($this->relationDepth > 0) {
81
            foreach ($obj->hasOne() as $relName => $relClass) {
82
                if (!singleton($relClass)->stat('api_access')) {
83
                    continue;
84
                }
85
86
                // Field filtering
87
                if ($fields && !in_array($relName, $fields)) {
88
                    continue;
89
                }
90
                if ($this->customRelations && !in_array($relName, $this->customRelations)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->customRelations of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
91
                    continue;
92
                }
93
94
                $fieldName = $relName . 'ID';
95 View Code Duplication
                if ($obj->$fieldName) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
96
                    $href = Director::absoluteURL($this->config()->api_base . "$relClass/" . $obj->$fieldName);
97
                } else {
98
                    $href = Director::absoluteURL($this->config()->api_base . "$className/$id/$relName");
99
                }
100
                $serobj->$relName = ArrayData::array_to_object(array(
101
                    "className" => $relClass,
102
                    "href" => "$href.json",
103
                    "id" => $obj->$fieldName
104
                ));
105
            }
106
107
            foreach ($obj->hasMany() + $obj->manyMany() as $relName => $relClass) {
108
                //remove dot notation from relation names
109
                $parts = explode('.', $relClass);
110
                $relClass = array_shift($parts);
111
112
                if (!singleton($relClass)->stat('api_access')) {
113
                    continue;
114
                }
115
116
                // Field filtering
117
                if ($fields && !in_array($relName, $fields)) {
118
                    continue;
119
                }
120
                if ($this->customRelations && !in_array($relName, $this->customRelations)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->customRelations of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
121
                    continue;
122
                }
123
124
                $innerParts = array();
125
                $items = $obj->$relName();
126
                foreach ($items as $item) {
127
                    //$href = Director::absoluteURL($this->config()->api_base . "$className/$id/$relName/$item->ID");
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
128
                    $href = Director::absoluteURL($this->config()->api_base . "$relClass/$item->ID");
129
                    $innerParts[] = ArrayData::array_to_object(array(
130
                        "className" => $relClass,
131
                        "href" => "$href.json",
132
                        "id" => $item->ID
133
                    ));
134
                }
135
                $serobj->$relName = $innerParts;
136
            }
137
        }
138
139
        return $serobj;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $serobj returns the type stdClass which is incompatible with the documented return type SilverStripe\RestfulServ...rmatter\EmptyJSONObject.
Loading history...
140
    }
141
142
    /**
143
     * Generate a JSON representation of the given {@link SS_List}.
144
     *
145
     * @param SS_List $set
146
     * @return String XML
147
     */
148
    public function convertDataObjectSet(SS_List $set, $fields = null)
149
    {
150
        $items = array();
151
        foreach ($set as $do) {
152
            if (!$do->canView()) {
153
                continue;
154
            }
155
            $items[] = $this->convertDataObjectToJSONObject($do, $fields);
156
        }
157
158
        $serobj = ArrayData::array_to_object(array(
159
            "totalSize" => (is_numeric($this->totalSize)) ? $this->totalSize : null,
160
            "items" => $items
161
        ));
162
163
        return Convert::array2json($serobj);
0 ignored issues
show
Bug introduced by
$serobj of type stdClass is incompatible with the type array expected by parameter $val of SilverStripe\Core\Convert::array2json(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

163
        return Convert::array2json(/** @scrutinizer ignore-type */ $serobj);
Loading history...
164
    }
165
166
    public function convertStringToArray($strData)
167
    {
168
        return Convert::json2array($strData);
169
    }
170
}
171