Completed
Pull Request — master (#16)
by Simon
01:25
created

PartialSubmissionController   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 171
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 0
Metric Value
wmc 23
lcom 1
cbo 11
dl 0
loc 171
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
B savePartialSubmission() 0 46 7
A createOrUpdateSubmission() 0 18 3
A savePartialField() 0 17 4
A savePartialFile() 0 18 6
A uploadFile() 0 16 3
1
<?php
2
3
namespace Firesphere\PartialUserforms\Controllers;
4
5
use Firesphere\PartialUserforms\Models\PartialFieldSubmission;
6
use Firesphere\PartialUserforms\Models\PartialFileFieldSubmission;
7
use Firesphere\PartialUserforms\Models\PartialFormSubmission;
8
use SilverStripe\Assets\File;
9
use SilverStripe\Assets\Upload;
10
use SilverStripe\CMS\Controllers\ContentController;
11
use SilverStripe\Control\HTTPRequest;
12
use SilverStripe\ORM\DataObject;
13
use SilverStripe\ORM\ValidationException;
14
use SilverStripe\UserForms\Model\EditableFormField;
15
16
/**
17
 * Class PartialSubmissionController
18
 *
19
 * @package Firesphere\PartialUserforms\Controllers
20
 */
21
class PartialSubmissionController extends ContentController
22
{
23
    /**
24
     * Session key name
25
     */
26
    public const SESSION_KEY = 'PartialSubmissionID';
27
28
    /**
29
     * @var array
30
     */
31
    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...
32
        'save' => 'savePartialSubmission',
33
    ];
34
35
    /**
36
     * @var array
37
     */
38
    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...
39
        'savePartialSubmission',
40
    ];
41
42
    /**
43
     * @param HTTPRequest $request
44
     * @return bool|void
45
     * @throws ValidationException
46
     * @throws \SilverStripe\Control\HTTPResponse_Exception
47
     */
48
    public function savePartialSubmission(HTTPRequest $request)
49
    {
50
        if (!$request->isPOST()) {
51
            return $this->httpError(404);
52
        }
53
54
        $postVars = $request->postVars();
55
        $editableField = null;
56
57
        // We don't want SecurityID and/or the process Action stored as a thing
58
        unset($postVars['SecurityID'], $postVars['action_process']);
59
        $submissionID = $request->getSession()->get(self::SESSION_KEY);
60
61
        /** @var PartialFormSubmission $partialSubmission */
62
        $partialSubmission = PartialFormSubmission::get()->byID($submissionID);
63
64
        if (!$submissionID || !$partialSubmission) {
65
            $partialSubmission = PartialFormSubmission::create();
66
            // TODO: Set the Parent ID and Parent Class before write, this issue will create new submissions
67
            // every time the session expires when the user proceeds to the next step.
68
            // Also, saving a new submission without a parent creates an "AccordionItems" as parent class (first DataObject found)
69
            $submissionID = $partialSubmission->write();
70
        }
71
        $request->getSession()->set(self::SESSION_KEY, $submissionID);
72
        foreach ($postVars as $field => $value) {
73
            /** @var EditableFormField $editableField */
74
            $editableField = $this->createOrUpdateSubmission([
75
                'Name'            => $field,
76
                'Value'           => $value,
77
                'SubmittedFormID' => $submissionID
78
            ]);
79
        }
80
81
        if ($editableField instanceof EditableFormField && !$partialSubmission->UserDefinedFormID) {
82
            // Updates parent class to the correct DataObject
83
            $partialSubmission->update([
84
                'UserDefinedFormID'    => $editableField->Parent()->ID,
85
                'ParentID'             => $editableField->Parent()->ID,
86
                'ParentClass'          => $editableField->Parent()->ClassName,
87
                'UserDefinedFormClass' => $editableField->Parent()->ClassName
88
            ]);
89
            $partialSubmission->write();
90
        }
91
92
        return $partialSubmission->exists();
93
    }
94
95
    /**
96
     * @param $formData
97
     * @return DataObject|EditableFormField
98
     * @throws ValidationException
99
     */
100
    protected function createOrUpdateSubmission($formData)
101
    {
102
        $filter = [
103
            'Name'            => $formData['Name'],
104
            'SubmittedFormID' => $formData['SubmittedFormID'],
105
        ];
106
107
        /** @var EditableFormField $editableField */
108
        $editableField = EditableFormField::get()->filter(['Name' => $formData['Name']])->first();
109
        if ($editableField instanceof EditableFormField\EditableFileField) {
110
            $this->savePartialFile($formData, $filter, $editableField);
111
        } elseif ($editableField instanceof EditableFormField) {
112
            $this->savePartialField($formData, $filter, $editableField);
113
        }
114
115
        // Return the ParentID to link the PartialSubmission to it's proper thingy
116
        return $editableField;
117
    }
118
119
    /**
120
     * @param $formData
121
     * @param array $filter
122
     * @param EditableFormField $editableField
123
     * @throws ValidationException
124
     */
125
    protected function savePartialField($formData, array $filter, EditableFormField $editableField)
126
    {
127
        $exists = PartialFieldSubmission::get()->filter($filter)->first();
128
        if (is_array($formData['Value'])) {
129
            $formData['Value'] = implode(', ', $formData['Value']);
130
        }
131
        if ($editableField) {
132
            $formData['Title'] = $editableField->Title;
133
            $formData['ParentClass'] = $editableField->Parent()->ClassName;
134
        }
135
        if (!$exists) {
136
            $exists = PartialFieldSubmission::create($formData);
137
        } else {
138
            $exists->update($formData);
139
        }
140
        $exists->write();
141
    }
142
143
    /**
144
     * @param $formData
145
     * @param array $filter
146
     * @param EditableFormField\EditableFileField $editableField
147
     * @throws ValidationException
148
     * @throws Exception
149
     */
150
    protected function savePartialFile($formData, array $filter, EditableFormField\EditableFileField $editableField)
151
    {
152
        $partialFileSubmission = PartialFileFieldSubmission::get()->filter($filter)->first();
153
        $partialData = [];
154
        if (!$partialFileSubmission && $editableField) {
155
            $partialData['Title'] = $editableField->Title;
156
            $partialData['ParentClass'] = $editableField->Parent()->ClassName;
157
        }
158
        // Don't overwrite existing uploads
159
        if (!$partialFileSubmission ||
160
            (!$partialFileSubmission->UploadedFileID && is_array($formData['Value']))
161
        ) {
162
            $file = $this->uploadFile($partialData, $editableField);
163
            $formData['UploadedFileID'] = $file->ID ?? 0;
164
            $partialFileSubmission = PartialFileFieldSubmission::create($partialData);
165
        }
166
        $partialFileSubmission->write();
167
    }
168
169
    /**
170
     * @param array $formData
171
     * @param EditableFormField\EditableFileField $field
172
     * @return bool|File
173
     * @throws \Exception
174
     */
175
    protected function uploadFile($formData, $field)
176
    {
177
        if (!empty($formData['Value']['name'])) {
178
            $foldername = $field->getFormField()->getFolderName();
179
180
            // create the file from post data
181
            $upload = Upload::create();
182
            $file = File::create();
183
            $file->ShowInSearch = 0;
184
            if ($upload->loadIntoFile($formData['Value'], $file, $foldername)) {
185
                return $file;
186
            }
187
        }
188
189
        return false;
190
    }
191
}
192