Completed
Push — master ( d03358...143fc5 )
by Nicolaas
02:11
created

TemplateoverviewPageAPI::createPageObject()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 28
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 28
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 24
nc 4
nop 2
1
<?php
2
3
4
5
class TemplateoverviewPageAPI extends Object
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
6
{
7
    
8
    private static $list_of_all_classes = array();
9
    
10
    private static $classes_to_exclude = array("SiteTree", "RedirectorPage", "VirtualPage");
0 ignored issues
show
Unused Code introduced by
The property $classes_to_exclude is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
11
12
    public function ListOfAllClasses($checkCurrentClass = true)
13
    {
14
        if (!self::$list_of_all_classes) {
0 ignored issues
show
Bug Best Practice introduced by
The expression self::$list_of_all_classes 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...
15
            $ArrayOfAllClasses =  array();
16
            //$classes = ClassInfo::subclassesFor("SiteTree");
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% 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...
17
            $classes = SiteTree::page_type_classes();
18
            $classesToRemove = array();
19
20
            foreach ($classes as $className) {
21
                if (!in_array($className, $this->config()->get("classes_to_exclude"))) {
22
                    if ($this->showAll) {
0 ignored issues
show
Bug introduced by
The property showAll does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
23
                        $objects = $className::get()
24
                            ->filter(array("ClassName" => $className))
25
                            ->sort("RAND() ASC")
26
                            ->limit(25);
27
                        $count = 0;
28
                        if ($objects->count()) {
29
                            foreach ($objects as $obj) {
30
                                if (!$count) {
31
                                    if ($ancestorToHide = $obj->stat('hide_ancestor')) {
32
                                        $classesToRemove[] = $ancestorToHide;
33
                                    }
34
                                }
35
                                $object = $this->createPageObject($obj, $count++);
36
                                $ArrayOfAllClasses[$object->indexNumber] = clone $object;
37
                            }
38
                        }
39
                    } else {
40
                        $obj = null;
0 ignored issues
show
Unused Code introduced by
$obj is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
41
                        $obj = $className::get()
42
                            ->filter(array("ClassName" => $className))
43
                            ->sort("RAND() ASC")
44
                            ->limit(1)
45
                            ->first();
46
                        if ($obj) {
47
                            $count = SiteTree::get()->filter(array("ClassName" => $obj->ClassName))->count();
48
                        } else {
49
                            $obj = $className::create();
50
                            $count = 0;
51
                        }
52
                        if ($ancestorToHide = $obj->stat('hide_ancestor')) {
53
                            $classesToRemove[] = $ancestorToHide;
54
                        }
55
                        $object = $this->createPageObject($obj, $count);
56
                        $object->TemplateOverviewDescription = $this->TemplateDetails($className);
57
                        $ArrayOfAllClasses[$object->indexNumber] = clone $object;
58
                    }
59
                }
60
            }
61
62
            //remove the hidden ancestors...
63
            if ($classesToRemove && count($classesToRemove)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $classesToRemove 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...
64
                $classesToRemove = array_unique($classesToRemove);
65
                // unset from $classes
66
                foreach ($ArrayOfAllClasses as $tempKey => $tempClass) {
67
                    if (in_array($tempClass->ClassName, $classesToRemove)) {
68
                        unset($ArrayOfAllClasses[$tempKey]);
69
                    }
70
                }
71
            }
72
            ksort($ArrayOfAllClasses);
73
            self::$list_of_all_classes =  new ArrayList();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \ArrayList() of type object<ArrayList> is incompatible with the declared type array of property $list_of_all_classes.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
74
            $currentClassname = '';
75
            if ($checkCurrentClass) {
76
                if ($c = Controller::curr()) {
77
                    if ($d = $c->dataRecord) {
78
                        $currentClassname = $d->ClassName;
79
                    }
80
                }
81
            }
82
            if (count($ArrayOfAllClasses)) {
83
                foreach ($ArrayOfAllClasses as $item) {
84
                    if ($item->ClassName == $currentClassname) {
85
                        $item->LinkingMode = "current";
86
                    } else {
87
                        $item->LinkingMode = "link";
88
                    }
89
                    self::$list_of_all_classes->push($item);
90
                }
91
            }
92
        }
93
        return self::$list_of_all_classes;
94
    }
95
96
    public function ShowAll()
97
    {
98
        $this->showAll = true;
99
        return array();
100
    }
101
102
103
    protected function TemplateDetails($className)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
104
    {
105
        $obj = TemplateOverviewDescription::get()
106
            ->filter(array("ClassNameLink" => $className))
107
            ->First();
108
        if (!$obj) {
109
            $obj = new TemplateOverviewDescription();
110
            $obj->ClassNameLink = $className;
111
            $obj->ParentID = $this->ID;
0 ignored issues
show
Bug introduced by
The property ID does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
112
            $obj->write();
113
        }
114
        DB::query("UPDATE TemplateOverviewDescription SET ParentID = ".$this->ID.";");
115
        return $obj;
116
    }
117
118
    public function TotalCount()
119
    {
120
        return count(ClassInfo::subclassesFor("SiteTree"))-1;
121
    }
122
123
    /**
124
     * @param SiteTree $obj
125
     * @param Int $count
126
     * @param String $ClassName
0 ignored issues
show
Bug introduced by
There is no parameter named $ClassName. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
127
     * @return ArrayData
128
     */
129
    private function createPageObject($obj, $count)
130
    {
131
        $this->counter++;
0 ignored issues
show
Bug introduced by
The property counter does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
132
        $listArray = array();
133
        $indexNumber = (10000 * $count) + $this->counter;
134
        $listArray["indexNumber"] = $indexNumber;
135
        $listArray["ClassName"] = $obj->ClassName;
136
        $listArray["Count"] = $count;
137
        $listArray["ID"] = $obj->ID;
138
        $listArray["URLSegment"] = $obj->URLSegment;
139
        $listArray["TypoURLSegment"] = $this->Link();
0 ignored issues
show
Documentation Bug introduced by
The method Link does not exist on object<TemplateoverviewPageAPI>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
140
        $listArray["Title"] = $obj->MenuTitle;
141
        $listArray["PreviewLink"] = $obj->PreviewLink();
142
        $listArray["CMSEditLink"] = $obj->CMSEditLink();
143
        $staticIcon = $obj->stat("icon", true);
144
        if (is_array($staticIcon)) {
145
            $iconArray = $obj->stat("icon");
146
            $icon = $iconArray[0];
147
        } else {
148
            $icon = $obj->stat("icon");
149
        }
150
        $iconFile = Director::baseFolder().'/'.$icon;
151
        if (!file_exists($iconFile)) {
152
            $icon = $icon."-file.gif";
153
        }
154
        $listArray["Icon"] = $icon;
155
        return new ArrayData($listArray);
156
    }
157
158
    //not used!
159
    public function NoSubClasses($obj)
160
    {
161
        $array = ClassInfo::subclassesFor($obj->ClassName);
162
        if (count($array)) {
163
            foreach ($array as $class) {
0 ignored issues
show
Bug introduced by
The expression $array of type null|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
164
                if ($class::get()->byID($obj->ID)) {
165
                    return false;
166
                }
167
            }
168
        }
169
        return true;
170
    }
171
}
172