Completed
Pull Request — master (#17)
by Lhalaa
07:38 queued 06:20
created

PartialFormSubmission::canEdit()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
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 $member
103
     * @param array $context
104
     * @return bool
105
     */
106
    public function canCreate($member = null, $context = [])
107
    {
108
        return false;
109
    }
110
111
    /**
112
     * @param Member
113
     *
114
     * @return boolean|string
115
     */
116
    public function canView($member = null)
117
    {
118
        if ($this->UserDefinedForm()) {
119
            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 119 which is incompatible with the return type of the parent method SilverStripe\UserForms\M...\SubmittedForm::canView of type boolean.
Loading history...
120
        }
121
122
        return parent::canView($member);
123
    }
124
125
    /**
126
     * @param Member
127
     *
128
     * @return boolean|string
129
     */
130
    public function canEdit($member = null)
131
    {
132
        if ($this->UserDefinedForm()) {
133
            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 133 which is incompatible with the return type of the parent method SilverStripe\UserForms\M...\SubmittedForm::canEdit of type boolean.
Loading history...
134
        }
135
136
        return parent::canEdit($member);
137
    }
138
139
    /**
140
     * @param Member
141
     *
142
     * @return boolean|string
143
     */
144
    public function canDelete($member = null)
145
    {
146
        if ($this->UserDefinedForm()) {
147
            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 147 which is incompatible with the return type of the parent method SilverStripe\UserForms\M...ubmittedForm::canDelete of type boolean.
Loading history...
148
        }
149
150
        return parent::canDelete($member);
151
    }
152
153
    /**
154
     * Get the share link of the form
155
     *
156
     * @return string
157
     * @throws \Exception
158
     */
159
    public function getPartialLink()
160
    {
161
        if (!$this->isInDB()) {
162
            return '(none)';
163
        }
164
165
        $token = $this->getPartialToken();
166
167
        return Controller::join_links(
168
            Director::absoluteBaseURL(),
169
            'partial',
170
            $this->generateKey($token),
0 ignored issues
show
Bug introduced by
It seems like $token defined by $this->getPartialToken() on line 165 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...
171
            $token
172
        );
173
    }
174
175
    /**
176
     * Get the unique token for the share link
177
     *
178
     * @return bool|string|null
179
     * @throws \Exception
180
     */
181
    protected function getPartialToken()
182
    {
183
        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...
184
            $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...
185
            $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...
186
            $this->write();
187
        }
188
189
        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...
190
    }
191
192
    /**
193
     * Generate a new token
194
     *
195
     * @return bool|string
196
     * @throws \Exception
197
     */
198
    protected function generateToken()
199
    {
200
        $generator = new RandomGenerator();
201
202
        return substr($generator->randomToken('sha256'), 0, 16);
203
    }
204
205
    /**
206
     * Generate a key based on the share token salt
207
     *
208
     * @param string $token
209
     * @return mixed
210
     */
211
    public function generateKey($token)
212
    {
213
        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...
214
    }
215
216
    /**
217
     * Get the partial fields in array
218
     *
219
     * @return array
220
     */
221
    public function getFieldList()
222
    {
223
        $list = [];
224
        if ($this->PartialFields()->exists()) {
225
            foreach ($this->PartialFields() as $field) {
226
                $list[$field->Name] = $field->Value;
227
            }
228
        }
229
230
        return $list;
231
    }
232
}
233