Completed
Push — master ( c07b10...3eba7c )
by Simon
13s
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
21
/**
22
 * Class \Firesphere\PartialUserforms\Models\PartialFormSubmission
23
 *
24
 * @property boolean $IsSend
25
 * @property int $UserDefinedFormID
26
 * @method DataObject UserDefinedForm()
27
 * @method DataList|PartialFieldSubmission[] PartialFields()
28
 */
29
class PartialFormSubmission extends SubmittedForm
30
{
31
    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...
32
33
    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...
34
        'IsSend'    => 'Boolean(false)',
35
        'TokenSalt' => 'Varchar(16)',
36
        'Token'     => 'Varchar(16)',
37
    ];
38
39
    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...
40
        'UserDefinedForm' => DataObject::class
41
    ];
42
43
    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...
44
        'PartialFields' => PartialFieldSubmission::class
45
    ];
46
47
    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...
48
        'PartialFields'
49
    ];
50
51
    /**
52
     * @var array
53
     */
54
    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...
55
        'ID'            => 'ID',
56
        'PartialLink'   => 'Link',
57
        'Created'       => 'Created',
58
        'LastEdited'    => 'Last Edited',
59
    ];
60
61
    public function getCMSFields()
62
    {
63
        /** @var FieldList $fields */
64
        $fields = parent::getCMSFields();
65
        $fields->removeByName(['Values', 'IsSend', 'PartialFields', 'TokenSalt', 'Token', 'UserDefinedFormID', 'Submitter']);
66
67
        $partialFields = GridField::create(
68
            'PartialFields',
69
            _t(static::class . '.PARTIALFIELDS', 'Partial fields'),
70
            $this->PartialFields()->sort('Created', 'ASC')
71
        );
72
73
        $exportColumns =[
74
            'Title'       => 'Title',
75
            'ExportValue' => 'Value'
76
        ];
77
78
        $config = new GridFieldConfig();
79
        $config->addComponent(new GridFieldDataColumns());
80
        $config->addComponent(new GridFieldButtonRow('after'));
81
        $config->addComponent(new GridFieldExportButton('buttons-after-left', $exportColumns));
82
        $config->addComponent(new GridFieldPrintButton('buttons-after-left'));
83
        $partialFields->setConfig($config);
84
85
        $fields->addFieldsToTab(
86
            'Root.Main',
87
            [
88
                ReadonlyField::create('ReadonlyPartialLink', 'Partial Link', $this->getPartialLink()),
89
                $partialFields
90
            ]
91
        );
92
93
        return $fields;
94
    }
95
96
    public function getParent()
97
    {
98
        return $this->UserDefinedForm();
99
    }
100
101
    /**
102
     * @param Member
103
     *
104
     * @return boolean|string
105
     */
106
    public function canCreate($member = null, $context = [])
107
    {
108
        if ($this->UserDefinedForm()) {
109
            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 109 which is incompatible with the return type of the parent method SilverStripe\UserForms\M...ubmittedForm::canCreate of type boolean.
Loading history...
110
        }
111
112
        return parent::canCreate($member);
113
    }
114
115
    /**
116
     * @param Member
117
     *
118
     * @return boolean|string
119
     */
120
    public function canView($member = null)
121
    {
122
        if ($this->UserDefinedForm()) {
123
            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 123 which is incompatible with the return type of the parent method SilverStripe\UserForms\M...\SubmittedForm::canView of type boolean.
Loading history...
124
        }
125
126
        return parent::canView($member);
127
    }
128
129
    /**
130
     * @param Member
131
     *
132
     * @return boolean|string
133
     */
134
    public function canEdit($member = null)
135
    {
136
        if ($this->UserDefinedForm()) {
137
            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 137 which is incompatible with the return type of the parent method SilverStripe\UserForms\M...\SubmittedForm::canEdit of type boolean.
Loading history...
138
        }
139
140
        return parent::canEdit($member);
141
    }
142
143
    /**
144
     * @param Member
145
     *
146
     * @return boolean|string
147
     */
148
    public function canDelete($member = null)
149
    {
150
        if ($this->UserDefinedForm()) {
151
            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 151 which is incompatible with the return type of the parent method SilverStripe\UserForms\M...ubmittedForm::canDelete of type boolean.
Loading history...
152
        }
153
154
        return parent::canDelete($member);
155
    }
156
157
    /**
158
     * Get the share link of the form
159
     *
160
     * @return string
161
     * @throws \Exception
162
     */
163
    public function getPartialLink()
164
    {
165
        if (!$this->isInDB()) {
166
            return '(none)';
167
        }
168
169
        $token = $this->getPartialToken();
170
171
        return Controller::join_links(
172
            Director::absoluteBaseURL(),
173
            'partial',
174
            $this->generateKey($token),
0 ignored issues
show
Bug introduced by
It seems like $token defined by $this->getPartialToken() on line 169 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...
175
            $token
176
        );
177
    }
178
179
    /**
180
     * Get the unique token for the share link
181
     *
182
     * @return bool|string|null
183
     * @throws \Exception
184
     */
185
    protected function getPartialToken()
186
    {
187
        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...
188
            $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...
189
            $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...
190
            $this->write();
191
        }
192
193
        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...
194
    }
195
196
    /**
197
     * Generate a new token
198
     *
199
     * @return bool|string
200
     * @throws \Exception
201
     */
202
    protected function generateToken()
203
    {
204
        $generator = new RandomGenerator();
205
206
        return substr($generator->randomToken('sha256'), 0, 16);
207
    }
208
209
    /**
210
     * Generate a key based on the share token salt
211
     *
212
     * @param string $token
213
     * @return mixed
214
     */
215
    public function generateKey($token)
216
    {
217
        return hash_pbkdf2('sha256', $token, $this->TokenSalt, 1000, 16);
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...
218
    }
219
}
220