/** * Form element validation handler for #type 'number'. * * Note that #required is validated by _form_validate() already. */ public static function validateNumber(&$element, FormStateInterface $form_state, &$complete_form) { $value = $element['#value']; if ($value === '') { return; } $name = empty($element['#title']) ? $element['#parents'][0] : $element['#title']; // Ensure the input is numeric. if (!is_numeric($value)) { $form_state->setError($element, t('%name must be a number.', array('%name' => $name))); return; } // Ensure that the input is greater than the #min property, if set. if (isset($element['#min']) && $value < $element['#min']) { $form_state->setError($element, t('%name must be higher than or equal to %min.', array('%name' => $name, '%min' => $element['#min']))); } // Ensure that the input is less than the #max property, if set. if (isset($element['#max']) && $value > $element['#max']) { $form_state->setError($element, t('%name must be lower than or equal to %max.', array('%name' => $name, '%max' => $element['#max']))); } if (isset($element['#step']) && strtolower($element['#step']) != 'any') { // Check that the input is an allowed multiple of #step (offset by #min if // #min is set). $offset = isset($element['#min']) ? $element['#min'] : 0.0; if (!NumberUtility::validStep($value, $element['#step'], $offset)) { $form_state->setError($element, t('%name is not a valid number.', array('%name' => $name))); } } }
/** * Tests the alphadecimal conversion functions. * * @dataProvider providerTestConversions * @covers ::intToAlphadecimal * @covers ::alphadecimalToInt * * @param int $value * The integer value. * @param string $expected * The expected alphadecimal value. */ public function testConversions($value, $expected) { $this->assertSame(Number::intToAlphadecimal($value), $expected); $this->assertSame($value, Number::alphadecimalToInt($expected)); }
/** * {@inheritdoc} */ public function preSave(EntityStorageInterface $storage) { parent::preSave($storage); if (is_null($this->get('status')->value)) { $published = \Drupal::currentUser()->hasPermission('skip comment approval') ? CommentInterface::PUBLISHED : CommentInterface::NOT_PUBLISHED; $this->setPublished($published); } if ($this->isNew()) { // Add the comment to database. This next section builds the thread field. // Also see the documentation for comment_view(). $thread = $this->getThread(); if (empty($thread)) { if ($this->threadLock) { // Thread lock was not released after being set previously. // This suggests there's a bug in code using this class. throw new \LogicException('preSave() is called again without calling postSave() or releaseThreadLock()'); } if (!$this->hasParentComment()) { // This is a comment with no parent comment (depth 0): we start // by retrieving the maximum thread level. $max = $storage->getMaxThread($this); // Strip the "/" from the end of the thread. $max = rtrim($max, '/'); // We need to get the value at the correct depth. $parts = explode('.', $max); $n = Number::alphadecimalToInt($parts[0]); $prefix = ''; } else { // This is a comment with a parent comment, so increase the part of // the thread value at the proper depth. // Get the parent comment: $parent = $this->getParentComment(); // Strip the "/" from the end of the parent thread. $parent->setThread((string) rtrim((string) $parent->getThread(), '/')); $prefix = $parent->getThread() . '.'; // Get the max value in *this* thread. $max = $storage->getMaxThreadPerThread($this); if ($max == '') { // First child of this parent. As the other two cases do an // increment of the thread number before creating the thread // string set this to -1 so it requires an increment too. $n = -1; } else { // Strip the "/" at the end of the thread. $max = rtrim($max, '/'); // Get the value at the correct depth. $parts = explode('.', $max); $parent_depth = count(explode('.', $parent->getThread())); $n = Number::alphadecimalToInt($parts[$parent_depth]); } } // Finally, build the thread field for this new comment. To avoid // race conditions, get a lock on the thread. If another process already // has the lock, just move to the next integer. do { $thread = $prefix . Number::intToAlphadecimal(++$n) . '/'; $lock_name = "comment:{$this->getCommentedEntityId()}:{$thread}"; } while (!\Drupal::lock()->acquire($lock_name)); $this->threadLock = $lock_name; } // We test the value with '===' because we need to modify anonymous // users as well. if ($this->getOwnerId() === \Drupal::currentUser()->id() && \Drupal::currentUser()->isAuthenticated()) { $this->setAuthorName(\Drupal::currentUser()->getUsername()); } // Add the values which aren't passed into the function. $this->setThread($thread); $this->setHostname(\Drupal::request()->getClientIP()); } }
/** * Tests Number::validStep() with offset. * * @param numeric $value * The value argument for Number::validStep(). * @param numeric $step * The step argument for Number::validStep(). * @param numeric $offset * The offset argument for Number::validStep(). * @param boolean $expected * Expected return value from Number::validStep(). * * @dataProvider providerTestValidStepOffset */ public function testValidStepOffset($value, $step, $offset, $expected) { $return = Number::validStep($value, $step, $offset); $this->assertEquals($expected, $return); }