Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Service/Style/Export.php
<?php

namespace XF\Service\Style;

use
XF\Entity\Style;
use
XF\Util\Xml;

class
Export extends \XF\Service\AbstractService
{
    const
EXPORT_VERSION_ID = 2;

   
/**
     * @var Style
     */
   
protected $style;

   
/**
     * @var \XF\Entity\AddOn
     */
   
protected $addOn;

    protected
$independent = false;

    protected
$changedAssets = [];

    public function
__construct(\XF\App $app, Style $style)
    {
       
parent::__construct($app);
       
$this->setStyle($style);
    }

    public function
setStyle(Style $style)
    {
       
$this->style = $style;
    }

    public function
getStyle()
    {
        return
$this->style;
    }

    public function
setAddOn(\XF\Entity\AddOn $addOn = null)
    {
       
$this->addOn = $addOn;
    }

    public function
getAddOn()
    {
        return
$this->addOn;
    }

    public function
setIndependent($independent)
    {
       
$this->independent = (bool)$independent;
    }

    public function
getIndependent()
    {
        return
$this->independent;
    }

    public function
addChangedAsset(string $key, string $path)
    {
       
$this->changedAssets[$key] = $path;
    }

    public function
exportToXml()
    {
       
$document = $this->createXml();
       
$styleNode = $this->getStyleNode($document);
       
$document->appendChild($styleNode);

       
$assetsNode = $document->createElement('assets');
       
$styleNode->appendChild($assetsNode);

        foreach (
$this->getExportableAssets() AS $key => $path)
        {
           
$assetsNode->appendChild($this->getAssetNode($document, $key, $path));
        }

       
$templatesNode = $document->createElement('templates');
       
$styleNode->appendChild($templatesNode);

        foreach (
$this->getExportableTemplates() AS $template)
        {
           
$templatesNode->appendChild($this->getTemplateNode($document, $template));
        }

       
$propertiesNode = $document->createElement('properties');
       
$styleNode->appendChild($propertiesNode);

        foreach (
$this->getExportablePropertyGroups() AS $group)
        {
           
$propertiesNode->appendChild($this->getPropertyGroupNode($document, $group));
        }

        foreach (
$this->getExportableProperties() AS $data)
        {
           
$propertiesNode->appendChild($this->getPropertyNode($document, $data['property'], $data['addon_id']));
        }

        return
$document;
    }

    public function
getExportFileName()
    {
       
$title = str_replace(' ', '-', utf8_romanize(utf8_deaccent($this->style->title)));
       
$addOnLimit = $this->addOn ? '-' . $this->addOn->addon_id_url : '';

        return
"style-{$title}{$addOnLimit}.xml";
    }

   
/**
     * @return \DOMDocument
     */
   
protected function createXml()
    {
       
$document = new \DOMDocument('1.0', 'utf-8');
       
$document->formatOutput = true;

        return
$document;
    }

    protected function
getStyleNode(\DOMDocument $document)
    {
       
$style = $this->style;

       
$styleNode = $document->createElement('style');
       
$styleNode->setAttribute('title', $style->title);
       
$styleNode->setAttribute('description', $style->description);
       
$styleNode->setAttribute('user_selectable', $style->user_selectable);
        if (
$this->addOn)
        {
           
$styleNode->setAttribute('addon_id', $this->addOn->addon_id);
           
$styleNode->setAttribute('base_version_id', $this->addOn->version_id);
        }
        else
        {
           
$styleNode->setAttribute('base_version_id', \XF::$versionId);
        }
       
$styleNode->setAttribute('export_version', self::EXPORT_VERSION_ID);

        return
$styleNode;
    }

    protected function
getAssetNode(\DOMDocument $document, string $key, string $path): \DOMElement
   
{
       
$assetNode = $document->createElement('asset');
       
$assetNode->setAttribute('key', $key);
       
$assetNode->setAttribute('path', $this->changedAssets[$key] ?? $this->stripDataStylesPathPrefix($path));

        return
$assetNode;
    }

    public function
stripDataStylesPathPrefix(string $abstractedPath): string
   
{
        return
preg_replace('#^data://styles/\d+/#i', '', $abstractedPath);
    }

    protected function
getTemplateNode(\DOMDocument $document, array $template)
    {
       
$templateNode = $document->createElement('template');
       
$templateNode->setAttribute('title', $template['title']);
       
$templateNode->setAttribute('type', $template['type']);
       
$templateNode->setAttribute('addon_id', $template['addon_id']);
       
$templateNode->setAttribute('version_id', $template['version_id']);
       
$templateNode->setAttribute('version_string', $template['version_string']);
       
$templateNode->appendChild(
            \
XF\Util\Xml::createDomCdataSection($document, $template['template'])
        );

        return
$templateNode;
    }

    protected function
getPropertyGroupNode(\DOMDocument $document, \XF\Entity\StylePropertyGroup $group)
    {
       
$mapped = [
           
'group_name',
           
'title',
           
'description',
           
'display_order',
           
'addon_id'
       
];

       
$groupNode = $document->createElement('group');
        foreach (
$mapped AS $attr)
        {
           
$groupNode->setAttribute($attr, $group->getValue($attr));
        }

        return
$groupNode;
    }

    protected function
getPropertyNode(\DOMDocument $document, \XF\Entity\StyleProperty $property, $addOnId)
    {
       
$mapped = [
           
'property_name',
           
'group_name',
           
'title',
           
'description',
           
'property_type',
           
'value_type',
           
'depends_on',
           
'value_group',
           
'display_order'
       
];

       
$propertyNode = $document->createElement('property');
        foreach (
$mapped AS $attr)
        {
           
$propertyNode->setAttribute($attr, $property->getValue($attr));
        }

        if (
$property->css_components)
        {
           
$propertyNode->setAttribute('css_components', implode(',', $property->css_components));
        }

       
$propertyNode->setAttribute('addon_id', $addOnId);

        if (
$property->value_parameters !== '')
        {
           
$propertyNode->appendChild(Xml::createDomElement($document, 'value_parameters', $property->value_parameters));
        }

       
$propertyNode->appendChild(
           
Xml::createDomElement($document, 'value', \XF\Util\Json::jsonEncodePretty($property->property_value))
        );

        return
$propertyNode;
    }

   
/**
     * @return array
     */
   
protected function getExportableAssets(): array
    {
       
$style = $this->style;

        if (
$this->independent)
        {
            return
$style->effective_assets;
        }
        else
        {
            return
$style->assets;
        }
    }

   
/**
     * @return array
     */
   
protected function getExportableTemplates()
    {
       
$style = $this->style;

       
$db = $this->db();

       
$addonLimitSql = ($this->addOn ? " AND master.addon_id = " . $db->quote($this->addOn->addon_id) : '');

        if (
$this->independent)
        {
            return
$db->fetchAll("
                SELECT template.*,
                    IF(template.addon_id, template.addon_id, COALESCE(master.addon_id, '')) AS addon_id
                FROM xf_template_map AS map
                INNER JOIN xf_template AS template ON (map.template_id = template.template_id)
                LEFT JOIN xf_template AS master ON (master.title = template.title AND master.type = template.type AND master.style_id = 0)
                WHERE map.style_id = ?
                    AND template.style_id <> 0
                   
$addonLimitSql
                ORDER BY map.title
            "
, $style->style_id);
        }
        else
        {
            return
$db->fetchAll("
                SELECT template.*,
                    IF(template.addon_id, template.addon_id, COALESCE(master.addon_id, '')) AS addon_id
                FROM xf_template AS template
                LEFT JOIN xf_template AS master ON (master.title = template.title AND master.type = template.type AND master.style_id = 0)
                WHERE template.style_id = ?
                   
$addonLimitSql
                ORDER BY template.title
            "
, $style->style_id);
        }
    }

   
/**
     * @return array
     */
   
protected function getExportableProperties()
    {
       
$style = $this->style;

       
$db = $this->db();

       
$addonLimitSql = ($this->addOn ? " AND master.addon_id = " . $db->quote($this->addOn->addon_id) : '');

        if (
$this->independent)
        {
           
$results = $db->fetchAllKeyed("
                SELECT property.property_id,
                    IF(property.addon_id, property.addon_id, COALESCE(master.addon_id, '')) AS addon_id
                FROM xf_style_property_map AS map
                INNER JOIN xf_style_property AS property ON (map.property_id = property.property_id)
                LEFT JOIN xf_style_property AS master ON (master.property_name = property.property_name AND master.style_id = 0)
                WHERE map.style_id = ?
                    AND property.style_id <> 0
                   
$addonLimitSql
                ORDER BY map.property_name
            "
, 'property_id', $style->style_id);
        }
        else
        {
           
$results = $db->fetchAllKeyed("
                SELECT property.property_id,
                    IF(property.addon_id, property.addon_id, COALESCE(master.addon_id, '')) AS addon_id
                FROM xf_style_property AS property
                LEFT JOIN xf_style_property AS master ON (master.property_name = property.property_name AND master.style_id = 0)
                WHERE property.style_id = ?
                   
$addonLimitSql
                ORDER BY property.property_name
            "
, 'property_id', $style->style_id);
        }

       
$properties = $this->em()->findByIds('XF:StyleProperty', array_keys($results));

        foreach (
$results AS $id => $result)
        {
            if (!isset(
$properties[$id]))
            {
                unset(
$results[$id]);
            }

           
$results[$id]['property'] = $properties[$id];
        }

        return
$results;
    }

   
/**
     * @return array
     */
   
protected function getExportablePropertyGroups()
    {
       
$propertyRepo = $this->repository('XF:StyleProperty');
       
$groups = $propertyRepo->getEffectivePropertyGroupsInStyle($this->style);
       
$output = [];
        foreach (
$groups AS $group)
        {
            if (
$this->independent)
            {
                if (
$group->style_id == 0)
                {
                    continue;
                }
            }
            else
            {
                if (
$group->style_id != $this->style->style_id)
                {
                    continue;
                }
            }

            if (
$this->addOn && $this->addOn->addon_id != $group->addon_id)
            {
                continue;
            }

           
$output[$group->group_name] = $group;
        }

        return
$output;
    }
}