doRestoreDatabaseBackup()   B
last analyzed

Complexity

Conditions 6
Paths 5

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 29
rs 8.8337
c 0
b 0
f 0
cc 6
nc 5
nop 2
1
<?php
2
3
class DatabasebackupLogDetailForm extends GridFieldDetailForm
4
{
5
}
6
7
class DatabasebackupLogDetailForm_ItemRequest extends GridFieldDetailForm_ItemRequest
8
{
9
    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...
10
        "ItemEditForm" => "ADMIN",
11
        "doDownload" => "ADMIN",
12
        'doRestoreDatabaseBackup' => "ADMIN"
13
    );
14
15
    public function ItemEditForm()
16
    {
17
        $form = parent::ItemEditForm();
18
        $actions = $this->record->getCMSActions();
19
        $oldActions = $form->Actions();
20
        foreach ($actions as $action) {
21
            $oldActions->push($action);
22
        }
23
        $form->setActions($oldActions);
0 ignored issues
show
Bug introduced by
It seems like $oldActions defined by $form->Actions() on line 19 can be null; however, Form::setActions() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
24
        return $form;
25
    }
26
27
    /**
28
     * run the action (separate method) and send the right message back
29
     *
30
     */
31
    public function doRestoreDatabaseBackup($data, $form)
0 ignored issues
show
Unused Code introduced by
The parameter $data is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
32
    {
33
        if (!$this->record->ID) {
34
            return new SS_HTTPResponse("Please pass an ID in the form content", 400);
35
        }
36
        $databaseToRestore = DatabasebackupLog::get()->byID($this->record->ID);
37
        if (!$databaseToRestore) {
38
            return new SS_HTTPResponse("backup #$id not found", 400);
0 ignored issues
show
Bug introduced by
The variable $id does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
39
        }
40
        $outcome = $this->restoreDatabaseBackup($databaseToRestore);
0 ignored issues
show
Compatibility introduced by
$databaseToRestore of type object<DataObject> is not a sub-type of object<DatabasebackupLog>. It seems like you assume a child class of the class DataObject to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
41
        if ($outcome) {
42
            $message = _t('Databasebackup.DB_RESTORED', 'Database Restored, please reload the entire site to continue...');
43
            $form->sessionMessage($message, 'good', false);
44
            return $this->getToplevelController()->redirectBack();
45
        } else {
46
            $message = _t('Databasebackup.DB_NOT_RESTORED', 'Database * NOT * Restored');
47
        }
48
        $toplevelController = $this->getToplevelController();
49
        if ($toplevelController && $toplevelController instanceof LeftAndMain) {
50
            $backForm = $toplevelController->getEditForm();
51
            $backForm->sessionMessage($message, 'good', false);
0 ignored issues
show
Bug introduced by
The method sessionMessage does only exist in CMSForm, but not in SS_HTTPResponse.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
52
        } else {
53
            $form->sessionMessage($message, 'good', false);
54
        }
55
        //when an item is deleted, redirect to the parent controller
56
        $controller = $this->getToplevelController();
57
        $controller->getRequest()->addHeader('X-Pjax', 'Content'); // Force a content refresh
58
        return $controller->redirect($this->getBacklink(), 302); //redirect back to admin section
59
    }
60
61
62
    /**
63
     * downloads the file
64
     * @param Array $data
65
     * @param Form $form
66
     */
67
    public function doDownload($data, $form)
0 ignored issues
show
Unused Code introduced by
The parameter $data is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
68
    {
69
        if (!$this->record->ID) {
70
            return new SS_HTTPResponse("Please pass an ID in the form content", 400);
71
        }
72
        $databaseToRestore = DatabasebackupLog::get()->byID($this->record->ID);
73
        if (!$databaseToRestore) {
74
            return new SS_HTTPResponse("backup #$id not found", 400);
0 ignored issues
show
Bug introduced by
The variable $id does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
75
        }
76
        if (!file_exists($databaseToRestore->FullLocation)) {
77
            return new SS_HTTPResponse("file #$id not found", 400);
78
        }
79
    }
80
81
    /**
82
     * copies back up files up one ...
83
     * returns true on success, false on failure
84
     *
85
     * @param DatabasebackupLog $databaseToRestore
86
     *
87
     * @return Boolean
88
     */
89
    private function restoreDatabaseBackup(DatabasebackupLog $databaseToRestore)
90
    {
91
        if (Permission::check("ADMIN")) {
92
            Config::inst()->update("DatabasebackupLog", "max_db_copies", Config::inst()->get("DatabasebackupLog", "max_db_copies") + 1);
93
            //firstly make a backup of the current state ...
94
            $obj = new DatabasebackupLog();
95
            $obj->Title = _t("DatabaseBackup.RESTORE_NOTE", "Additional backup before doing a database restore.");
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<DatabasebackupLog>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
96
            $obj->write();
97
            //make sure it still exists ...
98
            $databaseToRestore = DatabasebackupLog::get()->byID($databaseToRestore->ID);
99
            if ($databaseToRestore) {
100
                return $databaseToRestore->restoreDatabaseBackup();
101
            }
102
        }
103
        return false;
104
    }
105
}
106