Create fully configured BbCode

@return BbCode
962509
public function getFullBbCode() : BbCode
    {
        $bbcode = new BbCode();

        $bold = new Bold();
        $bbcode->addTag($bold);

        $underline = new Underline();
        $bbcode->addTag($underline);

        $italic = new Italic();
        $bbcode->addTag($italic);

        $link = new Link;
        $bbcode->addTag($link);

        $img = new ImgTag();
        $bbcode->addTag($img);

        $unknownTag = new Tag\UnknownSimpleType();
        $bbcode->addTag($unknownTag);

        $youtubeTag = new YoutubeTag();
        $bbcode->addTag($youtubeTag);

        $tags = [
            $bold,
            $underline,
            $italic,
            $link,
            $unknownTag,
            $img,
            $youtubeTag,
        ];

        // link allowed
        $bbcode->addAllowedChildTag($link, $bold);
        $bbcode->addAllowedChildTag($link, $italic);
        $bbcode->addAllowedChildTag($link, $underline);
        $bbcode->addAllowedChildTag($link, $unknownTag);
        $bbcode->addAllowedChildTag($link, $img);

        $tagsAllowingAnyChild = [
            $bold,
            $italic,
            $underline,
            $unknownTag,
        ];

        foreach ($tagsAllowingAnyChild as $tagAllowingAnyTag) {
            foreach ($tags as $tag) {
                $bbcode->addAllowedChildTag($tagAllowingAnyTag, $tag);
            }
        }

        return $bbcode;
    }
371456
public function createInstance()
    {
        switch ($this->method) {
            case 'addBigIntegerColumn':
            case 'addBinaryColumn':
            case 'addBooleanColumn':
            case 'addDateColumn':
            case 'addDateTimeColumn':
            case 'addDecimalColumn':
            case 'addFloatColumn':
            case 'addIntegerColumn':
            case 'addSmallIntegerColumn':
            case 'addStringColumn':
            case 'addTextColumn':
            case 'addTimeColumn':
                $namespace = 'Rentgen\\Database\\Column\\';
                $class = $namespace . ltrim($this->method, 'add');
                $options = isset($this->params[1]) ? $this->params[1] : array();

                if ('addStringColumn' === $this->method && !isset($options['limit'])) {
                    $options['limit'] = 255;
                }
                $column = new $class($this->params[0], $options);
                break;
            case 'addCustomColumn':
                $options = isset($this->params[2]) ? $this->params[2] : [];
                $column = new CustomColumn($this->params[0], $this->params[1], $options);
                break;
            default:
                throw new \Exception(sprintf("Unsupported method " . $this->method));
        }

        if (isset($options['comment'])) {
            $column->setDescription($options['comment']);
        }

        return $column;
    }
951235
public function build(): HighlightFrameRequest
	{
		$instance = new HighlightFrameRequest();
		if ($this->frameId === null) {
			throw new BuilderException('Property [frameId] is required.');
		}
		$instance->frameId = $this->frameId;
		$instance->contentColor = $this->contentColor;
		$instance->contentOutlineColor = $this->contentOutlineColor;
		return $instance;
	}
935572
public function bbcode($string)
    {
        if (!empty($string)) {
            $search = array(
                '@\[(?i)b\](.*?)\[/(?i)b\]@si',
                '@\[(?i)i\](.*?)\[/(?i)i\]@si',
                '@\[(?i)u\](.*?)\[/(?i)u\]@si',
                '@\[(?i)img=(.*?)\](.*?)\[/(?i)img\]@si',
                '@\[(?i)youtube\](.*?)\[/(?i)youtube\]@si',
                '@\[(?i)vimeo\](.*?)\[/(?i)vimeo\]@si',
                '@\[(?i)p\](.*?)\[/(?i)p\]@si',
                '@\[(?i)br/\]@si',
                '@\[(?i)url=(.*?)\](.*?)\[/(?i)url\]@si',
            );

            $replace = array(
                '<b>\\1</b>',
                '<i>\\1</i>',
                '<u>\\1</u>',
                '<img src="\\1" alt="\\2" />',
                '<iframe width="400" height="250" src="https://www.youtube.com/embed/\\1?theme=dark&iv_load_policy=3&wmode=transparent" frameborder="0" allowfullscreen></iframe>',
                '<iframe src="https://player.vimeo.com/video/\\1?title=0&amp;byline=0&amp;portrait=0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen="" frameborder="0" width="400" height="250"></iframe>',
                '<p>\\1</p>',
                '<br/>',
                '<a href="\\1">\\2</a>'
            );
            return preg_replace($search , $replace, $string);
        }
        return false;
    }
1249955
protected function createLaravelRoute()
    {
        $prefix = $this->app->make('config')->get('fluxbb.route_prefix', '');

        $this->app->make('router')->any($prefix.'/{uri}', ['as' => 'fluxbb', 'uses' => function () {
            $dispatcher = new Dispatcher(
                $this->app->make('FluxBB\Web\Router'),
                $this->app->make('FluxBB\Web\ControllerFactory')
            );

            return $dispatcher->handle($this->app->make('request'));
        }])->where('uri', '.*');
    }
868385
private function createCachePluginNode()
    {
        $builder = new TreeBuilder('config');
        // Keep compatibility with symfony/config < 4.2
        if (!method_exists($builder, 'getRootNode')) {
            $config = $builder->root('config');
        } else {
            $config = $builder->getRootNode();
        }

        $config
            ->fixXmlConfig('method')
            ->fixXmlConfig('respect_response_cache_directive')
            ->addDefaultsIfNotSet()
            ->validate()
                ->ifTrue(function ($config) {
                    // Cannot set both respect_cache_headers and respect_response_cache_directives
                    return isset($config['respect_cache_headers'], $config['respect_response_cache_directives']);
                })
                ->thenInvalid('You can\'t provide config option "respect_cache_headers" and "respect_response_cache_directives" simultaniously. Use "respect_response_cache_directives" instead.')
            ->end()
            ->children()
                ->scalarNode('cache_key_generator')
                    ->info('This must be a service id to a service implementing '.CacheKeyGenerator::class)
                ->end()
                ->integerNode('cache_lifetime')
                    ->info('The minimum time we should store a cache item')
                ->end()
                ->integerNode('default_ttl')
                    ->info('The default max age of a Response')
                ->end()
                ->enumNode('hash_algo')
                    ->info('Hashing algorithm to use')
                    ->values(hash_algos())
                    ->cannotBeEmpty()
                ->end()
                ->arrayNode('methods')
                    ->info('Which request methods to cache')
                    ->defaultValue(['GET', 'HEAD'])
                    ->prototype('scalar')
                        ->validate()
                            ->ifTrue(function ($v) {
                                /* RFC7230 sections 3.1.1 and 3.2.6 except limited to uppercase characters. */
                                return preg_match('/[^A-Z0-9!#$%&\'*+\-.^_`|~]+/', $v);
                            })
                            ->thenInvalid('Invalid method: %s')
                        ->end()
                    ->end()
                ->end()
                ->scalarNode('respect_cache_headers')
                    ->info('Whether we should care about cache headers or not [DEPRECATED]')
                    ->beforeNormalization()
                        ->always(function ($v) {
                            @trigger_error('The option "respect_cache_headers" is deprecated since version 1.3 and will be removed in 2.0. Use "respect_response_cache_directives" instead.', E_USER_DEPRECATED);

                            return $v;
                        })
                    ->end()
                    ->validate()
                        ->ifNotInArray([null, true, false])
                        ->thenInvalid('Value for "respect_cache_headers" must be null or boolean')
                    ->end()
                ->end()
                ->variableNode('respect_response_cache_directives')
                    ->info('A list of cache directives to respect when caching responses')
                    ->validate()
                        ->always(function ($v) {
                            if (is_null($v) || is_array($v)) {
                                return $v;
                            }

                            throw new InvalidTypeException();
                        })
                    ->end()
                ->end()
            ->end()
        ;

        $cache = $builder->root('cache');
        $cache
            ->canBeEnabled()
            ->info('Configure HTTP caching, requires the php-http/cache-plugin package')
            ->addDefaultsIfNotSet()
            ->validate()
                ->ifTrue(function ($v) {
                    return !empty($v['enabled']) && !class_exists(CachePlugin::class);
                })
                ->thenInvalid('To use the cache plugin, you need to require php-http/cache-plugin in your project')
            ->end()
            ->children()
                ->scalarNode('cache_pool')
                    ->info('This must be a service id to a service implementing '.CacheItemPoolInterface::class)
                    ->isRequired()
                    ->cannotBeEmpty()
                ->end()
                ->scalarNode('stream_factory')
                    ->info('This must be a service id to a service implementing '.StreamFactory::class)
                    ->defaultValue('httplug.stream_factory')
                    ->cannotBeEmpty()
                ->end()
            ->end()
            ->append($config)
        ;

        return $cache;
    }
94367
protected function createBaseRootElement()
    {
        $root = $this->createNewInstance();

        $root->setIsRoot(true);

        $root->setName('_ROOT_' . strtoupper($this->getResourceName()));
        $root->setTitle('_ROOT_' . strtoupper($this->getResourceName()));
        $root->setDescription('ROOT node for ' . $this->getResourceName());
        $root->setLevel(-1);
        $root->setPosition(0);
        $root->setLft(0);
        $root->setRgt(0);
        $root->setRgt(PHP_INT_MAX);

        $root->setParent(null);
        $root->setEnabled(true);

        $this->persist($root);

        $this->updateLftRgtForAllElements();

        return $root;
    }
1166732
public function build(): RequestChildNodesRequest
	{
		$instance = new RequestChildNodesRequest();
		if ($this->nodeId === null) {
			throw new BuilderException('Property [nodeId] is required.');
		}
		$instance->nodeId = $this->nodeId;
		$instance->depth = $this->depth;
		$instance->pierce = $this->pierce;
		return $instance;
	}
903423
public function setOptions(SettingsContainerInterface $options):BBCode{
		$this->options = $options;

		mb_internal_encoding('UTF-8');

		if(
			ini_set('pcre.backtrack_limit', $this->options->pcre_backtrack_limit) === false
			|| ini_set('pcre.recursion_limit', $this->options->pcre_recursion_limit) === false
			|| ini_set('pcre.jit', $this->options->pcre_jit) === false
		){
			throw new BBCodeException('could not alter ini settings');
		}

		if(ini_get('pcre.backtrack_limit') !== (string)$this->options->pcre_backtrack_limit
			|| ini_get('pcre.recursion_limit') !== (string)$this->options->pcre_recursion_limit
			|| ini_get('pcre.jit') !== (string)$this->options->pcre_jit
		){
			throw new BBCodeException('ini settings differ from options');
		}

		if($this->options->sanitizeInput || $this->options->sanitizeOutput){
			$this->sanitizerInterface  = new $this->options->sanitizerInterface($this->options);

			if(!$this->sanitizerInterface instanceof SanitizerInterface){
				throw new BBcodeException('invalid SanitizerInterface');
			}
		}

		if($this->options->preParse || $this->options->postParse){
			$this->parserMiddleware = new $this->options->parserMiddlewareInterface($this->options, $this->cache, $this->logger);

			if(!$this->parserMiddleware instanceof ParserMiddlewareInterface){
				throw new BBcodeException('invalid ParserMiddlewareInterface');
			}
		}

		$this->outputInterface = new $this->options->outputInterface($this->options, $this->cache, $this->logger);

		if(!$this->outputInterface instanceof BBCodeOutputInterface){
			throw new BBcodeException('invalid BBCodeOutputInterface');
		}

		$this->tags    = $this->outputInterface->getTags();
		$this->noparse = $this->outputInterface->getNoparse();
		$this->limit   = (int)$this->options->nestingLimit;

		if(is_array($this->options->allowedTags) && !empty($this->options->allowedTags)){
			$this->allowTags($this->options->allowedTags);
		}
		elseif($this->options->allowAvailableTags === true){
			$this->allowed = $this->tags;
		}

		return $this;
	}
106574
public function CreatePage() 
	{
		parent::CreatePage();
		
		$this->myWords = $this->WordCollection();
		$this->setTitlePage($this->myWords->Value("TITLE"));
		$this->setHelp($this->myWords->Value("DESCRIPTION"));

		$block = new XmlBlockCollection($this->myWords->Value("TITLE"), BlockPosition::Center);
		
		$this->addMenuItem($this->_moduleUrl, $this->myWords->Value("MENULISTPOLLS"), "");
		$this->addMenuItem("module:Xmlnuke.Admin.ManageDBConn", $this->myWords->Value("MENUMANAGEDBCONN"), "");
			
		// Create a NEW config file and SETUP Database
		$configfile = new AnydatasetFilenameProcessor("_poll");
		if (!FileUtil::Exists($configfile))
		{
			$this->CreateSetup($block);
		}
		else 
		{
			$anyconfig = new AnyDataset($configfile->FullQualifiedNameAndPath());
			$it = $anyconfig->getIterator();
			if ($it->hasNext())
			{
				$sr = $it->moveNext();
				$this->_isdb = $sr->getField("dbname") != "-anydata-";
				$this->_connection = $sr->getField("dbname");
				$this->_tblanswer = $sr->getField("tbl_answer");
				$this->_tblpoll = $sr->getField("tbl_poll");
				$this->_tbllastip = $sr->getField("tbl_lastip");
			}
			else 
			{
				$this->CreateSetup($block);
				$this->defaultXmlnukeDocument->addXmlnukeObject($block);
				return $this->defaultXmlnukeDocument->generatePage();
			}
			
			if ($this->_context->get("op") == "")
			{
				$this->ListPoll($block);
			}
			elseif ($this->_context->get("op") == "answer")
			{
				$polldata = explode("|", $this->_context->get("valueid"));
				$this->ListAnswers($block, $polldata[0], $polldata[1]);
			}
			elseif ($this->_context->get("op") == "answernav")
			{
				$this->ListAnswers($block, $this->_context->get("curpoll"), $this->_context->get("curlang"));
			}
		}

		$this->defaultXmlnukeDocument->addXmlnukeObject($block);
		return $this->defaultXmlnukeDocument->generatePage();
	}
609588
private function createAuthenticationPluginNode()
    {
        $treeBuilder = new TreeBuilder('authentication');
        // Keep compatibility with symfony/config < 4.2
        if (!method_exists($treeBuilder, 'getRootNode')) {
            $node = $treeBuilder->root('authentication');
        } else {
            $node = $treeBuilder->getRootNode();
        }

        $node
            ->useAttributeAsKey('name')
            ->prototype('array')
                ->validate()
                    ->always()
                    ->then(function ($config) {
                        switch ($config['type']) {
                            case 'basic':
                                $this->validateAuthenticationType(['username', 'password'], $config, 'basic');

                                break;
                            case 'bearer':
                                $this->validateAuthenticationType(['token'], $config, 'bearer');

                                break;
                            case 'service':
                                $this->validateAuthenticationType(['service'], $config, 'service');

                                break;
                            case 'wsse':
                                $this->validateAuthenticationType(['username', 'password'], $config, 'wsse');

                                break;
                            case 'query_param':
                                $this->validateAuthenticationType(['params'], $config, 'query_param');

                                break;
                        }

                        return $config;
                    })
                ->end()
                ->children()
                    ->enumNode('type')
                        ->values(['basic', 'bearer', 'wsse', 'service', 'query_param'])
                        ->isRequired()
                        ->cannotBeEmpty()
                    ->end()
                    ->scalarNode('username')->end()
                    ->scalarNode('password')->end()
                    ->scalarNode('token')->end()
                    ->scalarNode('service')->end()
                    ->arrayNode('params')->prototype('scalar')->end()
                    ->end()
                ->end()
            ->end(); // End authentication plugin

        return $node;
    }
1199176
public function create()
    {
        $type = NodeType::getByHandle('file');
        if (!is_object($type)) {
            NodeType::add('file');
        }
        $type = NodeType::getByHandle('file_folder');
        if (!is_object($type)) {
            NodeType::add('file_folder');
        }
        $type = NodeType::getByHandle('search_preset');
        if (!is_object($type)) {
            NodeType::add('search_preset');
        }
        $type = TreeType::getByHandle('file_manager');
        if (!is_object($type)) {
            TreeType::add('file_manager');
        }

        $manager = FileManager::get();
        if (!is_object($manager)) {
            $manager = FileManager::add();
        }

        return $manager;
    }
127103
public function createContainer(): Factory
    {
        // First set all the directories
        Core::$appDir = $this->parameters['appDir'];
        Core::$wwwDir = $this->parameters['wwwDir'];
        Core::$tempDir = $this->parameters['tempDir'];
        Core::$logDir = $this->parameters['logDir'];

        // Then set debug mode
        if ($this->parameters['debugMode'])
        {
            define('ENVIRONMENT', 'DEVELOPMENT');
        }
        else
        {
            define('ENVIRONMENT', 'PRODUCTION');
        }

        // And enable Tracy Debugger 
        if (class_exists('Tracy\Debugger', true))
        {
            Debugger::enable(!$this->parameters['debugMode'], realpath($this->parameters['logDir']));
            if (isset($this->parameters['debugEmail']))
            {
                Debugger::$email = $this->parameters['debugEmail'];
            }
            Logger::$useTracy = true;
        }

        // Then load the framework
        Core::init();

        return Factory::getInstance();
    }
756478
private function createModel(): self
    {
        $oInput      = $this->oInput;
        $oOutput     = $this->oOutput;
        $bSkipDb     = $oInput->getOption('skip-db');
        $bSkipSeeder = $oInput->getOption('skip-seeder');
        $bAutoDetect = $oInput->getOption('auto-detect');
        $bLocalised  = $oInput->getOption('localised');
        $bAdmin      = Components::exists('nails/module-admin') && $oInput->getOption('admin');

        //  If auto-detecting models using the database then skip cresting database tables
        if ($bAutoDetect) {
            $bSkipDb = true;
        }

        try {

            if (!$bAutoDetect) {

                $aFields    = $this->getArguments();
                $aModels    = explode(',', $aFields['MODEL_NAME']);
                $aModelData = [];
                sort($aModels);
                foreach ($aModels as $sModelName) {
                    $oModel = $this->prepareModelName($sModelName);

                    /**
                     * Test whether the model exists already
                     *
                     * Alter our behaviour slightly depending if we're localising or not. An existing model, which
                     * is not-localised is OK as we'll convert it to be localised (assuming the --localised flag
                     * is passed).
                     */

                    if ($this->modelExists($oModel)) {
                        if ($bLocalised && classUses($oModel->class_path, Localised::class)) {
                            throw new NailsException(
                                'A localised model by that path already exists "' . $oModel->path . $oModel->filename . '"'
                            );
                        } elseif (!$bLocalised) {
                            throw new NailsException(
                                'A model by that path already exists "' . $oModel->path . $oModel->filename . '"'
                            );
                        }
                    }

                    if (!$bSkipDb && $this->tableExists($oModel)) {
                        if ($bLocalised && classUses($oModel->class_path, Localised::class)) {
                            throw new NailsException(
                                'Localised table "' . $oModel->table_with_prefix . '" already exists. Use option --skip-db to skip database check.'
                            );
                        } elseif (!$bLocalised) {
                            throw new NailsException(
                                'Table "' . $oModel->table_with_prefix . '" already exists. Use option --skip-db to skip database check.'
                            );
                        }
                    }

                    $aModelData[] = $oModel;
                }

            } else {

                $oDb        = Factory::service('PDODatabase');
                $sAppPrefix = defined('APP_DB_PREFIX') ? APP_DB_PREFIX : '';
                $oTables    = $oDb->query('SHOW TABLES LIKE "' . $sAppPrefix . '%";');
                $aTables    = $oTables->fetchAll(\PDO::FETCH_NUM);

                //  If APP_DB_PREFIX is empty then the query above will have all the Nails table's too,
                //  filter them out.
                if (empty($sAppPrefix)) {
                    $aTables = array_filter(
                        $aTables,
                        function ($aTable) {
                            return !preg_match('/^' . NAILS_DB_PREFIX . '/', $aTable[0]);
                        }
                    );
                    $aTables = array_values($aTables);
                }

                $aModelData = array_map(
                    function ($aTable) use ($sAppPrefix) {
                        $sTable = $aTable[0];
                        $sTable = preg_replace('/^' . $sAppPrefix . '/', '', $sTable);
                        $sTable = str_replace('_', ' ', $sTable);
                        $sTable = ucwords($sTable);
                        $sTable = str_replace(' ', '/', $sTable);

                        $oModel = $this->prepareModelName($sTable);

                        return $this->modelExists($oModel) ? null : $oModel;
                    },
                    $aTables
                );
                $aModelData = array_filter($aModelData);
            }

            arraySortMulti($aModelData, 'class_path');

            //  Report to the user and get confirmation
            $oOutput->writeln('The following model(s) will be created:');
            $oOutput->writeln('');
            foreach ($aModelData as $oModel) {
                $oOutput->writeln('Model Class:    <info>\\' . $oModel->class_path . '</info>');
                $oOutput->writeln('Model Path:     <info>' . $oModel->path . $oModel->filename . '</info>');
                if ($bLocalised && $this->modelExists($oModel)) {
                    $oOutput->writeln('Localised:      <info>Model will be converted</info>');
                } else {
                    $oOutput->writeln('Resource Class: <info>\\' . $oModel->resource_class_path . '</info>');
                    $oOutput->writeln('Resource Path:  <info>' . $oModel->resource_path . $oModel->resource_filename . '</info>');
                    if (!$bSkipDb) {
                        $oOutput->writeln('Table:          <info>' . $oModel->table_with_prefix . '</info>');
                    }
                    if ($bAdmin) {
                        $oOutput->writeln('Admin:          <info>Controller will be created</info>');
                    }
                    if (!$bSkipSeeder) {
                        $oOutput->writeln('Seeder:         <info>Seeder will be created</info>');
                    }
                }
                $oOutput->writeln('');
            }

            if ($this->confirm('Continue?', true)) {

                $aServiceModelDefinitions    = [];
                $aServiceResourceDefinitions = [];

                foreach ($aModelData as $oModel) {
                    $oOutput->writeln('');
                    if ($bLocalised && $this->modelExists($oModel)) {
                        $this->convertExistingModelToLocalised(
                            $oModel,
                            $bSkipDb,
                            $bAdmin,
                            $bSkipSeeder
                        );
                    } elseif ($bLocalised && !$this->modelExists($oModel)) {
                        list($sServiceDefinition, $sResourceDefinition) = $this->createLocalisedModel(
                            $oModel,
                            $bSkipDb,
                            $bAdmin,
                            $bSkipSeeder
                        );
                    } else {
                        list($sServiceDefinition, $sResourceDefinition) = $this->createNormalModel(
                            $oModel,
                            $bSkipDb,
                            $bAdmin,
                            $bSkipSeeder
                        );
                    }

                    if (!empty($sServiceDefinition)) {
                        $aServiceModelDefinitions[] = $sServiceDefinition;
                    }

                    if (!empty($sResourceDefinition)) {
                        $aServiceResourceDefinitions[] = $sResourceDefinition;
                    }
                }

                // --------------------------------------------------------------------------

                //  Add models to the app's services array
                if (!empty($aServiceModelDefinitions)) {
                    $this->oOutput->writeln('');
                    $this->oOutput->write('Adding model(s) to app services...');
                    $this->writeServiceFile($aServiceModelDefinitions);
                    $this->oOutput->writeln('<info>done!</info>');
                }

                //  Add resources to app's service array
                if (!empty($aServiceResourceDefinitions)) {
                    $this->oOutput->write('Adding resource(s) to app services...');
                    //  Reset the token detials so we write to the correct part of the file
                    $this->validateServiceFile(static::SERVICE_RESOURCE_TOKEN);
                    $this->writeServiceFile($aServiceResourceDefinitions);
                    $this->oOutput->writeln('<info>done!</info>');
                }
            }

        } catch (\Exception $e) {
            if (!empty($aModelData)) {
                foreach ($aModelData as $oModel) {
                    @unlink($oModel->path . '/' . $oModel->filename);
                }
            }
            throw new NailsException(
                $e->getMessage(),
                is_numeric($e->getCode()) ? $e->getCode() : null
            );
        }

        return $this;
    }
1118939
public function get_bbcode($tag)
	{
		if(!isset($this->bbcodes[$tag]))
			return null;

		return $this->bbcodes[$tag];
	}
1120073
public function parse(string $bbcode):string{

		// sanitize the input if needed
		if($this->options->sanitizeInput){
			$bbcode = $this->sanitizerInterface->sanitizeInput($bbcode);
		}

		// run the pre-parser
		if($this->options->preParse){
			$bbcode = $this->parserMiddleware->pre($bbcode);
		}

		// @todo: array < 2 elements causes a PREG_BACKTRACK_LIMIT_ERROR! (breaks match pattern)
		$singleTags = array_merge(['br', 'hr'], $this->outputInterface->getSingleTags());

		// close singletags: [br] -> [br][/br]
		$bbcode = preg_replace('#\[('.implode('|', $singleTags).')((?:\s|=)[^]]*)?]#is', '[$1$2][/$1]', $bbcode);

		// @todo: find non-singletags without a closing tag and close them (or convert the brackets to entities)

		// protect newlines
		$bbcode = str_replace(["\r", "\n"], ['', $this->options->placeholder_eol], $bbcode);
		// parse the bbcode
		$bbcode = $this->parseBBCode($bbcode);

		// run the post-parser
		if($this->options->postParse){
			$bbcode = $this->parserMiddleware->post($bbcode);
		}

		// replace the newline placeholders
		$bbcode = str_replace($this->options->placeholder_eol, $this->outputInterface->getEOL(), $bbcode);

		// run the sanitizer/html purifier/whatever as a final step
		if($this->options->sanitizeOutput){
			$bbcode = $this->sanitizerInterface->sanitizeOutput($bbcode);
		}

		return $bbcode;
	}
63702
public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root('asf_layout');

        $rootNode
            ->children()
                ->booleanNode('enable_flash_messages')
                    ->defaultTrue()
                ->end()
                ->arrayNode('assets')
                    ->addDefaultsIfNotSet()
                    ->children()
                       ->append($this->addJqueryParameterNode())
                       ->append($this->addTwitterBootstrapParameterNode())
                       ->append($this->addjQueryUIParameterNode())
                       ->append($this->addSelect2ParameterNode())
                       ->append($this->addBazingaJsTranslationParameterNode())
                       ->append($this->addSpeakingURLParameterNode())
                       ->append($this->addTinyMCEParameterNode())
                       ->append($this->addJqueryTagsInputParameterNode())
                       ->append($this->addPrismJSParameterNode())
                       ->booleanNode('fos_js_routing')->defaultFalse()->end()
                    ->end()
                ->end()
                ->scalarNode('components_dir')
                    ->defaultValue(self::COMPONENTS_DIR)
                ->end()
            ->end()
        ;

        return $treeBuilder;
    }