OptionalTreeDropdownField::preTree()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
nc 1
nop 0
1
<?php
2
3
/**
4
 * TreeDropdown-like field that gives you a tree of items including an empty field, using ajax.
5
 * Author: Marijn Kampf www.exadium.com
6
 * Date:						24 Nov 2009
7
 * Version:				2.2
8
 * Revision date:	9 May 2011
9
 * Changes:				Fixed ajax sub tree request
10
 * Revision date:	8 October 2010
11
 * Changes:				Changed $this->postTree to OptionalTreeDropdownField::$postTree to avoid Undefined error
12
 * Revision date:	17 June 2010
13
 * Changes:				Updated to work with SilverStripe 2.4, tree function added.
14
 */
15
class OptionalTreeDropdownField extends TreeDropdownField
16
{
17
    private static $allowed_actions = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
18
        'tree',
19
    );
20
21
    /**
22
     * Define once rather than defining same line twice.
23
     */
24
    private static $postTree = '</ul>';
25
26
    /**
27
     * Helper function to return the header (rather than defining same line twice).
28
     */
29
    public function preTree()
30
    {
31
        return '<ul class="tree"><li id="" class="l"><a>'._t('OptionalTreeDropdownField.NONE', '(None)').'</a>';
32
    }
33
34
    public function getField($field)
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...
35
    {
36
        return $this->$field;
37
    }
38
39
    /**
40
     * Return the site tree
41
     * For version 2.3 and earlier.
42
     */
43
    public function gettree()
44
    {
45
        echo $this->preTree();
46
        parent::gettree();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class TreeDropdownField as the method gettree() does only exist in the following sub-classes of TreeDropdownField: OptionalTreeDropdownField. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
47
        echo self::$postTree;
48
    }
49
50
    /**
51
     * Get the whole tree of a part of the tree via an AJAX request with empty / none item prepended.
52
     *
53
     * @param SS_HTTPRequest $request
54
     *
55
     * @return string
56
     *                for version 2.4 and later
57
     */
58
    public function tree(SS_HTTPRequest $request)
59
    {
60
        if ($ID = (int) $request->latestparam('ID')) {
0 ignored issues
show
Unused Code introduced by
$ID 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...
61
            return parent::tree($request);
62
        } else {
63
            return $this->preTree().parent::tree($request).self::$postTree;
64
        }
65
    }
66
}
67