Completed
Pull Request — master (#13)
by Lhalaa
01:56
created

PartialFormSubmission::getPartialToken()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
namespace Firesphere\PartialUserforms\Models;
4
5
use SilverStripe\Control\Controller;
6
use SilverStripe\Control\Director;
7
use SilverStripe\Forms\FieldList;
8
use SilverStripe\Forms\GridField\GridField;
9
use SilverStripe\Forms\GridField\GridFieldButtonRow;
10
use SilverStripe\Forms\GridField\GridFieldConfig;
11
use SilverStripe\Forms\GridField\GridFieldDataColumns;
12
use SilverStripe\Forms\GridField\GridFieldExportButton;
13
use SilverStripe\Forms\GridField\GridFieldPrintButton;
14
use SilverStripe\Forms\ReadonlyField;
15
use SilverStripe\ORM\DataList;
16
use SilverStripe\ORM\DataObject;
17
use SilverStripe\Security\Member;
18
use SilverStripe\Security\RandomGenerator;
19
use SilverStripe\UserForms\Model\Submission\SubmittedForm;
20
use SilverStripe\UserForms\Model\UserDefinedForm;
21
22
/**
23
 * Class \Firesphere\PartialUserforms\Models\PartialFormSubmission
24
 *
25
 * @property boolean $IsSend
26
 * @property int $UserDefinedFormID
27
 * @method DataObject UserDefinedForm()
28
 * @method DataList|PartialFieldSubmission[] PartialFields()
29
 */
30
class PartialFormSubmission extends SubmittedForm
31
{
32
    private static $table_name = 'PartialFormSubmission';
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...
33
34
    private static $db = [
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...
35
        'IsSend' => 'Boolean(false)',
36
        'TokenSalt' => 'Varchar(16)',
37
        'Token' => 'Varchar(16)',
38
    ];
39
40
    private static $has_one = [
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...
41
        'UserDefinedForm' => UserDefinedForm::class
42
    ];
43
44
    private static $has_many = [
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...
45
        'PartialFields' => PartialFieldSubmission::class
46
    ];
47
48
    private static $cascade_deletes = [
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...
49
        'PartialFields'
50
    ];
51
52
    /**
53
     * @var array
54
     */
55
    private static $summary_fields = [
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...
56
        'ID' => 'ID',
57
        'PartialLink' => 'Link',
58
        'Created' => 'Created',
59
        'LastEdited' => 'Last Edited',
60
    ];
61
62
    public function getCMSFields()
63
    {
64
        /** @var FieldList $fields */
65
        $fields = parent::getCMSFields();
66
        $fields->removeByName(['Values', 'IsSend', 'PartialFields', 'TokenSalt', 'Token', 'UserDefinedFormID', 'Submitter']);
67
68
        $partialFields = GridField::create(
69
            'PartialFields',
70
            _t(static::class . '.PARTIALFIELDS', 'Partial fields'),
71
            $this->PartialFields()->sort('Created', 'ASC')
72
        );
73
74
        $exportColumns =[
75
            'Title'       => 'Title',
76
            'ExportValue' => 'Value'
77
        ];
78
79
        $config = new GridFieldConfig();
80
        $config->addComponent(new GridFieldDataColumns());
81
        $config->addComponent(new GridFieldButtonRow('after'));
82
        $config->addComponent(new GridFieldExportButton('buttons-after-left', $exportColumns));
83
        $config->addComponent(new GridFieldPrintButton('buttons-after-left'));
84
        $partialFields->setConfig($config);
85
86
        $fields->addFieldsToTab(
87
            'Root.Main',
88
            [
89
                ReadonlyField::create('ReadonlyPartialLink', 'Partial Link', $this->getPartialLink()),
90
                $partialFields
91
            ]
92
        );
93
94
        return $fields;
95
    }
96
97
    public function getParent()
98
    {
99
        return $this->UserDefinedForm();
100
    }
101
102
    /**
103
     * @param Member
104
     *
105
     * @return boolean|string
106
     */
107
    public function canCreate($member = null, $context = [])
108
    {
109
        if ($this->UserDefinedForm()) {
110
            return $this->UserDefinedForm()->canCreate($member, $context);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->UserDefinedForm()...ate($member, $context); of type boolean|string adds the type string to the return on line 110 which is incompatible with the return type of the parent method SilverStripe\UserForms\M...ubmittedForm::canCreate of type boolean.
Loading history...
111
        }
112
113
        return parent::canCreate($member);
114
    }
115
116
    /**
117
     * @param Member
118
     *
119
     * @return boolean|string
120
     */
121
    public function canView($member = null)
122
    {
123
        if ($this->UserDefinedForm()) {
124
            return $this->UserDefinedForm()->canView($member);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->UserDefinedForm()->canView($member); of type boolean|string adds the type string to the return on line 124 which is incompatible with the return type of the parent method SilverStripe\UserForms\M...\SubmittedForm::canView of type boolean.
Loading history...
125
        }
126
127
        return parent::canView($member);
128
    }
129
130
    /**
131
     * @param Member
132
     *
133
     * @return boolean|string
134
     */
135
    public function canEdit($member = null)
136
    {
137
        if ($this->UserDefinedForm()) {
138
            return $this->UserDefinedForm()->canEdit($member);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->UserDefinedForm()->canEdit($member); of type boolean|string adds the type string to the return on line 138 which is incompatible with the return type of the parent method SilverStripe\UserForms\M...\SubmittedForm::canEdit of type boolean.
Loading history...
139
        }
140
141
        return parent::canEdit($member);
142
    }
143
144
    /**
145
     * @param Member
146
     *
147
     * @return boolean|string
148
     */
149
    public function canDelete($member = null)
150
    {
151
        if ($this->UserDefinedForm()) {
152
            return $this->UserDefinedForm()->canDelete($member);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->UserDefinedForm()->canDelete($member); of type boolean|string adds the type string to the return on line 152 which is incompatible with the return type of the parent method SilverStripe\UserForms\M...ubmittedForm::canDelete of type boolean.
Loading history...
153
        }
154
155
        return parent::canDelete($member);
156
    }
157
158
    /**
159
     * Get the share link of the form
160
     *
161
     * @return string
162
     * @throws \Exception
163
     */
164
    public function getPartialLink()
165
    {
166
        if (!$this->isInDB()) {
167
            return '(none)';
168
        }
169
170
        $token = $this->getPartialToken();
171
172
        return Controller::join_links(
173
            Director::absoluteBaseURL(),
174
            'partial',
175
            $this->generateKey($token),
0 ignored issues
show
Bug introduced by
It seems like $token defined by $this->getPartialToken() on line 170 can also be of type boolean or null; however, Firesphere\PartialUserfo...bmission::generateKey() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
176
            $token
177
        );
178
    }
179
180
    /**
181
     * Get the unique token for the share link
182
     *
183
     * @return bool|string|null
184
     * @throws \Exception
185
     */
186
    protected function getPartialToken()
187
    {
188
        if (!$this->TokenSalt) {
0 ignored issues
show
Documentation introduced by
The property TokenSalt 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...
189
            $this->TokenSalt = $this->generateToken();
0 ignored issues
show
Documentation introduced by
The property TokenSalt does not exist on object<Firesphere\Partia...\PartialFormSubmission>. 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...
190
            $this->Token = $this->generateToken();
0 ignored issues
show
Documentation introduced by
The property Token does not exist on object<Firesphere\Partia...\PartialFormSubmission>. 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...
191
            $this->write();
192
        }
193
194
        return $this->Token;
0 ignored issues
show
Documentation introduced by
The property Token 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...
195
    }
196
197
    /**
198
     * Generate a new token
199
     *
200
     * @return bool|string
201
     * @throws \Exception
202
     */
203
    protected function generateToken()
204
    {
205
        $generator = new RandomGenerator();
206
207
        return substr($generator->randomToken('sha256'), 0, 16);
208
    }
209
210
    /**
211
     * Generate a key based on the share token salt
212
     *
213
     * @param string $token
214
     * @return mixed
215
     */
216
    public function generateKey($token)
217
    {
218
        return hash_pbkdf2('sha256', $token, $this->PartialTokenSalt, 1000, 16);
0 ignored issues
show
Documentation introduced by
The property PartialTokenSalt 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...
219
    }
220
}
221