Вход Регистрация
Файл: library/XenForo/Template/Compiler/Tag/Admin/Abstract.php
Строк: 533
<?php

/**
* Abstract base for template tags that apply to the admin area.
*
* @package XenForo_Template
*/
abstract class XenForo_Template_Compiler_Tag_Admin_Abstract
{
    
/**
     * Standard options that apply to the row for (almost) all *unit tags.
     *
     * @var array
     */
    
protected static $_standardRowOptions = array(
        
'label',
        
'hint',
        
'explain',
        
'class'
    
);

    
/**
     * Standard control-level options. These apply to most controls but not all.
     * Use this if the control support most or all of the standard options.
     *
     * @var array
     */
    
protected static $_standardControlOptions = array(
        
'id',
        
'name',
        
'value',
        
'title',
        
'inputclass',
        
'listclass',
        
'after',
        
'readonly'
    
);

    protected static 
$_standardOptionTags = array(
        
'option',
        
'options',
        
'optgroup',
        
'foreach'
    
);

    
/**
    * Gets the standard data out of a list of segments. Data will be pulled from tags
    * in that list and their attributes only.
    *
    * @param XenForo_Template_Compiler
    * @param array List of segments
    * @param array An optional list of additional tags that are allowed
    *
    * @return array Keys are standard data types that were found
    */
    
protected function _getStandardAdminTagData(XenForo_Template_Compiler $compiler, array $segments, array $extraAllowedTags = array())
    {
        
$segments $compiler->prepareSegmentsForIteration($segments);

        
$output = array();
        
$foundContent false;

        foreach (
$segments AS $segment)
        {
            if (
is_string($segment))
            {
                if (
trim($segment) !== '')
                {
                    
$foundContent true;
                }
                continue;
            }
            else if (!isset(
$segment['type']) || $segment['type'] != 'TAG')
            {
                
$foundContent true;
                continue;
            }

            switch (
$segment['name'])
            {
                case 
'label';
                    
$attributes $segment['attributes'];

                    if (isset(
$attributes['hidden']))
                    {
                        
$output['labelHidden'] = $attributes['hidden'];
                    }

                    if (isset(
$attributes['hint']))
                    {
                        
$output['hint'] = $attributes['hint'];
                    }

                    
$output['label'] = $segment['children'];
                break;

                case 
'hint':
                case 
'explain':
                case 
'html':
                    
$output[$segment['name']] = $segment['children'];
                break;

                default:
                    if (!
$extraAllowedTags || !in_array($segment['name'], $extraAllowedTags))
                    {
                        
// all other tags are "content" tags
                        
$foundContent true;
                    }
            }
        }

        if (
$output && $foundContent)
        {
            
// found some known tags, some content -- error
            
throw $compiler->getNewCompilerException(new XenForo_Phrase('found_unexpected_content_within_an_admin_control_tag'));
        }
        else if (
$foundContent)
        {
            
// content only -- treat it as HTML tag
            
$output = array('html' => $segments);
        }

        return 
$output;
    }

    
/**
     * Gets the standard row options from attributes or child tags.
     *
     * @param XenForo_Template_Compiler $compiler
     * @param array $attributes Attributes
     * @param array $children Child elements
     * @param array $extraAllowedTags List of extra allowed child tags (that won't be treated as "content")
     *
     * @return array Key-value pairs of row options
     */
    
protected function _getRowOptions(XenForo_Template_Compiler $compiler, array $attributes, array $children, array $extraAllowedTags = array())
    {
        return 
array_merge(
            
$compiler->getNamedAttributes($attributesself::$_standardRowOptions),
            
$this->_getStandardAdminTagData($compiler$children$extraAllowedTags)
        );
    }

    
/**
     * Gets the control options for a given tag.
     *
     * @param XenForo_Template_Compiler $compiler
     * @param array $attributes Raw key-value attribues list
     * @param array $extraExpected Extra expected attributes, on top of the standard
     * @param boolean $includeStandard If true, include the standard control tags
     * @param boolean $allowData If true, allow all data-* attributes
     *
     * @return array Key-value pairs of expected attributes; data attributes in _data key
     */
    
protected function _getControlOptions(XenForo_Template_Compiler $compiler, array $attributes, array $extraExpected = array(),
        
$includeStandard true$allowData true
    
)
    {
        if (
$includeStandard)
        {
            
$extraExpected array_merge($extraExpectedself::$_standardControlOptions);
        }

        
$controlOptions $compiler->getNamedAttributes($attributes$extraExpected);

        if (
$allowData)
        {
            
$data $this->_getDataAttributes($compiler$attributes);
            if (
$data)
            {
                
$controlOptions['_data'] = $data;
            }
        }

        return 
$controlOptions;
    }

    
/**
     * Gets all data-* attributes and returns them as an array without the
     * data prefix.
     *
     * @param array $attributes
     *
     * @return array Key-value data pairs, without the "data-" prefix
     */
    
protected function _getDataAttributes(XenForo_Template_Compiler $compiler, array $attributes)
    {
        
$data = array();

        foreach (
$attributes AS $key => $value)
        {
            if (
strtolower(substr($key05)) == 'data-')
            {
                
$dataKey substr($key5);
                if (
is_string($dataKey) && strlen($dataKey) >= 1)
                {
                    if (
strval(intval($dataKey)) === $dataKey)
                    {
                        throw 
$compiler->getNewCompilerException(new XenForo_Phrase('data_attributes_names_may_not_look_like_integers'));
                    }

                    
$data[$dataKey] = $value;
                }
            }
        }

        return 
$data;
    }

    
/**
    * Compiles the standard data and removes it from the optional extra data for
    * use as separate arguments.
    *
    * @param XenForo_Template_Compiler
    * @param array Options for the compiler
    * @param array Row options. Will be modified by reference.
    * @param array Control options. Will be modified by reference.
    *
    * @return array Standardized data (label, name, value)
    */
    
protected function _compileStandardData(XenForo_Template_Compiler $compiler, array $compilerOptions, array &$rowOptions, array &$controlOptions = array())
    {
        if (isset(
$rowOptions['label']))
        {
            
$label $rowOptions['label'];
            unset(
$rowOptions['label']);
        }
        else
        {
            
$label '';
        }

        if (isset(
$controlOptions['name']))
        {
            
$name $controlOptions['name'];
            unset(
$controlOptions['name']);
        }
        else
        {
            
$name '';
        }

        if (isset(
$controlOptions['value']))
        {
            
$value $controlOptions['value'];
            unset(
$controlOptions['value']);
        }
        else
        {
            
$value '';
        }

        return array(
            
'label' => $compiler->compileAndCombineSegments($label$compilerOptions),
            
'name' => $compiler->compileAndCombineSegments($name$compilerOptions),
            
'value' => $compiler->compileAndCombineSegments($value$compilerOptions)
        );
    }

    
/**
     * Helper to compile the standard row options with the default options.
     *
     * @param XenForo_Template_Compiler $compiler
     * @param array $rowOptions
     * @param array $compilerOptions
     *
     * @return string
     */
    
protected function _compileRowOptions(XenForo_Template_Compiler $compiler, array $rowOptions, array $compilerOptions,
        &
$htmlCode '', &$htmlOutputVar '')
    {
        if (isset(
$rowOptions['html']))
        {
            
$htmlCode $compiler->compileIntoVariable($rowOptions['html'], $htmlOutputVar$compilerOptions);
            unset(
$rowOptions['html']);
        }
        else
        {
            
$htmlCode '';
            
$htmlOutputVar '';
        }

        
$params $compiler->compileNamedParams($rowOptions$compilerOptions, array('labelHidden'));
        if (
$htmlCode !== '' && !empty($htmlOutputVar))
        {
            
$params["html"] = '$' $htmlOutputVar;
        }

        return 
$compiler->buildNamedParamCode($params);
    }

    
/**
     * Gets the choices that apply to this tag, via option/optgroup/options tags.
     *
     * @param array $children Child tags to search
     * @param XenForo_Template_Compiler $compiler Compiler
     * @param array $options Compiler options
     * @param string $newOutputVar
     *
     * @return string
     */
    
protected function _getChoicesCode(array $childrenXenForo_Template_Compiler $compiler, array $options, &$newOutputVar '')
    {
        
$oldOutputVar $compiler->getOutputVar();
        
$newOutputVar $compiler->getUniqueVar();
        
$compiler->setOutputVar($newOutputVar);

        
$code '$' $newOutputVar " = array();n";

        foreach (
$children AS $child)
        {
            
$compiler->setLastVistedSegment($child);
            
$code .= $this->_compileChoiceChild($newOutputVar$child$compiler$options);
        }

        
$compiler->setOutputVar($oldOutputVar);

        return 
$code;
    }

    protected function 
_compileChoiceChild($newOutputVar$childXenForo_Template_Compiler $compiler, array $options)
    {
        if (
$compiler->isSegmentNamedTag($child'foreach'))
        {
            
$inner '';
            foreach (
$child['children'] AS $grandChild)
            {
                
$inner .= $this->_compileChoiceChild($newOutputVar$grandChild$compiler$options);
            }
            
$statement XenForo_Template_Compiler_Tag_Foreach::compileForeach($inner$compiler$child['attributes'], $options);
            return 
$statement->getFullStatements($newOutputVar);
        }
        else if (
$compiler->isSegmentNamedTag($child'option'))
        {
            
$choice $compiler->getNamedAttributes($child['attributes'], array('label''name''value''selected''hint''id''class''inputclass''title''depth''disabled''optdisabled''unselectable'));

            
$childrenAsLabel = (isset($choice['label']) ? false true); // if label attribute, then assume children as "special"
            
$foundOther false;
            
$disabledControls = array();

            foreach (
$child['children'] AS $optionChild)
            {
                if (!
is_array($optionChild) || !isset($optionChild['type']) || $optionChild['type'] != 'TAG')
                {
                    continue;
                }

                
$optionChildName strtolower($optionChild['name']);

                switch (
$optionChildName)
                {
                    case 
'label':
                    case 
'hint':
                        
$choice[$optionChildName] = $optionChild['children'];
                        
$childrenAsLabel false;
                        break;

                    case 
'checkbox':
                    case 
'combobox':
                    case 
'password':
                    case 
'radio':
                    case 
'select':
                    case 
'spinbox':
                    case 
'textbox':
                    case 
'upload':
                        
$disabledControls[] = $optionChild;
                        
$childrenAsLabel false;
                        break;

                    case 
'disabled':
                        
$disabledControls[] = $optionChild['children'];
                        
$childrenAsLabel false;
                        break;

                    default:
                        
$foundOther $optionChild;
                }
            }

            if (!isset(
$choice['label']))
            {
                if (!
$childrenAsLabel)
                {
                    throw 
$compiler->getNewCompilerException(new XenForo_Phrase('missing_label_for_option_tag'), $child);
                }

                
$choice['label'] = $child['children'];
            }

            
$data $this->_getDataAttributes($compiler$child['attributes']);
            if (
$data)
            {
                
$choice['_data'] = $data;
            }

            if (!
$childrenAsLabel && $foundOther)
            {
                
// have special tags as child and found unexpected
                
throw $compiler->getNewCompilerException(new XenForo_Phrase('found_unexpected_tag_x_as_disabled_control', array('tag' => $foundOther['name'])), $foundOther);
            }

            
$compiled $compiler->compileNamedParams($choice$options, array('selected'));

            
$disabledCode '';
            if (
$disabledControls)
            {
                
$compiled['disabled'] = array();

                foreach (
$disabledControls AS $disabled)
                {
                    
$disabledCode .= $compiler->compileIntoVariable($disabled$disabledOutputVar$optionstrue);
                    
$compiled['disabled'][] = '$' $disabledOutputVar;
                }
            }

            
$additionalCode $disabledCode '$' $newOutputVar '[] = ' $compiler->buildNamedParamCode($compiled) . ";n";

            if (!empty(
$compiled['disabled']))
            {
                
$additionalCode .= 'unset(' implode(', '$compiled['disabled']) . ");n";
            }

            if (!empty(
$child['attributes']['displayif']))
            {
                
$condition $compiler->parseConditionExpression($child['attributes']['displayif'], $options);
                return 
'if ' $condition "n{n" $additionalCode "}n";
            }
            else
            {
                return 
$additionalCode;
            }
        }
        else if (
$compiler->isSegmentNamedTag($child'options'))
        {
            if (!isset(
$child['attributes']['source']))
            {
                throw 
$compiler->getNewCompilerException(new XenForo_Phrase('options_tag_must_have_source_attribute'), $child);
            }
            
$sourceVar $compiler->compileVarRef($child['attributes']['source'], array_merge($options, array('varEscape' => false)));

            if (!empty(
$child['attributes']['raw']))
            {
                
$raw $compiler->parseConditionExpression($child['attributes']['raw'], $options);
            }
            else
            {
                
$raw 'false';
            }

            return 
'$' $newOutputVar ' = XenForo_Template_Helper_Admin::mergeOptionArrays('
                
'$' $newOutputVar ', ' $sourceVar ', '$raw ");n";
        }
        else if (
$compiler->isSegmentNamedTag($child'optgroup'))
        {
            if (!isset(
$child['attributes']['label']))
            {
                throw 
$compiler->getNewCompilerException(new XenForo_Phrase('optgroups_must_have_label'), $child);
            }

            
$label $compiler->compileAndCombineSegments($child['attributes']['label']);

            
$groupVar null// changed by next line
            
$code $this->_getChoicesCode($child['children'], $compiler$options$groupVar);
            
$code .= '$' $newOutputVar '[' $label '] = $' $groupVar ";n";
            
$code .= 'unset($' $groupVar ");n";

            return 
$code;
        }
        else
        {
            return 
'';
        }
    }

    
/**
     * Gets the compiled output for a function call, with extra preceding statements
     * and variables to unset.
     *
     * @param XenForo_Template_Compiler $compiler
     * @param string $function Function to call in XenForo_Template_Helper_Admin namespace
     * @param string $args String of PHP code for args
     * @param string|array $extraStatements List of extra, raw PHP statements to prepend
     * @param string|array $unsetVars List of variables to unset at the end, not including leading
     *
     * @return XenForo_Template_Compiler_Statement_Raw
     */
    
protected function _getCompiledOutput(XenForo_Template_Compiler $compiler$function$args$extraStatements false$unsetVars false)
    {
        
$statement $compiler->getNewRawStatement();

        if (!
is_array($extraStatements))
        {
            
$extraStatements = array($extraStatements);
        }

        foreach (
$extraStatements AS $extra)
        {
            if (
is_string($extra) && $extra !== '')
            {
                
$statement->addStatement($extra);
            }
        }

        
$statement->addStatement(
            
'$' $compiler->getOutputVar() . ' .= XenForo_Template_Helper_Admin::' $function '(' $args ");n"
        
);

        if (
is_string($unsetVars))
        {
            
$unsetVars = array($unsetVars);
        }

        if (
is_array($unsetVars))
        {
            
$unset '';
            foreach (
$unsetVars AS $unsetVar)
            {
                if (!
is_string($unsetVar) || $unsetVar === '')
                {
                    continue;
                }
                if (
$unset)
                {
                    
$unset .= ', ';
                }
                
$unset .= '$' $unsetVar;
            }

            if (
$unset)
            {
                
$statement->addStatement('unset(' $unset ");n");
            }
        }

        return 
$statement;
    }

}
Онлайн: 0
Реклама