Completed
Pull Request — master (#31)
by Lhalaa
04:10
created

PartialUserFormController::partial()   B

Complexity

Conditions 10
Paths 8

Size

Total Lines 57

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 31
CRAP Score 10.2678

Importance

Changes 0
Metric Value
dl 0
loc 57
ccs 31
cts 36
cp 0.8611
rs 7.0715
c 0
b 0
f 0
cc 10
nc 8
nop 1
crap 10.2678

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 Firesphere\PartialUserforms\Controllers;
4
5
use Exception;
6
use Firesphere\PartialUserforms\Models\PartialFormSubmission;
7
use Page;
8
use SilverStripe\Control\HTTPRequest;
9
use SilverStripe\Control\HTTPResponse_Exception;
10
use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware;
11
use SilverStripe\Forms\Form;
12
use SilverStripe\Forms\HiddenField;
13
use SilverStripe\ORM\DataObject;
14
use SilverStripe\ORM\FieldType\DBField;
15
use SilverStripe\ORM\FieldType\DBHTMLText;
16
use SilverStripe\UserForms\Control\UserDefinedFormController;
17
18
/**
19
 * Class PartialUserFormController
20
 *
21
 * @package Firesphere\PartialUserforms\Controllers
22
 */
23
class PartialUserFormController extends UserDefinedFormController
24
{
25
    /**
26
     * @var array
27
     */
28
    private static $url_handlers = [
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...
29
        '$Key/$Token' => 'partial',
30
    ];
31
32
    /**
33
     * @var array
34
     */
35
    private static $allowed_actions = [
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...
36
        'partial',
37
    ];
38
39
    /**
40
     * Partial form
41
     *
42
     * @param HTTPRequest $request
43
     * @return DBHTMLText|void
44
     * @throws HTTPResponse_Exception
45
     * @throws Exception
46
     */
47 5
    public function partial(HTTPRequest $request)
48
    {
49
        // Ensure this URL doesn't get picked up by HTTP caches
50 5
        HTTPCacheControlMiddleware::singleton()->disableCache();
51
52 5
        $key = $request->param('Key');
53 5
        $token = $request->param('Token');
54 5
        if (!$key || !$token) {
55 1
            return $this->httpError(404);
56
        }
57
58 4
        $partial = PartialFormSubmission::validateKeyToken($key, $token);
59 4
        if ($partial === false) {
60 3
            return $this->httpError(404);
61
        }
62
63
        // Set data record and load the form
64 2
        $record = DataObject::get_by_id($partial->UserDefinedFormClass, $partial->UserDefinedFormID);
0 ignored issues
show
Documentation introduced by
The property UserDefinedFormClass does not exist on object<Firesphere\Partia...\PartialFormSubmission>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read 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.");
        }
    }

}

If the property has read access only, you can use the @property-read 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...
65 2
        $controller = parent::create($record);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (create() instead of partial()). Are you sure this is correct? If so, you might want to change this to $this->create().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
66 2
        $controller->doInit();
67
68
        // Set the session if the last session has expired or another submission has started
69 2
        $sessionID = $request->getSession()->get(PartialSubmissionController::SESSION_KEY);
70 2
        if (!$sessionID || $sessionID !==  $partial->ID) {
71 2
            $request->getSession()->set(PartialSubmissionController::SESSION_KEY, $partial->ID);
72
        }
73
74 2
        $form = $controller->Form();
75 2
        $form->loadDataFrom($partial->getFields());
0 ignored issues
show
Documentation Bug introduced by
The method loadDataFrom does not exist on object<Firesphere\Partia...tialUserFormController>? 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...
76 2
        $this->populateData($form, $partial);
0 ignored issues
show
Documentation introduced by
$form is of type object<Firesphere\Partia...tialUserFormController>, but the function expects a object<SilverStripe\Forms\Form>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
77
78
        // Copied from {@link UserDefinedFormController}
79 2
        if ($controller->Content && $form && !$controller->config()->disable_form_content_shortcode) {
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<Firesphere\Partia...tialUserFormController>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read 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.");
        }
    }

}

If the property has read access only, you can use the @property-read 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...
80 2
            $hasLocation = stristr($controller->Content, '$UserDefinedForm');
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<Firesphere\Partia...tialUserFormController>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read 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.");
        }
    }

}

If the property has read access only, you can use the @property-read 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...
81 2
            if ($hasLocation) {
82
                /** @see Requirements_Backend::escapeReplacement */
83 2
                $formEscapedForRegex = addcslashes($form->forTemplate(), '\\$');
0 ignored issues
show
Documentation Bug introduced by
The method forTemplate does not exist on object<Firesphere\Partia...tialUserFormController>? 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...
84 2
                $content = preg_replace(
85 2
                    '/(<p[^>]*>)?\\$UserDefinedForm(<\\/p>)?/i',
86 2
                    $formEscapedForRegex,
87 2
                    $controller->Content
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<Firesphere\Partia...tialUserFormController>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read 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.");
        }
    }

}

If the property has read access only, you can use the @property-read 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...
88
                );
89
90 2
                return $controller->customise([
91 2
                    'Content'     => DBField::create_field('HTMLText', $content),
92 2
                    'Form'        => '',
93 2
                    'PartialLink' => $partial->getPartialLink()
94 2
                ])->renderWith([static::class, Page::class]);
95
            }
96
        }
97
98
        return $controller->customise([
99
            'Content'     => DBField::create_field('HTMLText', $controller->Content),
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<Firesphere\Partia...tialUserFormController>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read 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.");
        }
    }

}

If the property has read access only, you can use the @property-read 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...
100
            'Form'        => $form,
101
            'PartialLink' => $partial->getPartialLink()
102
        ])->renderWith([static::class, Page::class]);
103
    }
104
105
    /**
106
     * Add partial submission and set the uploaded filenames as right title of the file fields
107
     *
108
     * @param Form $form
109
     * @param PartialFormSubmission $partial
110
     */
111 2
    protected function populateData($form, $partial)
112
    {
113 2
        $fields = $form->Fields();
114
        // Add partial submission ID
115 2
        $fields->push(
116 2
            HiddenField::create(
117 2
                'PartialID',
118 2
                null,
119 2
                $partial->ID
120
            )
121
        );
122
123
        // Populate files
124 2
        $uploads = $partial->PartialUploads()->filter([
125 2
            'UploadedFileID:not'=> null
126
        ]);
127
128 2
        if (!$uploads->exists()) {
129
            return;
130
        }
131
132 2
        foreach ($uploads as $upload) {
133 2
            $fields->dataFieldByName($upload->Name)
134 2
                ->setRightTitle(
135 2
                    sprintf(
136 2
                        'Uploaded: %s (Attach a new file to replace the uploaded file)',
137 2
                        $upload->UploadedFile()->Name
138
                    )
139
                );
140
        }
141 2
    }
142
}
143