public function validateBlockType(SuperTableBlockTypeModel $blockType, bool $validateUniques = true): bool
    {
        $validates = true;

        $reservedHandles = ['type'];

        $blockTypeRecord = $this->_getBlockTypeRecord($blockType);
        $blockTypeRecord->fieldId = $blockType->fieldId;

        if (!$blockTypeRecord->validate()) {
            $validates = false;
            $blockType->addErrors($blockTypeRecord->getErrors());
        }

        // Reset this each time - normal Super Table fields won't be an issue, but when validation is called multiple times
        // its because its being embedded in another field (Matrix). Thus, we need to reset unique field handles, because they
        // can be different across multiple parent fields.
        $this->_uniqueFieldHandles = [];

        // Can't validate multiple new rows at once so we'll need to give these temporary context to avoid false unique
        // handle validation errors, and just validate those manually. Also apply the future fieldColumnPrefix so that
        // field handle validation takes its length into account.
        $contentService = Craft::$app->getContent();
        $originalFieldContext = $contentService->fieldContext;
        $originalFieldColumnPrefix = $contentService->fieldColumnPrefix;

        $contentService->fieldContext = StringHelper::randomString(10);
        $contentService->fieldColumnPrefix = 'field_';

        foreach ($blockType->getFields() as $field) {
            $field->validate();

            if ($field->handle) {
                if (in_array($field->handle, $this->_uniqueFieldHandles, true)) {
                    // This error *might* not be entirely accurate, but it's such an edge case that it's probably better
                    // for the error to be worded for the common problem (two duplicate handles within the same block
                    // type).
                    $error = Craft::t('app', '{attribute} "{value}" has already been taken.', [
                        'attribute' => Craft::t('app', 'Handle'),
                        'value' => $field->handle
                    ]);

                    $field->addError('handle', $error);
                } else {
                    $this->_uniqueFieldHandles[] = $field->handle;
                }
            }

            if ($field->hasErrors()) {
                $blockType->hasFieldErrors = true;
                $validates = false;

                $blockType->addErrors($field->getErrors());
            }

            // `type` is a restricted handle
            if (in_array($field->handle, $reservedHandles)) {
                $blockType->hasFieldErrors = true;
                $validates = false;

                $field->addErrors(['handle' => Craft::t('app', '"{handle}" is a reserved word.', ['handle' => $field->handle])]);
            }

            // Special-case for validating child Matrix fields
            if (get_class($field) == 'craft\fields\Matrix') {
                $matrixBlockTypes = $field->getBlockTypes();

                foreach ($matrixBlockTypes as $matrixBlockType) {
                    if ($matrixBlockType->hasFieldErrors) {
                        $blockType->hasFieldErrors = true;
                        $validates = false;

                        // Store a generic error for our parent Super Table field to show a nested error exists
                        $field->addErrors(['field' => 'general']);
                    }
                }
            }
        }

        $contentService->fieldContext = $originalFieldContext;
        $contentService->fieldColumnPrefix = $originalFieldColumnPrefix;

        return $validates;
    }
public function validateBlockType(SuperTableBlockTypeModel $blockType, bool $validateUniques = true): bool
    {
        $validates = true;

        $reservedHandles = ['type'];

        $blockTypeRecord = $this->_getBlockTypeRecord($blockType);
        $blockTypeRecord->fieldId = $blockType->fieldId;

        if (!$blockTypeRecord->validate()) {
            $validates = false;
            $blockType->addErrors($blockTypeRecord->getErrors());
        }

        // Reset this each time - normal Super Table fields won't be an issue, but when validation is called multiple times
        // its because its being embedded in another field (Matrix). Thus, we need to reset unique field handles, because they
        // can be different across multiple parent fields.
        $this->_uniqueFieldHandles = [];

        // Can't validate multiple new rows at once so we'll need to give these temporary context to avoid false unique
        // handle validation errors, and just validate those manually. Also apply the future fieldColumnPrefix so that
        // field handle validation takes its length into account.
        $contentService = Craft::$app->getContent();
        $originalFieldContext = $contentService->fieldContext;
        $originalFieldColumnPrefix = $contentService->fieldColumnPrefix;

        $contentService->fieldContext = StringHelper::randomString(10);
        $contentService->fieldColumnPrefix = 'field_';

        foreach ($blockType->getFields() as $field) {
            $field->validate();

            if ($field->handle) {
                if (in_array($field->handle, $this->_uniqueFieldHandles, true)) {
                    // This error *might* not be entirely accurate, but it's such an edge case that it's probably better
                    // for the error to be worded for the common problem (two duplicate handles within the same block
                    // type).
                    $error = Craft::t('app', '{attribute} "{value}" has already been taken.', [
                        'attribute' => Craft::t('app', 'Handle'),
                        'value' => $field->handle
                    ]);

                    $field->addError('handle', $error);
                } else {
                    $this->_uniqueFieldHandles[] = $field->handle;
                }
            }

            if ($field->hasErrors()) {
                $blockType->hasFieldErrors = true;
                $validates = false;

                $blockType->addErrors($field->getErrors());
            }

            // `type` is a restricted handle
            if (in_array($field->handle, $reservedHandles)) {
                $blockType->hasFieldErrors = true;
                $validates = false;

                $field->addErrors(['handle' => Craft::t('app', '"{handle}" is a reserved word.', ['handle' => $field->handle])]);
            }

            // Special-case for validating child Matrix fields
            if (get_class($field) == 'craft\fields\Matrix') {
                $matrixBlockTypes = $field->getBlockTypes();

                foreach ($matrixBlockTypes as $matrixBlockType) {
                    if ($matrixBlockType->hasFieldErrors) {
                        $blockType->hasFieldErrors = true;
                        $validates = false;

                        // Store a generic error for our parent Super Table field to show a nested error exists
                        $field->addErrors(['field' => 'general']);
                    }
                }
            }
        }

        $contentService->fieldContext = $originalFieldContext;
        $contentService->fieldColumnPrefix = $originalFieldColumnPrefix;

        return $validates;
    }
public function validateBlockType ( SuperTableBlockTypeModel $ blockType , bool $ validateUniques = true ) : bool { $ validates = true ; $ reservedHandles = [ 'type' ] ; $ blockTypeRecord = $ this -> _getBlockTypeRecord ( $ blockType ) ; $ blockTypeRecord -> fieldId = $ blockType -> fieldId ; if ( ! $ blockTypeRecord -> validate ( ) ) { $ validates = false ; $ blockType -> addErrors ( $ blockTypeRecord -> getErrors ( ) ) ; } // Reset this each time - normal Super Table fields won't be an issue, but when validation is called multiple times // its because its being embedded in another field (Matrix). Thus, we need to reset unique field handles, because they // can be different across multiple parent fields. $ this -> _uniqueFieldHandles = [ ] ; // Can't validate multiple new rows at once so we'll need to give these temporary context to avoid false unique // handle validation errors, and just validate those manually. Also apply the future fieldColumnPrefix so that // field handle validation takes its length into account. $ contentService = Craft :: $ app -> getContent ( ) ; $ originalFieldContext = $ contentService -> fieldContext ; $ originalFieldColumnPrefix = $ contentService -> fieldColumnPrefix ; $ contentService -> fieldContext = StringHelper :: randomString ( 10 ) ; $ contentService -> fieldColumnPrefix = 'field_' ; foreach ( $ blockType -> getFields ( ) as $ field ) { $ field -> validate ( ) ; if ( $ field -> handle ) { if ( in_array ( $ field -> handle , $ this -> _uniqueFieldHandles , true ) ) { // This error *might* not be entirely accurate, but it's such an edge case that it's probably better // for the error to be worded for the common problem (two duplicate handles within the same block // type). $ error = Craft :: t ( 'app' , '{attribute} "{value}" has already been taken.' , [ 'attribute' => Craft :: t ( 'app' , 'Handle' ) , 'value' => $ field -> handle ] ) ; $ field -> addError ( 'handle' , $ error ) ; } else { $ this -> _uniqueFieldHandles [ ] = $ field -> handle ; } } if ( $ field -> hasErrors ( ) ) { $ blockType -> hasFieldErrors = true ; $ validates = false ; $ blockType -> addErrors ( $ field -> getErrors ( ) ) ; } // `type` is a restricted handle if ( in_array ( $ field -> handle , $ reservedHandles ) ) { $ blockType -> hasFieldErrors = true ; $ validates = false ; $ field -> addErrors ( [ 'handle' => Craft :: t ( 'app' , '"{handle}" is a reserved word.' , [ 'handle' => $ field -> handle ] ) ] ) ; } // Special-case for validating child Matrix fields if ( get_class ( $ field ) == 'craft\fields\Matrix' ) { $ matrixBlockTypes = $ field -> getBlockTypes ( ) ; foreach ( $ matrixBlockTypes as $ matrixBlockType ) { if ( $ matrixBlockType -> hasFieldErrors ) { $ blockType -> hasFieldErrors = true ; $ validates = false ; // Store a generic error for our parent Super Table field to show a nested error exists $ field -> addErrors ( [ 'field' => 'general' ] ) ; } } } } $ contentService -> fieldContext = $ originalFieldContext ; $ contentService -> fieldColumnPrefix = $ originalFieldColumnPrefix ; return $ validates ; }
Validates a block type.

If the block type doesn’t validate, any validation errors will be stored on the block type.

@param SuperTableBlockTypeModel $blockType        The block type.
@param bool            $validateUniques      Whether the Name and Handle attributes should be validated to
ensure they’re unique. Defaults to `true`.

@return bool Whether the block type validated.
Validates a block type .