Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Template/Compiler/Tag/Widget.php
<?php

namespace XF\Template\Compiler\Tag;

use
XF\Template\Compiler\Syntax\Tag;
use
XF\Template\Compiler;

class
Widget extends AbstractTag
{
    public function
compile(Tag $tag, Compiler $compiler, array $context, $inlineExpected)
    {
       
$tag->assertEmpty();
       
$context['escape'] = false;
       
$attributes = $tag->attributes;
       
$argumentsCode = 'array()';

        if (isset(
$attributes['key']))
        {
            if (!(
$attributes['key'] instanceof Compiler\Syntax\Str))
            {
                throw
$tag->exception(\XF::phrase('template_tag_attribute_x_must_be_literal_string', ['name' => 'key']));
            }

            if (!
preg_match('#^[a-z0-9_]+$#i', $attributes['key']->content))
            {
                throw
$tag->exception(\XF::phrase('widget_keys_may_only_contain_alphanumeric_underscore'));
            }

           
$identifier = $attributes['key']->compile($compiler, $context, true);
        }
        else if (isset(
$attributes['class']))
        {
            if (!(
$attributes['class'] instanceof Compiler\Syntax\Str))
            {
                throw
$tag->exception(\XF::phrase('template_tag_attribute_x_must_be_literal_string', ['name' => 'class']));
            }

           
$arguments = [];
            foreach (
$attributes AS $attribute => $value)
            {
                if (
preg_match('#^opt-([a-zA-Z0-9_-]+)$#', $attribute, $match))
                {
                    if (
strpos($match[1], '-') !== false)
                    {
                        throw
$tag->exception(\XF::phrase('widget_option_names_may_only_contain_alphanumeric_underscore'));
                    }

                   
$arguments[$match[1]] = $value;
                }
                else if (
$attribute == 'title')
                {
                   
// Set an attribute which is treated as a special case later on to override the title
                   
$arguments['_title'] = $value;
                }
            }

           
$class = $attributes['class'];

            if (
strpos($class->content, ':') === false && strpos($class->content, '\\') === false)
            {
                throw
$tag->exception(\XF::phrase('widget_tag_widget_attribute_must_be_widget_definition_class_name'));
            }

           
$class->content = \XF::stringToClass($class->content, '%s\Widget\%s');
           
$identifier = $class->compile($compiler, $context, true);

            if (
$arguments)
            {
               
$arguments = $this->compileAttributesAsArray($arguments, $compiler, $context);
               
$indent = $compiler->indent();
               
$argumentsCode = "array(" . implode('', $arguments) . "\n$indent)";
            }
        }
        else
        {
            throw
$tag->exception(\XF::phrase('widget_tags_must_contain_either_key_or_widget_attribute'));
        }

       
$contextParams = [];
        foreach (
$attributes AS $attribute => $value)
        {
            if (
preg_match('#^context-([a-zA-Z0-9_-]+)$#', $attribute, $match))
            {
                if (
strpos($match[1], '-') !== false)
                {
                    throw
$tag->exception(\XF::phrase('context_param_names_may_only_contain_alphanumeric_underscore'));
                }

               
$contextParams[$match[1]] = $value;
            }
        }

        if (
$contextParams)
        {
           
$contextParams = $this->compileAttributesAsArray($contextParams, $compiler, $context);
           
$indent = $compiler->indent();
           
$contextCode = "array(" . implode('', $contextParams) . "\n$indent)";
        }
        else
        {
           
$contextCode = 'array()';
        }

       
$widget = "{$compiler->templaterVariable}->renderWidget({$identifier}, {$argumentsCode}, {$contextCode})";

        if (!empty(
$attributes['position']))
        {
            if (!(
$attributes['position'] instanceof Compiler\Syntax\Str))
            {
                throw
$tag->exception(\XF::phrase('template_tag_attribute_x_must_be_literal_string', ['name' => 'position']));
            }

           
// this used to be the key/class itself, but that would prevent rendering the same widget with various
            // options set, so instead set it to be unique based on the code generated
           
$keyId = md5($widget);

           
$position = strtolower($attributes['position']->content);
            switch (
$position)
            {
                case
'sidebar':
                   
$key = $compiler->getStringCode('_xfWidgetSidebar' . \XF\Util\Php::camelCase($keyId, ['_', '\\']));
                   
$compiler->write("{$compiler->templaterVariable}->modifySidebarHtml({$key}, {$widget}, 'replace');");
                    break;

                case
'sidenav':
                   
$key = $compiler->getStringCode('_xfWidgetSideNav' . \XF\Util\Php::camelCase($keyId, ['_', '\\']));
                   
$compiler->write("{$compiler->templaterVariable}->modifySideNavHtml({$key}, {$widget}, 'replace');");
                    break;

                default:
                    throw
$tag->exception(\XF::phrase('unknown_position_x', ['position' => $position]));
            }

            return
$inlineExpected ? "''" : false;
        }
        else
        {
            return
$widget;
        }
    }
}