Completed
Pull Request — master (#12)
by Simon
08:50
created

PartialUserFormController::partial()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 48

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 30.7665

Importance

Changes 0
Metric Value
dl 0
loc 48
ccs 6
cts 28
cp 0.2143
rs 8.2012
c 0
b 0
f 0
cc 7
nc 4
nop 1
crap 30.7665
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 Firesphere\PartialUserforms\Forms\PasswordForm;
10
use SilverStripe\Control\HTTPResponse;
11
use SilverStripe\Control\HTTPResponse_Exception;
12
use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware;
13
use SilverStripe\Forms\Form;
14
use SilverStripe\ORM\DataObject;
15
use SilverStripe\ORM\FieldType\DBField;
16
use SilverStripe\ORM\FieldType\DBHTMLText;
17
use SilverStripe\UserForms\Control\UserDefinedFormController;
18
use SilverStripe\UserForms\Model\UserDefinedForm;
19
20
/**
21
 * Class PartialUserFormController
22
 *
23
 * @package Firesphere\PartialUserforms\Controllers
24
 */
25
class PartialUserFormController extends UserDefinedFormController
26
{
27
    /**
28
     * @var array
29
     */
30
    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...
31
        '$Key/$Token' => 'partial',
32
    ];
33
    /**
34
     * @var array
35
     */
36
    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...
37
        'partial',
38
    ];
39
    /**
40
     * @var PartialFormSubmission
41
     */
42
    protected $partialFormSubmission;
43
44
    /**
45 3
     * Partial form
46
     *
47
     * @param HTTPRequest $request
48 3
     * @return HTTPResponse|DBHTMLText|void
49
     * @throws HTTPResponse_Exception
50 3
     * @throws Exception
51 3
     */
52 3
    public function partial(HTTPRequest $request)
53 1
    {
54
        // Ensure this URL doesn't get picked up by HTTP caches
55
        HTTPCacheControlMiddleware::singleton()->disableCache();
56
57 2
        /** @var PartialFormSubmission $partial */
58 2
        $partial = $this->validateToken($request);
59
        if ($this->data()->PasswordProtected &&
60 2
            $request->getSession()->get(PasswordForm::PASSWORD_SESSION_KEY) !== $partial->ID
61
        ) {
62 2
            return $this->redirect('verify');
63
        }
64
        $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
        /** @var self $controller */
66
        $controller = self::create($record);
67
        $controller->doInit();
68
69
        /** @var Form $form */
70
        $form = $controller->Form();
71
        $fields = $partial->PartialFields()->map('Name', 'Value')->toArray();
72
        $form->loadDataFrom($fields);
73
74
        // Copied from {@link UserDefinedFormController}
75
        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...
76
            $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...
77
            if ($hasLocation) {
78
                /** @see Requirements_Backend::escapeReplacement */
79
                $formEscapedForRegex = addcslashes($form->forTemplate(), '\\$');
80
                $content = preg_replace(
81
                    '/(<p[^>]*>)?\\$UserDefinedForm(<\\/p>)?/i',
82
                    $formEscapedForRegex,
83
                    $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...
84
                );
85
86
                return $controller->customise([
87
                    'Content'     => DBField::create_field('HTMLText', $content),
88
                    'Form'        => '',
89
                    'PartialLink' => $partial->getPartialLink()
90
                ])->renderWith([static::class, Page::class]);
91
            }
92
        }
93
94
        return $controller->customise([
95
            '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...
96
            'Form'        => $form,
97
            'PartialLink' => $partial->getPartialLink()
98
        ])->renderWith([static::class, Page::class]);
99
    }
100
101
    /**
102
     * A little abstraction to be more readable
103
     *
104
     * @param HTTPRequest $request
105
     * @return PartialFormSubmission|void
106
     * @throws HTTPResponse_Exception
107
     */
108
    public function validateToken($request)
109
    {
110
        $key = $request->param('Key');
111
        $token = $request->param('Token');
112
        if (!$key || !$token) {
113
            return $this->httpError(404);
114
        }
115
116
        /** @var PartialFormSubmission $partial */
117
        $partial = PartialFormSubmission::get()->find('Token', $token);
118
        if (!$token ||
119
            !$partial ||
120
            !$partial->UserDefinedFormID ||
121
            !hash_equals($partial->generateKey($token), $key)
122
        ) {
123
            return $this->httpError(404);
124
        }
125
126
        $sessionKey = PartialSubmissionController::SESSION_KEY;
127
128
        // Set the session if the last session has expired
129
        if (!$request->getSession()->get($sessionKey)) {
130
            $request->getSession()->set($sessionKey, $partial->ID);
131
        }
132
133
        return $partial;
134
    }
135
136
    /**
137
     * @return PartialFormSubmission
138
     */
139
    public function getPartialFormSubmission(): PartialFormSubmission
140
    {
141
        return $this->partialFormSubmission;
142
    }
143
144
    /**
145
     * @param PartialFormSubmission $partialFormSubmission
146
     */
147
    public function setPartialFormSubmission(PartialFormSubmission $partialFormSubmission): void
148
    {
149
        $this->partialFormSubmission = $partialFormSubmission;
150
    }
151
}
152