Вход Регистрация
Файл: library/XenForo/Model/TemplateModificationAbstract.php
Строк: 412
<?php

abstract class XenForo_Model_TemplateModificationAbstract extends XenForo_Model
{
    protected 
$_modTableName '';
    protected 
$_logTableName '';
    protected 
$_dataWriterName '';

    abstract public function 
onAddonActiveSwitch(array $addon);

    public function 
getModificationById($id)
    {
        return 
$this->_getDb()->fetchRow("
            SELECT *
            FROM 
{$this->_modTableName}
            WHERE modification_id = ?
        "
$id);
    }

    public function 
getModificationByKey($key)
    {
        return 
$this->_getDb()->fetchRow("
            SELECT *
            FROM 
{$this->_modTableName}
            WHERE modification_key = ?
        "
$key);
    }

    public function 
getAllModifications()
    {
        return 
$this->fetchAllKeyed("
            SELECT *
            FROM 
{$this->_modTableName}
            ORDER BY template, execution_order
        "
'modification_id');
    }

    public function 
getModificationsByKeys(array $keys)
    {
        if (!
$keys)
        {
            return array();
        }

        return 
$this->fetchAllKeyed("
            SELECT *
            FROM 
{$this->_modTableName}
            WHERE modification_key IN (" 
$this->_getDb()->quote($keys) . ")
        "
'modification_key');
    }

    public function 
groupModificationsByAddon(array $modifications)
    {
        
$results = array();
        foreach (
$modifications AS $id => $modification)
        {
            
$results[$modification['addon_id']][$id] = $modification;
        }

        return 
$results;
    }

    public function 
getModificationsForTemplate($title)
    {
        return 
$this->fetchAllKeyed("
            SELECT *
            FROM 
{$this->_modTableName}
            WHERE template = ?
            ORDER BY execution_order
        "
'modification_id'$title);
    }

    public function 
getActiveModificationsForTemplate($title)
    {
        return 
$this->fetchAllKeyed("
            SELECT modification.*
            FROM 
{$this->_modTableName} AS modification
            LEFT JOIN xf_addon AS addon ON (addon.addon_id = modification.addon_id)
            WHERE modification.template = ?
                AND modification.enabled = 1
                AND (addon.active IS NULL OR addon.active = 1)
            ORDER BY modification.execution_order
        "
'modification_id'$title);
    }

    public function 
getModificationLogSummary()
    {
        return 
$this->fetchAllKeyed("
            SELECT modification_id,
                SUM(apply_count) AS ok,
                COUNT(IF(status = 'ok' AND apply_count = 0, 1, NULL)) AS not_found,
                COUNT(IF(status LIKE 'error%', 1, NULL)) AS error
            FROM 
{$this->_logTableName}
            GROUP BY modification_id
        "
'modification_id');
    }

    public function 
getModificationLogsForModification($modificationId)
    {
        return 
$this->fetchAllKeyed("
            SELECT *
            FROM 
{$this->_logTableName}
            WHERE modification_id = ?
        "
'template_id'$modificationId);
    }

    public function 
getModificationTemplateTitlesForAddon($addOnId)
    {
        return 
$this->_getDb()->fetchCol("
            SELECT DISTINCT template
            FROM 
{$this->_modTableName}
            WHERE addon_id = ?
        "
$addOnId);
    }

    public function 
updateTemplateModificationLog($templateId, array $modificationStatuses)
    {
        
$inserts = array();
        
$db $this->_getDb();
        
$quotedTemplateId $db->quote($templateId);

        foreach (
$modificationStatuses AS $id => $status)
        {
            if (
is_int($status))
            {
                
$inserts[] = '(' $quotedTemplateId .
                    
', ' $db->quote($id) .
                    
", 'ok', " $db->quote($status) . ')';
            }
            else
            {
                
$inserts[] = '(' $quotedTemplateId .
                    
', ' $db->quote($id) .
                    
', ' $db->quote($status) . ', 0)';
            }
        }

        
$db->delete($this->_logTableName'template_id = ' $quotedTemplateId);
        if (
$inserts)
        {
            
$db->query("
                INSERT INTO 
{$this->_logTableName}
                    (template_id, modification_id, status, apply_count)
                VALUES " 
implode(', '$inserts)
            );
        }
    }

    public function 
applyModificationsToTemplate($title$template, &$status = array())
    {
        
$modifications $this->getActiveModificationsForTemplate($title);
        return 
$this->applyTemplateModifications($template$modifications$status);
    }

    public function 
applyTemplateModifications($template, array $modifications, &$status = array())
    {
        
$status = array();

        foreach (
$modifications AS $id => $modification)
        {
            
$template str_replace("rn""n"$template);

            switch (
$modification['action'])
            {
                case 
'str_replace':
                    
$modification['find'] = str_replace("rn""n"$modification['find']);
                    
$modification['replace'] = str_replace('$0'$modification['find'], $modification['replace']);

                    
$status[$id] = substr_count($template$modification['find']);
                    
$template str_replace($modification['find'], $modification['replace'], $template);
                    break;

                case 
'preg_replace':
                case 
'callback':
                    
$modification['find'] = str_replace(
                        array(
"rn"'rn'),
                        array(
"n"'n'),
                        
$modification['find']
                    );

                    try
                    {
                        if (
preg_match('/W[sw]*e[sw]*$/'$modification['find']))
                        {
                            
// can't run a /e regex
                            
$status[$id] = 'error_invalid_regex';
                        }
                        else
                        {
                            
$status[$id] = preg_match_all($modification['find'], $template$null);
                        }
                    }
                    catch (
ErrorException $e)
                    {
                        
$status[$id] = 'error_invalid_regex';
                        break;
                    }

                    if (
$modification['action'] == 'callback')
                    {
                        if (
XenForo_Application::getConfig()->enableTemplateModificationCallbacks)
                        {
                            if (
preg_match('/^([a-z0-9_\\]+)::([a-z0-9_]+)$/i'$modification['replace'], $match))
                            {
                                if (!
class_exists($match[1]) || !is_callable(array($match[1], $match[2])))
                                {
                                    
$status[$id] = 'error_invalid_callback';
                                }
                                else
                                {
                                    try
                                    {
                                        
$template preg_replace_callback(
                                            
$modification['find'],
                                            array(
$match[1], $match[2]),
                                            
$template
                                        
);
                                    }
                                    catch (
Exception $e)
                                    {
                                        
$status[$id] = 'error_callback_failed';
                                        
XenForo_Error::logException($efalse'Template modification callback error: ');
                                    }
                                }
                            }
                            else
                            {
                                
$status[$id] = 'error_invalid_callback';
                            }
                        }
                    }
                    else
                    {
                        
$template preg_replace($modification['find'], $modification['replace'], $template);
                    }
                    break;

                default:
                    
$status[$id] = 'error_unknown_action';
            }
        }

        return 
$template;
    }

    
/**
     * Gets all modifications that belong to the specified add-on,
     * ordered by their modification keys.
     *
     * @param string $addOnId
     *
     * @return array Format: [modification_key] => info
     */
    
public function getModificationsByAddOnId($addOnId)
    {
        return 
$this->fetchAllKeyed("
            SELECT *
            FROM 
{$this->_modTableName}
            WHERE addon_id = ?
            ORDER BY modification_key
        "
'modification_key'$addOnId);
    }

    
/**
     * Deletes the modifications that belong to the specified add-on.
     *
     * @param string $addOnId
     */
    
public function deleteModificationsForAddOn($addOnId)
    {
        
$db $this->_getDb();
        
$db->query("
            DELETE log FROM 
{$this->_logTableName} AS log
            INNER JOIN 
{$this->_modTableName} AS modification ON
                (log.modification_id = modification.modification_id AND modification.addon_id = ?)
        "
$addOnId);
        
$db->delete($this->_modTableName'addon_id = ' $db->quote($addOnId));
    }

    
/**
     * Imports the modifications for an add-on.
     *
     * @param SimpleXMLElement $xml XML element pointing to the root of the event data
     * @param string $addOnId Add-on to import for
     */
    
public function importModificationAddOnXml(SimpleXMLElement $xml$addOnId)
    {
        
$db $this->_getDb();

        
$addonMods $this->getModificationsByAddOnId($addOnId);

        
XenForo_Db::beginTransaction($db);
        
$this->deleteModificationsForAddOn($addOnId);

        
$xmlEntries XenForo_Helper_DevelopmentXml::fixPhpBug50670($xml->modification);

        
$keys = array();
        foreach (
$xmlEntries AS $entry)
        {
            
$keys[] = (string)$entry['modification_key'];
        }

        
$modifications $this->getModificationsByKeys($keys);

        foreach (
$xmlEntries AS $modification)
        {
            
$key = (string)$modification['modification_key'];

            
$dw XenForo_DataWriter::create($this->_dataWriterName);
            if (isset(
$modifications[$key]))
            {
                
$dw->setExistingData($modifications[$key]);
            }

            if (isset(
$addonMods[$key]))
            {
                
$enabled $addonMods[$key]['enabled'];
            }
            else
            {
                
$enabled = (string)$modification['enabled'];
            }

            
$dw->setOption(XenForo_DataWriter_TemplateModificationAbstract::OPTION_FULL_TEMPLATE_COMPILEfalse);
            
$dw->setOption(XenForo_DataWriter_TemplateModificationAbstract::OPTION_REPARSE_TEMPLATEfalse);
            
$dw->bulkSet(array(
                
'addon_id' => $addOnId,
                
'template' => (string)$modification['template'],
                
'modification_key' => $key,
                
'description' => (string)$modification['description'],
                
'execution_order' => (int)$modification['execution_order'],
                
'enabled' => $enabled,
                
'action' => (string)$modification['action'],
                
'find' => XenForo_Helper_DevelopmentXml::processSimpleXmlCdata($modification->find[0]),
                
'replace' => XenForo_Helper_DevelopmentXml::processSimpleXmlCdata($modification->replace[0])
            ));
            
$this->_addExtraToAddonXmlImportDw($dw$modification);
            
$dw->save();
        }

        
XenForo_Db::commit($db);
    }

    protected function 
_addExtraToAddonXmlImportDw(XenForo_DataWriter_TemplateModificationAbstract $dwSimpleXMLElement $modification)
    {

    }

    
/**
     * Appends the add-on template modification XML to a given DOM element.
     *
     * @param DOMElement $rootNode Node to append all prefix elements to
     * @param string $addOnId Add-on ID to be exported
     */
    
public function appendModificationAddOnXml(DOMElement $rootNode$addOnId)
    {
        
$modifications $this->getModificationsByAddOnId($addOnId);

        
$document $rootNode->ownerDocument;

        foreach (
$modifications AS $modification)
        {
            
$modNode $document->createElement('modification');
            
$modNode->setAttribute('template'$modification['template']);
            
$modNode->setAttribute('modification_key'$modification['modification_key']);
            
$modNode->setAttribute('description'$modification['description']);
            
$modNode->setAttribute('execution_order'$modification['execution_order']);
            
$modNode->setAttribute('enabled'$modification['enabled']);
            
$modNode->setAttribute('action'$modification['action']);

            
$findNode $document->createElement('find');
            
$findNode->appendChild(XenForo_Helper_DevelopmentXml::createDomCdataSection($document$modification['find']));
            
$modNode->appendChild($findNode);

            
$replaceNode $document->createElement('replace');
            
$replaceNode->appendChild(XenForo_Helper_DevelopmentXml::createDomCdataSection($document$modification['replace']));
            
$modNode->appendChild($replaceNode);

            
$this->_modifyAddOnXmlNode($modNode$modification);

            
$rootNode->appendChild($modNode);
        }
    }

    protected function 
_modifyAddOnXmlNode(DOMElement &$modNode, array $modification)
    {
    }

    public function 
canEditModification(array $modification)
    {
        return 
XenForo_Application::debugMode()
            || empty(
$modification['addon_id'])
            || empty(
$modification['modification_id']);
    }
}
Онлайн: 1
Реклама