Validate all properties right before triggering the event.

This throws coding exceptions for fatal problems and debugging for minor problems.

@throws \coding_exception
177101
protected final function validate_before_trigger() {
        global $DB, $CFG;

        if (empty($this->data['crud'])) {
            throw new \coding_exception('crud must be specified in init() method of each method');
        }
        if (!isset($this->data['edulevel'])) {
            throw new \coding_exception('edulevel must be specified in init() method of each method');
        }
        if (!empty($this->data['objectid']) and empty($this->data['objecttable'])) {
            throw new \coding_exception('objecttable must be specified in init() method if objectid present');
        }

        if ($CFG->debugdeveloper) {
            // Ideally these should be coding exceptions, but we need to skip these for performance reasons
            // on production servers.

            if (!in_array($this->data['crud'], array('c', 'r', 'u', 'd'), true)) {
                debugging("Invalid event crud value specified.", DEBUG_DEVELOPER);
            }
            if (!in_array($this->data['edulevel'], array(self::LEVEL_OTHER, self::LEVEL_TEACHING, self::LEVEL_PARTICIPATING))) {
                // Bitwise combination of levels is not allowed at this stage.
                debugging('Event property edulevel must a constant value, see event_base::LEVEL_*', DEBUG_DEVELOPER);
            }
            if (self::$fields !== array_keys($this->data)) {
                debugging('Number of event data fields must not be changed in event classes', DEBUG_DEVELOPER);
            }
            $encoded = json_encode($this->data['other']);
            // The comparison here is not set to strict as whole float numbers will be converted to integers through JSON encoding /
            // decoding and send an unwanted debugging message.
            if ($encoded === false or $this->data['other'] != json_decode($encoded, true)) {
                debugging('other event data must be compatible with json encoding', DEBUG_DEVELOPER);
            }
            if ($this->data['userid'] and !is_number($this->data['userid'])) {
                debugging('Event property userid must be a number', DEBUG_DEVELOPER);
            }
            if ($this->data['courseid'] and !is_number($this->data['courseid'])) {
                debugging('Event property courseid must be a number', DEBUG_DEVELOPER);
            }
            if ($this->data['objectid'] and !is_number($this->data['objectid'])) {
                debugging('Event property objectid must be a number', DEBUG_DEVELOPER);
            }
            if ($this->data['relateduserid'] and !is_number($this->data['relateduserid'])) {
                debugging('Event property relateduserid must be a number', DEBUG_DEVELOPER);
            }
            if ($this->data['objecttable']) {
                if (!$DB->get_manager()->table_exists($this->data['objecttable'])) {
                    debugging('Unknown table specified in objecttable field', DEBUG_DEVELOPER);
                }
                if (!isset($this->data['objectid'])) {
                    debugging('Event property objectid must be set when objecttable is defined', DEBUG_DEVELOPER);
                }
            }
        }
    }
1039251
private function ensure_isset(array $properties) {
        foreach ($properties as $property) {
            if (!isset($this->$property)) {
                throw new coding_exception('The property "'.$property.'" is not set.');
            }
        }
    }
900582
public function validate()
    {
        if ($this->isWorkflowDispatch() && null === $this->getWorkflowRunType()) {
            $errMsg = 'workflowRunType not specified';
            throw new Exception\InvalidMetadataException($errMsg);
        }

        if ($this->isFlagRunPrepareData()) {
            if (null === $this->getPrepareDataMethod()) {
                $errMsg = 'prepareDataMethod not specified';
                throw new Exception\InvalidMetadataException($errMsg);
            }
            if (null === $this->getPrepareDataMethod()) {
                $errMsg = 'prepareDataMethod not specified';
                throw new Exception\InvalidMetadataException($errMsg);
            }
        }

        if ($this->getFlagHasConditions()) {
            if (0 === count($this->getConditions())) {
                $errMsg = 'empty conditions';
                throw new Exception\InvalidMetadataException($errMsg);
            }

            foreach ($this->getConditions() as $condition) {
                $condition->validate();
            }
        }
    }
813799
protected function performValidation()
    {
        $this->requireProperties(['type']);
        if (isset($this->type)) {
            if (!in_array($this->type, $this->knownTypes)) {
                $this->addError("Unknown Security Scheme type: $this->type");
            } else {
                switch ($this->type) {
                    case "apiKey":
                        $this->requireProperties(['name', 'in']);
                        if (isset($this->in)) {
                            if (!in_array($this->in, ["query", "header", "cookie"])) {
                                $this->addError("Invalid value for Security Scheme property 'in': $this->in");
                            }
                        }
                        break;
                    case "http":
                        $this->requireProperties(['scheme']);
                        break;
                    case "oauth2":
                        $this->requireProperties(['flows']);
                        break;
                    case "openIdConnect":
                        $this->requireProperties(['openIdConnectUrl']);
                        break;
                }
            }
        }
    }
1317614
public function validate() : void
    {
        if (null === $this->is_valid) {
            if (null === $this->user_value && null !== $this->default_value) {
                // There is a preset value, and its not being changed
                $this->is_valid = true;
            } elseif (null != $this->validator && false != $this->validator) {
                $validator = $this->validator;
                $valids = array();
                $all_valid = true;
                $pieces = explode(',', $this->user_value);
                foreach ($pieces as $piece) {
                    $result = $validator::quickValidate($piece, $this->constraints);
                    if (null !== $result) {
                        $valids[] = $result;
                    } else {
                        $all_valid = false;
                    }
                }
                $this->user_value = implode(',', $valids);
                $this->is_valid = $all_valid;
                if (!$all_valid) {
                    $this->error = 'The provided value is not valid. Please enter a valid value.';
                }
            } else {
                // This field does not get validated
                $this->is_valid = true;
            }
        }

        // Check if the input is different from the default value
        if ($this->is_valid && null !== $this->user_value) {
            $this->is_changed = ($this->default_value != $this->user_value);
        }
    }
728691
public function validate() {
        if ($this->initializer) {
            Ensure::isFalse($this->initializer->getRepository() && $this->initializer->getValue(), 'It makes no sense to define initializer repository and value simultaneously for column [%s]', $this->name);
        }
    }
27359
private function validate()
    {
        if ($this->hasValidated) {
            return;
        }

        $this->checkDepth();

        foreach ($this->schema as $rule => $parameter) {
            $this->currentKeyword   = $rule;
            $this->currentParameter = $parameter;
            $this->mergeErrors($this->validateRule($rule, $parameter));
            $this->currentKeyword = $this->currentParameter = null;
        }

        $this->hasValidated = true;
    }
1121634
private function validate()
    {
        if (!array_key_exists('type', $this->properties)) {
            throw new StatusException(sprintf('Key %s in %s missing', 'type', __CLASS__), 100, null);
        }

        $type = $this->properties['type'];

        // the type specified must be valid
        if (!in_array($this->properties['type'], $this->types)) {
            throw new StatusException('The type specified is invalid', 100, null);
        }

        switch ($type) {
            case StatusInterface::TYPE_INITIAL:
            case StatusInterface::TYPE_EXCEPTION:
                $mandatoryKeys = ['name'];
                break;

            default:
                $mandatoryKeys = ['name', 'transitions_from', 'transitions_to'];
                break;
        }

        foreach ($mandatoryKeys as $key) {
            if (!array_key_exists($key, $this->properties)) {
                throw new StatusException(sprintf('Key %s in %s missing', $key, __CLASS__), 100, null);
            }
        }

        if (StatusInterface::TYPE_INITIAL != $type && StatusInterface::TYPE_EXCEPTION != $type) {
            $keysMustBeArray = ['transitions_from', 'transitions_to'];
            foreach ($keysMustBeArray as $key) {
                if (!is_array($this->properties[$key])) {
                    throw new StatusException(sprintf('Key %s is not an array', $key), 100, null);
                }
            }
        }
    }
1015991
protected function validate()
    {
        if (!$this->validator instanceof ValidatorInterface) {
            return;
        }

        $valid = true;
        if ($this->getEntityContainerMap()->count() > 0) {
            $entityContainers = $this->getEntityContainerMap()->getAll();

            $this->logger->debug('start form entity valiation', array('name' => $this->getName()));

            /**
             * @var $entityContainer    \Naucon\Form\Mapper\EntityContainerInterface
             */
            foreach ($entityContainers as $entityContainer) {
                if ($entityContainer->hasValidate()) {
                    $this->logger->debug('invoke form prevalidator hook', array('name' => $this->getName(), 'entity' => $entityContainer->getName()));
                    // prevalidation hook
                    $entityContainer->invokeHook('prevalidatorHook');

                    $violations = $this->validator->validate($entityContainer->getEntity(), null, $this->configuration->get('validation_groups'));
                    if (is_array($violations) && count($violations)) {
                        // TODO set FormValidations to $entityContainer
                        /**
                         * @var \Naucon\Form\Validator\ViolationInterface $violation
                         */
                        $violationsDump = array();
                        foreach ($violations as $violation) {
                            $violationsDump[$violation->getName()] = $violation->getMessage();
                            $entityContainer->setError($violation->getName(), new FormError($violation->getName(), $violation->getMessage()));
                        }
                        $valid = false;

                        $this->logger->debug('form entity violations', array('name' => $this->getName(), 'entity' => $entityContainer->getName(), 'violations' => $violationsDump));
                    }

                    // postvalidation hook
                    $this->logger->debug('invoke form postvalidator hook', array('name' => $this->getName(), 'entity' => $entityContainer->getName()));
                    $entityContainer->invokeHook('postvalidatorHook');

                    if ($entityContainer->hasErrors()) {
                        $valid = false;
                    }
                }
            }
        }

        if ($valid) {
            $this->logger->debug('finished form entity valiation successful', array('name' => $this->getName()));
        } else {
            $this->logger->debug('finished form entity valiation failed', array('name' => $this->getName()));
        }
        $this->setValid($valid);
    }
234849
public function validate() : void
    {
        $this->value = null;
        $value = $this->filter($this->raw_value);
        if (true === $this->checkValidity($value)) {
            $this->is_valid = true;
        } else {
            $this->is_valid = false;
            $this->reportError($this->error_message);
            $error_message = sprintf($this->error_message, $this->field_name);
            $this->the_message = $error_message;
        }
        // If no issues have been found, check the constraints.
        if ($this->is_valid) {
            foreach ($this->constraints as $constraint) {
                if (false === $constraint->check($value)) {
                    $this->is_valid = false;
                    $this->the_message = sprintf($constraint->getErrorMessage(), $this->field_name);
                }
            }
        }
        // Set the value for retrieval
        if ($this->is_valid) {
            $this->value = $value;
        }
    }
1224418
private function validateAnnotations()
    {
        //Count annotations in the annotation namespace, ignore annotations not in our namespace
        $count = 0;
        foreach($this->annotations as $a)
        {
            //If you find the namespace in the class name, add to count
            if(strrpos(get_class($a), self::ANNOTATION_NAMESPACE) !== false)
            {
                $count++;
            }
        }

        switch($count)
        {
            //0 annotations, just ignore
            case 0:

                return;

            //1 Annotation, it can't be index.
            case 1:

                if($this->getAnnotationIndex(self::INDEX) < 0)
                {
                    //It's not index, return.
                    return;
                }

                throw new Exception("@Index cannot be the only annotation on {$this->name} in {$this->property->getDeclaringClass()->getName()}.");

            //2 Annotations, they have to be index and property.
            case 2:

                if( ($this->getAnnotationIndex(self::PROPERTY) >= 0) && ($this->getAnnotationIndex(self::INDEX) >= 0))
                {
                    //They are index and property, return
                    return;
                }

                break;
        }

        //It didn't fall into any of the categories, must be invalid
        throw new Exception("Invalid annotation combination on {$this->name} in {$this->property->getDeclaringClass()->getName()}.");
    }
570596
private static function validation() {
        if (isset(self::$config['validators'])) {
            $validators = self::$config['validators'];
        }
        else {
            $validators = true;
        }

        // action name validation
        if ($validators === true || (!isset($validators['actionName']) || $validators['actionName'] === true)) {
            if (substr(PHPMVC_ACTION, 0, 2) == '__') {
                throw new ActionNameValidationException();
            }
        }

        // request verification token
        $antiForgeryTokenForAction = InternalHelper::getStaticPropertyValue('\\PhpMvc\\ValidateAntiForgeryToken', 'enable');
        if ($antiForgeryTokenForAction === true || (($validators === true || (!isset($validators['antiForgeryToken']) || $validators['antiForgeryToken'] === true)) && $antiForgeryTokenForAction !== false)) {
            $request = self::$config['httpContext']->getRequest();

            if ($request->isPost()) {
                $post = $request->post();
                $expected = $request->cookies('__requestVerificationToken');

                if (!isset($post)) { $post = array(); }

                if (
                    (isset($expected) && $expected !== 'false' && (!isset($post['__requestVerificationToken']) || $post['__requestVerificationToken'] != $expected)) ||
                    (isset($expected) && $expected === 'false' && !empty($post['__requestVerificationToken'])) ||
                    (isset($post['__requestVerificationToken']) && empty($expected))
                   ) {
                    throw new HttpAntiForgeryException();
                }
            }
        }

        // cross site scripting validation
        if ($validators === true || (!isset($validators['crossSiteScripting']) || $validators['crossSiteScripting'] === true)) {
            $request = self::$config['httpContext']->getRequest();

            $get = $request->get();
            $post = $request->post();

            if (!isset($get)) { $get = array(); }
            if (!isset($post)) { $post = array(); }

            $items = array_merge($get, $post);

            foreach ($items as $key => $value) {
                $isDangerousString = CrossSiteScriptingValidation::IsDangerousString($key) || CrossSiteScriptingValidation::IsDangerousString($value);
    
                if ($isDangerousString) {
                    $source = null;

                    if (!empty($get[$key])) {
                        $source = '$_GET';
                    }
                    elseif (!empty($post[$key])) {
                        $source = '$_POST';
                    }
    
                    throw new HttpRequestValidationException($source, $key, $value);
                }
            }
        }
    }
1167902
protected function validate() {
        $c = strlen($this->text);
        if ($c === 0) {
            throw new CINParseException('codabar', 'No data has been entered.');
        }

        // Checking if all chars are allowed
        for ($i = 0; $i < $c; $i++) {
            if (array_search($this->text[$i], $this->keys) === false) {
                throw new CINParseException('codabar', 'The character \'' . $this->text[$i] . '\' is not allowed.');
            }
        }

        // Must start by A, B, C or D
        if ($c == 0 || ($this->text[0] !== 'A' && $this->text[0] !== 'B' && $this->text[0] !== 'C' && $this->text[0] !== 'D')) {
            throw new CINParseException('codabar', 'The text must start by the character A, B, C, or D.');
        }

        // Must end by A, B, C or D
        $c2 = $c - 1;
        if ($c2 === 0 || ($this->text[$c2] !== 'A' && $this->text[$c2] !== 'B' && $this->text[$c2] !== 'C' && $this->text[$c2] !== 'D')) {
            throw new CINParseException('codabar', 'The text must end by the character A, B, C, or D.');
        }

        parent::validate();
    }
127710
protected function validate_data() {
        if (self::$preventcreatecall) {
            throw new \coding_exception('cannot call submission_form_viewed::create() directly, use submission_form_viewed::create_from_user() instead.');
        }

        parent::validate_data();

        if (!isset($this->relateduserid)) {
            throw new \coding_exception('The \'relateduserid\' must be set.');
        }

        if (!isset($this->other['assignid'])) {
            throw new \coding_exception('The \'assignid\' value must be set in other.');
        }
    }
36809
protected function validate_data() {
        parent::validate_data();
        // Make sure this class is never used without proper object details.
        if (empty($this->objectid) || empty($this->objecttable)) {
            throw new \coding_exception('The course_module_viewed event must define objectid and object table.');
        }
        // Make sure the context level is set to module.
        if ($this->contextlevel != CONTEXT_MODULE) {
            throw new \coding_exception('Context level must be CONTEXT_MODULE.');
        }
    }
69649
public function validate()
	{
		// reset the error container and status
		$this->errors = array();
		$this->isValid = true;

		// validation starts, call the pre-validation callback
		$this->runCallbacks('before_validation');

		// was the upload of the file a success?
		if ($this->container['error'] == 0)
		{
			// add some filename details (pathinfo can't be trusted with utf-8 filenames!)
			$this->container['extension'] = ltrim(strrchr(ltrim($this->container['name'], '.'), '.'),'.');
			if (empty($this->container['extension']))
			{
				$this->container['basename'] = $this->container['name'];
			}
			else
			{
				$this->container['basename'] = substr($this->container['name'], 0, strlen($this->container['name'])-(strlen($this->container['extension'])+1));
			}

			// does this upload exceed the maximum size?
			if ( ! empty($this->config['max_size']) and is_numeric($this->config['max_size']) and $this->container['size'] > $this->config['max_size'])
			{
				$this->addError(static::UPLOAD_ERR_MAX_SIZE);
			}

			// add mimetype information
			try
			{
				$handle = finfo_open(FILEINFO_MIME_TYPE);
				$this->container['mimetype'] = finfo_file($handle, $this->container['tmp_name']);
				finfo_close($handle);
			}
			// this will only work if PHP errors are converted into ErrorException (like when you use FuelPHP)
			catch (\ErrorException $e)
			{
				$this->container['mimetype'] = false;
				$this->addError(UPLOAD_ERR_NO_FILE);
			}

			// make sure it contains something valid
			if (empty($this->container['mimetype']) or strpos($this->container['mimetype'], '/') === false)
			{
				$this->container['mimetype'] = 'application/octet-stream';
			}

			// split the mimetype info so we can run some tests
			preg_match('|^(.*)/(.*)|', $this->container['mimetype'], $mimeinfo);

			// check the file extension black- and whitelists
			if (in_array(strtolower($this->container['extension']), (array) $this->config['ext_blacklist']))
			{
				$this->addError(static::UPLOAD_ERR_EXT_BLACKLISTED);
			}
			elseif ( ! empty($this->config['ext_whitelist']) and ! in_array(strtolower($this->container['extension']), (array) $this->config['ext_whitelist']))
			{
				$this->addError(static::UPLOAD_ERR_EXT_NOT_WHITELISTED);
			}

			// check the file type black- and whitelists
			if (in_array($mimeinfo[1], (array) $this->config['type_blacklist']))
			{
				$this->addError(static::UPLOAD_ERR_TYPE_BLACKLISTED);
			}
			if ( ! empty($this->config['type_whitelist']) and ! in_array($mimeinfo[1], (array) $this->config['type_whitelist']))
			{
				$this->addError(static::UPLOAD_ERR_TYPE_NOT_WHITELISTED);
			}

			// check the file mimetype black- and whitelists
			if (in_array($this->container['mimetype'], (array) $this->config['mime_blacklist']))
			{
				$this->addError(static::UPLOAD_ERR_MIME_BLACKLISTED);
			}
			elseif ( ! empty($this->config['mime_whitelist']) and ! in_array($this->container['mimetype'], (array) $this->config['mime_whitelist']))
			{
				$this->addError(static::UPLOAD_ERR_MIME_NOT_WHITELISTED);
			}

			// validation finished, call the post-validation callback
			$this->runCallbacks('after_validation');
		}
		else
		{
			// upload was already a failure, store the corresponding error
			$this->addError($this->container['error']);
		}

		// set the flag to indicate we ran the validation
		$this->isValidated = true;

		// return the validation state
		return $this->isValid;
	}
766251
public function validateForm()
    {
        $validator = $this->getValidationFactory()->make(
            $this->requestData(),
            $this->rules()
        );

        if ($validator->fails())
            throw new \Exception($this->formatErrors($validator->errors()));
    }