These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace SilverStripe\Comments\Forms; |
||
4 | |||
5 | use SilverStripe\Control\HTTPResponse; |
||
6 | use SilverStripe\Forms\CompositeField; |
||
7 | use SilverStripe\Forms\EmailField; |
||
8 | use SilverStripe\Forms\FieldList; |
||
9 | use SilverStripe\Forms\Form; |
||
10 | use SilverStripe\Forms\FormAction; |
||
11 | use SilverStripe\Forms\HiddenField; |
||
12 | use SilverStripe\Forms\ReadonlyField; |
||
13 | use SilverStripe\Forms\RequiredFields; |
||
14 | use SilverStripe\Forms\TextareaField; |
||
15 | use SilverStripe\Forms\TextField; |
||
16 | use SilverStripe\Security\Member; |
||
17 | use SilverStripe\Control\Cookie; |
||
18 | use SilverStripe\Core\Convert; |
||
19 | use SilverStripe\Security\Security; |
||
20 | use SilverStripe\Comments\Model\Comment; |
||
21 | use SilverStripe\Control\Controller; |
||
22 | use SilverStripe\Comments\Controllers\CommentingController; |
||
23 | use SilverStripe\Core\Config\Config; |
||
24 | |||
25 | class CommentForm extends Form |
||
26 | { |
||
27 | /** |
||
28 | * @param string $name |
||
29 | * @param CommentingController $controller |
||
30 | */ |
||
31 | public function __construct($name, CommentingController $controller) |
||
32 | { |
||
33 | $usePreview = $controller->getOption('use_preview'); |
||
34 | $nameRequired = _t('CommentInterface.YOURNAME_MESSAGE_REQUIRED', 'Please enter your name'); |
||
35 | $emailRequired = _t('CommentInterface.EMAILADDRESS_MESSAGE_REQUIRED', 'Please enter your email address'); |
||
36 | $emailInvalid = _t('CommentInterface.EMAILADDRESS_MESSAGE_EMAIL', 'Please enter a valid email address'); |
||
37 | $urlInvalid = _t('CommentInterface.COMMENT_MESSAGE_URL', 'Please enter a valid URL'); |
||
38 | $commentRequired = _t('CommentInterface.COMMENT_MESSAGE_REQUIRED', 'Please enter your comment'); |
||
39 | |||
40 | $fields = FieldList::create( |
||
41 | $dataFields = CompositeField::create( |
||
42 | // Name |
||
43 | $a = TextField::create('Name', _t('CommentInterface.YOURNAME', 'Your name')) |
||
44 | ->setCustomValidationMessage($nameRequired) |
||
45 | ->setAttribute('data-msg-required', $nameRequired), |
||
46 | |||
47 | EmailField::create( |
||
48 | 'Email', |
||
49 | _t('SilverStripe\\Comments\\Controllers\\CommentingController.EMAILADDRESS', 'Your email address (will not be published)') |
||
50 | ) |
||
51 | ->setCustomValidationMessage($emailRequired) |
||
52 | ->setAttribute('data-msg-required', $emailRequired) |
||
53 | ->setAttribute('data-msg-email', $emailInvalid) |
||
54 | ->setAttribute('data-rule-email', true), |
||
0 ignored issues
–
show
|
|||
55 | // Url |
||
56 | TextField::create('URL', _t('SilverStripe\\Comments\\Controllers\\CommentingController.WEBSITEURL', 'Your website URL')) |
||
57 | ->setAttribute('data-msg-url', $urlInvalid) |
||
58 | ->setAttribute('data-rule-url', true), |
||
0 ignored issues
–
show
true is of type boolean , but the function expects a string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
59 | // Comment |
||
60 | TextareaField::create('Comment', _t('SilverStripe\\Comments\\Controllers\\CommentingController.COMMENTS', 'Comments')) |
||
61 | ->setCustomValidationMessage($commentRequired) |
||
62 | ->setAttribute('data-msg-required', $commentRequired) |
||
63 | ), |
||
64 | HiddenField::create('ParentID'), |
||
65 | HiddenField::create('ParentClassName'), |
||
66 | HiddenField::create('ReturnURL'), |
||
67 | HiddenField::create('ParentCommentID') |
||
68 | ); |
||
69 | |||
70 | // Preview formatted comment. Makes most sense when shortcodes or |
||
71 | // limited HTML is allowed. Populated by JS/Ajax. |
||
72 | if ($usePreview) { |
||
73 | $fields->insertAfter( |
||
74 | ReadonlyField::create('PreviewComment', _t('CommentInterface.PREVIEWLABEL', 'Preview')) |
||
75 | ->setAttribute('style', 'display: none'), // enable through JS |
||
76 | 'Comment' |
||
0 ignored issues
–
show
'Comment' is of type string , but the function expects a object<SilverStripe\Forms\FormField> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
77 | ); |
||
78 | } |
||
79 | |||
80 | $dataFields->addExtraClass('data-fields'); |
||
81 | |||
82 | // save actions |
||
83 | $actions = FieldList::create( |
||
84 | $postAction = new FormAction('doPostComment', _t('CommentInterface.POST', 'Post')) |
||
85 | ); |
||
86 | |||
87 | if ($usePreview) { |
||
88 | $actions->push( |
||
89 | FormAction::create('doPreviewComment', _t('CommentInterface.PREVIEW', 'Preview')) |
||
90 | ->addExtraClass('action-minor') |
||
91 | ->setAttribute('style', 'display: none') // enable through JS |
||
92 | ); |
||
93 | } |
||
94 | |||
95 | $required = new RequiredFields( |
||
96 | $controller->config()->required_fields |
||
97 | ); |
||
98 | |||
99 | parent::__construct($controller, $name, $fields, $actions, $required); |
||
100 | |||
101 | |||
102 | // if the record exists load the extra required data |
||
103 | if ($record = $controller->getOwnerRecord()) { |
||
104 | // Load member data |
||
105 | $member = Member::currentUser(); |
||
0 ignored issues
–
show
The method
SilverStripe\Security\Member::currentUser() has been deprecated with message: 5.0.0 use Security::getCurrentUser()
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
106 | if (($record->CommentsRequireLogin || $record->PostingRequiredPermission) && $member) { |
||
107 | $fields = $this->Fields(); |
||
108 | |||
109 | $fields->removeByName('Name'); |
||
110 | $fields->removeByName('Email'); |
||
111 | $fields->insertBefore( |
||
112 | new ReadonlyField( |
||
113 | 'NameView', |
||
114 | _t('CommentInterface.YOURNAME', 'Your name'), |
||
115 | $member->getName() |
||
116 | ), |
||
117 | 'URL' |
||
0 ignored issues
–
show
'URL' is of type string , but the function expects a object<SilverStripe\Forms\FormField> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
118 | ); |
||
119 | $fields->push(new HiddenField('Name', '', $member->getName())); |
||
120 | $fields->push(new HiddenField('Email', '', $member->Email)); |
||
121 | } |
||
122 | |||
123 | // we do not want to read a new URL when the form has already been submitted |
||
124 | // which in here, it hasn't been. |
||
125 | $this->loadDataFrom(array( |
||
126 | 'ParentID' => $record->ID, |
||
127 | 'ReturnURL' => $controller->getRequest()->getURL(), |
||
128 | 'ParentClassName' => $controller->getParentClass() |
||
129 | )); |
||
130 | } |
||
131 | |||
132 | // Set it so the user gets redirected back down to the form upon form fail |
||
133 | $this->setRedirectToFormOnValidationError(true); |
||
134 | |||
135 | // load any data from the cookies |
||
136 | if ($data = Cookie::get('CommentsForm_UserData')) { |
||
137 | $data = Convert::json2array($data); |
||
138 | |||
139 | $this->loadDataFrom(array( |
||
140 | 'Name' => isset($data['Name']) ? $data['Name'] : '', |
||
141 | 'URL' => isset($data['URL']) ? $data['URL'] : '', |
||
142 | 'Email' => isset($data['Email']) ? $data['Email'] : '' |
||
143 | )); |
||
144 | |||
145 | // allow previous value to fill if comment not stored in cookie (i.e. validation error) |
||
146 | $prevComment = Cookie::get('CommentsForm_Comment'); |
||
147 | |||
148 | if ($prevComment && $prevComment != '') { |
||
0 ignored issues
–
show
The expression
$prevComment of type string|null is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
Loading history...
|
|||
149 | $this->loadDataFrom(array('Comment' => $prevComment)); |
||
150 | } |
||
151 | } |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * @param array $data |
||
156 | * @param Form $form |
||
157 | * @return HTTPResponse |
||
158 | */ |
||
159 | public function doPreviewComment($data, $form) |
||
160 | { |
||
161 | $data['IsPreview'] = 1; |
||
162 | |||
163 | return $this->doPostComment($data, $form); |
||
164 | } |
||
165 | |||
166 | /** |
||
167 | * Process which creates a {@link Comment} once a user submits a comment from this form. |
||
168 | * |
||
169 | * @param array $data |
||
170 | * @param Form $form |
||
171 | * @return HTTPResponse |
||
172 | */ |
||
173 | public function doPostComment($data, $form) |
||
174 | { |
||
175 | // Load class and parent from data |
||
176 | if (isset($data['ParentClassName'])) { |
||
177 | $this->controller->setParentClass($data['ParentClassName']); |
||
178 | } |
||
179 | if (isset($data['ParentID']) && ($class = $this->controller->getParentClass())) { |
||
180 | $this->controller->setOwnerRecord($class::get()->byID($data['ParentID'])); |
||
181 | } |
||
182 | if (!$this->controller->getOwnerRecord()) { |
||
183 | return $this->getRequestHandler()->httpError(404); |
||
184 | } |
||
185 | |||
186 | // cache users data |
||
187 | Cookie::set('CommentsForm_UserData', Convert::raw2json($data)); |
||
188 | Cookie::set('CommentsForm_Comment', $data['Comment']); |
||
189 | |||
190 | // extend hook to allow extensions. Also see onAfterPostComment |
||
191 | $this->controller->extend('onBeforePostComment', $form); |
||
192 | |||
193 | // If commenting can only be done by logged in users, make sure the user is logged in |
||
194 | if (!$this->controller->getOwnerRecord()->canPostComment()) { |
||
195 | return Security::permissionFailure( |
||
196 | $this->controller, |
||
0 ignored issues
–
show
$this->controller is of type object<SilverStripe\Control\RequestHandler> , but the function expects a object<SilverStripe\Control\Controller>|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
197 | _t( |
||
198 | 'SilverStripe\\Comments\\Controllers\\CommentingController.PERMISSIONFAILURE', |
||
199 | "You're not able to post comments to this page. Please ensure you are logged in and have an " |
||
200 | . 'appropriate permission level.' |
||
201 | ) |
||
202 | ); |
||
203 | } |
||
204 | |||
205 | if ($member = Security::getCurrentUser()) { |
||
206 | $form->Fields()->push(new HiddenField('AuthorID', 'Author ID', $member->ID)); |
||
207 | } |
||
208 | |||
209 | // What kind of moderation is required? |
||
210 | switch ($this->controller->getOwnerRecord()->ModerationRequired) { |
||
211 | case 'Required': |
||
212 | $requireModeration = true; |
||
213 | break; |
||
214 | case 'NonMembersOnly': |
||
215 | $requireModeration = empty($member); |
||
216 | break; |
||
217 | case 'None': |
||
218 | default: |
||
219 | $requireModeration = false; |
||
220 | break; |
||
221 | } |
||
222 | |||
223 | $comment = Comment::create(); |
||
224 | $form->saveInto($comment); |
||
225 | |||
226 | $comment->ParentID = $data['ParentID']; |
||
227 | $comment->ParentClass = $data['ParentClassName']; |
||
0 ignored issues
–
show
The property
ParentClass does not exist on object<SilverStripe\Comments\Model\Comment> . Since you implemented __set , maybe consider adding a @property annotation.
Since your code implements the magic setter <?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...
|
|||
228 | |||
229 | $comment->AllowHtml = $this->controller->getOption('html_allowed'); |
||
230 | $comment->Moderated = !$requireModeration; |
||
231 | |||
232 | // Save into DB, or call pre-save hooks to give accurate preview |
||
233 | $usePreview = $this->controller->getOption('use_preview'); |
||
234 | $isPreview = $usePreview && !empty($data['IsPreview']); |
||
235 | if ($isPreview) { |
||
236 | $comment->extend('onBeforeWrite'); |
||
237 | } else { |
||
238 | $comment->write(); |
||
239 | |||
240 | // extend hook to allow extensions. Also see onBeforePostComment |
||
241 | $this->controller->extend('onAfterPostComment', $comment); |
||
242 | } |
||
243 | |||
244 | // we want to show a notification if comments are moderated |
||
245 | if ($requireModeration && !$comment->IsSpam) { |
||
246 | $this->getRequest()->getSession()->set('CommentsModerated', 1); |
||
247 | } |
||
248 | |||
249 | // clear the users comment since it passed validation |
||
250 | Cookie::set('CommentsForm_Comment', false); |
||
251 | |||
252 | // Find parent link |
||
253 | if (!empty($data['ReturnURL'])) { |
||
254 | $url = $data['ReturnURL']; |
||
255 | } elseif ($parent = $comment->Parent()) { |
||
256 | $url = $parent->Link(); |
||
257 | } else { |
||
258 | return $this->controller->redirectBack(); |
||
259 | } |
||
260 | |||
261 | // Given a redirect page exists, attempt to link to the correct anchor |
||
262 | if ($comment->IsSpam) { |
||
263 | // Link to the form with the error message contained |
||
264 | $hash = $form->FormName(); |
||
265 | } elseif (!$comment->Moderated) { |
||
266 | // Display the "awaiting moderation" text |
||
267 | $hash = 'moderated'; |
||
268 | } else { |
||
269 | // Link to the moderated, non-spam comment |
||
270 | $hash = $comment->Permalink(); |
||
271 | } |
||
272 | |||
273 | return $this->controller->redirect(Controller::join_links($url, "#{$hash}")); |
||
274 | } |
||
275 | } |
||
276 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: