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

/**
 * Model for admin templates.
 *
 * @package XenForo_AdminTemplates
 */
class XenForo_Model_AdminTemplate extends XenForo_Model
{
    
/**
     * Returns all admin template basic info in alphabetical order
     *
     * @return array Format: [title] => basic info
     */
    
public function getAllAdminTemplateTitles()
    {
        return 
$this->getAdminTemplateTitles();
    }

    
/**
     * Returns all admin template basic info for templates that match the conditions and fetch options
     *
     * @param array $conditions
     * @param array $fetchOptions
     *
     * @return array Format: [title] => basic info
     */
    
public function getAdminTemplateTitles(array $conditions = array(), array $fetchOptions = array())
    {
        
$whereClause $this->prepareTemplateConditions($conditions$fetchOptions);
        
$limitOptions $this->prepareLimitFetchOptions($fetchOptions);

        return 
$this->fetchAllKeyed($this->limitQueryResults('
            SELECT template.template_id, template.title,
                addon.addon_id, addon.title AS addonTitle
            FROM xf_admin_template AS template
                LEFT JOIN xf_addon AS addon ON (addon.addon_id = template.addon_id)
            WHERE ' 
$whereClause '
            ORDER BY CONVERT(template.title USING utf8)
        '
$limitOptions['limit'], $limitOptions['offset']), 'title');
    }

    
/**
     * Prepares SQL WHERE conditions for a SELECT query
     *
     * @param array $conditions
     * @param array $fetchOptions
     *
     * @return string
     */
    
public function prepareTemplateConditions(array $conditions, array &$fetchOptions)
    {
        
$db $this->_getDb();
        
$sqlConditions = array();

        if (!empty(
$conditions['title']))
        {
            if (
is_array($conditions['title']))
            {
                
$sqlConditions[] = 'CONVERT(template.title USING utf8) LIKE ' XenForo_Db::quoteLike($conditions['title'][0], $conditions['title'][1], $db);
            }
            else
            {
                
$sqlConditions[] = 'CONVERT(template.title USING utf8) LIKE ' XenForo_Db::quoteLike($conditions['title'], 'lr'$db);
            }
        }

        if (!empty(
$conditions['template']))
        {
            
$caseSensitive = (empty($conditions['template_case_sensitive']) ? '' 'BINARY ');

            if (
is_array($conditions['template']))
            {
                
$sqlConditions[] = 'template.template LIKE ' $caseSensitive XenForo_Db::quoteLike($conditions['template'][0], $conditions['phrase_text'][1], $db);
            }
            else
            {
                
$sqlConditions[] = 'template.template LIKE ' $caseSensitive XenForo_Db::quoteLike($conditions['template'], 'lr'$db);
            }
        }

        return 
$this->getConditionsForClause($sqlConditions);
    }

    
/**
     * Returns all admin templates in alphabetical title order
     *
     * @return array Format: [title] => (array) template
     */
    
public function getAllAdminTemplates()
    {
        return 
$this->fetchAllKeyed('
            SELECT *
            FROM xf_admin_template
            ORDER BY CONVERT(title USING utf8)
        '
'title');
    }

    
/**
     * Returns all admin templates that include the specified admin template
     *
     * @param integer $templateId
     *
     * @return array Format: [] => (array) template
     */
    
public function getDependentAdminTemplates($templateId)
    {
        return 
$this->_getDb()->fetchAll('
            SELECT admin_template.*
            FROM xf_admin_template AS admin_template
            INNER JOIN xf_admin_template_include AS include ON
                (admin_template.template_id = include.source_id)
            WHERE include.target_id = ?
        '
$templateId);
    }

    
/**
     * Gets the template IDs of any templates that include the source
     * IDs. For example, this would pass in the ID of header
     * and get the ID of the PAGE_CONTAINER.
     *
     * @param integer|array $templateIds One ID as a scalar or an array of many.
     *
     * @return array Array of IDs
     */
    
public function getIncludingTemplateIds($templateIds)
    {
        if (!
is_array($templateIds))
        {
            
$templateIds = array($templateIds);
        }

        if (!
$templateIds)
        {
            return array();
        }

        
$db $this->_getDb();

        return 
$db->fetchCol('
            SELECT source_id
            FROM xf_admin_template_include
            WHERE target_id IN (' 
$db->quote($templateIds) . ')
        '
);
    }

    
/**
     * Returns the admin template specified by template_id
     *
     * @param integer Template id
     * @return array Template
     */
    
public function getAdminTemplateById($template_id)
    {
        return 
$this->_getDb()->fetchRow('
            SELECT *
            FROM xf_admin_template
            WHERE template_id = ?
        '
$template_id);
    }

    
/**
     * Returns the admin template specified by its title
     *
     * @param string Template title
     *
     * @return array Template
     */
    
public function getAdminTemplateByTitle($title)
    {
        return 
$this->_getDb()->fetchRow('
            SELECT *
            FROM xf_admin_template
            WHERE title = ?
        '
$title);
    }

    public function 
getAdminTemplatesLikeTitle($title$likeType 'lr'$limit 0)
    {
        return 
$this->fetchAllKeyed($this->limitQueryResults('
            SELECT *
            FROM xf_admin_template
            WHERE CONVERT(title USING utf8) LIKE ' 
XenForo_Db::quoteLike($title$likeType) . '
            ORDER BY CONVERT(title USING utf8)
        '
$limit), 'title');
    }

    
/**
     * Returns all the admin templates specified by the array of titles provided
     *
     * @param array $titles
     *
     * @return array Templates
     */
    
public function getAdminTemplatesByTitles(array $titles)
    {
        if (empty(
$titles))
        {
            return array();
        }

        return 
$this->fetchAllKeyed('
            SELECT *
            FROM xf_admin_template
            WHERE title IN(' 
$this->_getDb()->quote($titles) . ')
            ORDER BY CONVERT(title USING utf8)
        '
'title');
    }

    
/**
     * Returns all the admin templates specified by the array of IDs provided
     *
     * @param array $ids
     *
     * @return array Templates
     */
    
public function getAdminTemplatesByIds(array $ids)
    {
        if (empty(
$ids))
        {
            return array();
        }

        return 
$this->fetchAllKeyed('
            SELECT *
            FROM xf_admin_template
            WHERE template_id IN (' 
$this->_getDb()->quote($ids) . ')
            ORDER BY CONVERT(title USING utf8)
        '
'template_id');
    }

    
/**
     * Returns all the admin templates that belong to the specified add-on
     *
     * @param string $addOnId
     *
     * @return array Format: [title] => info
     */
    
public function getAdminTemplatesByAddOn($addOnId)
    {
        return 
$this->fetchAllKeyed('
            SELECT *
            FROM xf_admin_template
            WHERE addon_id = ?
            ORDER BY CONVERT(title USING utf8)
        '
'title'$addOnId);
    }

    
/**
     * Gets information on all admin templates that include the named phrase.
     *
     * @param string $phraseTitle
     *
     * @return array Format: [template id] => admin template info
     */
    
public function getAdminTemplatesThatIncludePhrase($phraseTitle)
    {
        return 
$this->fetchAllKeyed('
            SELECT admin_template.*
            FROM xf_admin_template_phrase AS template_phrase
            INNER JOIN xf_admin_template AS admin_template ON
                (admin_template.template_id = template_phrase.template_id)
            WHERE template_phrase.phrase_title = ?
        '
'template_id'$phraseTitle);
    }

    
/**
     * Gets all template ID and title pairs that belong to the specified add-on.
     *
     * @param string $addOnId
     *
     * @return array Format: [template id] => title
     */
    
public function getAdminTemplateTitlesByAddOn($addOnId)
    {
        return 
$this->_getDb()->fetchPairs('
            SELECT template_id, title
            FROM xf_admin_template
            WHERE addon_id = ?
        '
$addOnId);
    }

    
/**
     * Get admin templates whose names contain the search text
     *
     * @param string $searchText
     *
     * @return array
     */
    
public function getAdminTemplatesForAdminQuickSearch($searchText)
    {
        return 
$this->fetchAllKeyed('
            SELECT template_id, title, addon_id
            FROM xf_admin_template
            WHERE CONVERT(title USING utf8) LIKE ' 
XenForo_Db::quoteLike($searchText'lr') . '
        '
'template_id');
    }

    
/**
     * Returns the path to the admin template development directory, if it has been configured and exists
     *
     * @return string Path to admin template directory
     */
    
public function getAdminTemplateDevelopmentDirectory()
    {
        
$config XenForo_Application::get('config');
        if (!
$config->debug || !$config->development->directory)
        {
            return 
'';
        }

        return 
XenForo_Application::getInstance()->getRootDir()
            . 
'/' $config->development->directory '/file_output/admin_templates';
    }

    
/**
     * Checks that the admin templates directory has been configured and exists
     *
     * @return boolean
     */
    
public function canImportAdminTemplatesFromDevelopment()
    {
        
$dir $this->getAdminTemplateDevelopmentDirectory();
        return (
$dir && is_dir($dir));
    }

    
/**
     * Deletes the admin templates that belong to the specified add-on.
     *
     * @param string $addOnId
     */
    
public function deleteAdminTemplatesForAddOn($addOnId)
    {
        
$templateTitles $this->getAdminTemplateTitlesByAddOn($addOnId);
        
$templateIds array_keys($templateTitles);

        if (
$templateTitles)
        {
            
$db $this->_getDb();
            
$quotedIds $db->quote($templateIds);

            
$db->delete('xf_admin_template'"template_id IN ($quotedIds)");
            
$db->delete('xf_admin_template_compiled''title IN (' $db->quote($templateTitles) . ')');
            
$db->delete('xf_admin_template_include'"source_id IN ($quotedIds)");
            
$db->delete('xf_admin_template_phrase'"template_id IN ($quotedIds)");
            
$db->delete('xf_admin_template_modification_log'"template_id IN ($quotedIds)");
        }

        
XenForo_Template_Compiler_Admin::resetTemplateCache();
    }

    
/**
     * Imports all admin templates from the admin templates directory into the database
     */
    
public function importAdminTemplatesFromDevelopment()
    {
        
$db $this->_getDb();

        
$templateDir $this->getAdminTemplateDevelopmentDirectory();
        if (!
$templateDir && !is_dir($templateDir))
        {
            throw new 
XenForo_Exception("Admin template development directory not enabled or doesn't exist");
        }

        
$files glob("$templateDir/*.html");
        if (!
$files)
        {
            throw new 
XenForo_Exception("Admin template development directory does not have any templates");
        }

        
XenForo_Db::beginTransaction($db);
        
$this->deleteAdminTemplatesForAddOn('XenForo');

        
$titles = array();
        foreach (
$files AS $templateFile)
        {
            
$filename basename($templateFile);
            if (
preg_match('/^(.+).html$/'$filename$match))
            {
                
$titles[] = $match[1];
            }
        }

        
$existingTemplates $this->getAdminTemplatesByTitles($titles);

        foreach (
$files AS $templateFile)
        {
            if (!
is_readable($templateFile))
            {
                throw new 
XenForo_Exception("Template file '$templateFile' not readable");
            }

            
$filename basename($templateFile);
            if (
preg_match('/^(.+).html$/'$filename$match))
            {
                
$templateName $match[1];
                
$data file_get_contents($templateFile);

                
$dw XenForo_DataWriter::create('XenForo_DataWriter_AdminTemplate');
                if (isset(
$existingTemplates[$templateName]))
                {
                    
$dw->setExistingData($existingTemplates[$templateName], true);
                }
                
$dw->setOption(XenForo_DataWriter_AdminTemplate::OPTION_DEV_OUTPUT_DIR'');
                
$dw->setOption(XenForo_DataWriter_AdminTemplate::OPTION_FULL_COMPILEfalse);
                
$dw->setOption(XenForo_DataWriter_AdminTemplate::OPTION_TEST_COMPILEfalse);
                
$dw->set('title'$templateName);
                
$dw->set('template'$data);
                
$dw->set('addon_id''XenForo');

                try
                {
                    
$dw->save();
                }
                catch (
Exception $e)
                {
                    throw new 
XenForo_Exception("Template '$templateName' not imported." "n" $e->getMessage() . "n" $e->getTraceAsString());
                }
            }
        }

        
$this->compileAllParsedAdminTemplates();

        
XenForo_Db::commit($db);
    }

    
/**
     * Imports the add-on admin templates XML.
     *
     * @param SimpleXMLElement $xml XML element pointing to the root of the data
     * @param string $addOnId Add-on to import for
     * @param integer $maxExecution Maximum run time in seconds
     * @param integer $offset Number of elements to skip
     *
     * @return boolean|integer True on completion; false if the XML isn't correct; integer otherwise with new offset value
     */
    
public function importAdminTemplatesAddOnXml(SimpleXMLElement $xml$addOnId$maxExecution 0$offset 0)
    {
        
$db $this->_getDb();

        
XenForo_Db::beginTransaction($db);

        
$startTime microtime(true);

        if (
$offset == 0)
        {
            
$this->deleteAdminTemplatesForAddOn($addOnId);
        }

        
$templates XenForo_Helper_DevelopmentXml::fixPhpBug50670($xml->template);

        
$titles = array();
        
$current 0;
        foreach (
$templates AS $template)
        {
            
$current++;
            if (
$current <= $offset)
            {
                continue;
            }
            
$titles[] = (string)$template['title'];
        }

        
$existingTemplates $this->getAdminTemplatesByTitles($titles);

        
$current 0;
        
$restartOffset false;
        foreach (
$templates AS $template)
        {
            
$current++;
            if (
$current <= $offset)
            {
                continue;
            }

            
$templateName = (string)$template['title'];

            
$dw XenForo_DataWriter::create('XenForo_DataWriter_AdminTemplate');
            if (isset(
$existingTemplates[$templateName]))
            {
                
$dw->setExistingData($existingTemplates[$templateName], true);
            }
            
$dw->setOption(XenForo_DataWriter_AdminTemplate::OPTION_DEV_OUTPUT_DIR'');
            
$dw->setOption(XenForo_DataWriter_AdminTemplate::OPTION_FULL_COMPILEfalse);
            
$dw->setOption(XenForo_DataWriter_AdminTemplate::OPTION_TEST_COMPILEfalse);
            
$dw->set('title'$templateName);
            
$dw->set('template'XenForo_Helper_DevelopmentXml::processSimpleXmlCdata($template));
            
$dw->set('addon_id'$addOnId);
            
$dw->save();

            if (
$maxExecution && (microtime(true) - $startTime) > $maxExecution)
            {
                
$restartOffset $current;
                break;
            }
        }

        
XenForo_Db::commit($db);

        return (
$restartOffset $restartOffset true);
    }

    
/**
     * Appends the add-on admin template XML to a given DOM element.
     *
     * @param DOMElement $rootNode Node to append all elements to
     * @param string $addOnId Add-on ID to be exported
     */
    
public function appendAdminTemplatesAddOnXml(DOMElement $rootNode$addOnId)
    {
        
$document $rootNode->ownerDocument;

        
$templates $this->getAdminTemplatesByAddOn($addOnId);
        foreach (
$templates AS $template)
        {
            
$templateNode $document->createElement('template');
            
$templateNode->setAttribute('title'$template['title']);
            
$templateNode->appendChild(XenForo_Helper_DevelopmentXml::createDomCdataSection($document$template['template']));

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

    
/**
     * Gets the admin templates development XML.
     *
     * @return DOMDocument
     */
    
public function getAdminTemplatesDevelopmentXml()
    {
        
$document = new DOMDocument('1.0''utf-8');
        
$document->formatOutput true;
        
$rootNode $document->createElement('admin_templates');
        
$document->appendChild($rootNode);

        
$this->appendAdminTemplatesAddOnXml($rootNode'XenForo');

        return 
$document;
    }

    
/**
     * Updates the last modified date of the admin style.
     */
    
public function updateAdminStyleLastModifiedDate()
    {
        
// make sure when updating, the time is reflected as late as possible
        
$this->_getDataRegistryModel()->set('adminStyleModifiedDate'time());
    }

    public function 
getIdsToCompileByTemplateIds(array $templateIds)
    {
        
$templateIds array_merge($templateIds$this->getIncludingTemplateIds($templateIds));

        return 
array_unique($templateIds);
    }

    public function 
reparseTemplate($templateId$fullCompile true)
    {
        
$dw XenForo_DataWriter::create('XenForo_DataWriter_AdminTemplate'XenForo_DataWriter::ERROR_SILENT);
        
$dw->setExistingData($templateId);
        
$dw->reparseTemplate();
        
$dw->setOption(XenForo_DataWriter_AdminTemplate::OPTION_FULL_COMPILE$fullCompile);
        
$dw->save();
        return 
$dw;
    }

    
/**
     * Reparses all admin templates
     *
     * @param integer $maxExecution The approx maximum length of time this function will run for
     * @param integer $startTemplate The number of the template to start with in that style (not ID, just counter)
     *
     * @return boolean|int True if completed successfully, otherwise int of restart template counter
     */
    
public function reparseAllAdminTemplates($maxExecution 0$startTemplate 0)
    {
        
$db $this->_getDb();

        
$startTime microtime(true);
        
$complete true;
        
$lastTemplate 0;

        
XenForo_Db::beginTransaction($db);

        
$templates $this->getAllAdminTemplates();

        foreach (
$templates AS $template)
        {
            
$lastTemplate++;
            if (
$lastTemplate $startTemplate)
            {
                continue;
            }

            
$this->reparseTemplate($templatefalse)->getMergedData();

            if (
$maxExecution && (microtime(true) - $startTime) > $maxExecution)
            {
                
$complete false;
                break;
            }
        }

        
XenForo_Db::commit($db);

        if (
$complete)
        {
            return 
true;
        }
        else
        {
            return 
$lastTemplate 1;
        }
    }

    
/**
     * Compiles all admin templates
     *
     * @param integer $maxExecution The approx maximum length of time this function will run for
     * @param integer $startTemplate The number of the template to start with in that style (not ID, just counter)
     * @param array $priority List of templates that have priority to be compiled on the first run (eg, cache rebuild and page container)
     *
     * @return boolean|int True if completed successfully, otherwise int of restart template counter
     */
    
public function compileAllParsedAdminTemplates($maxExecution 0$startTemplate 0, array $priority = array())
    {
        
$db $this->_getDb();

        
$startTime microtime(true);
        
$complete true;
        
$lastTemplate 0;

        
XenForo_Db::beginTransaction($db);

        
$templates $this->getAllAdminTemplates();

        if (
$startTemplate == 0)
        {
            foreach (
$priority AS $priorityTemplate)
            {
                if (isset(
$templates[$priorityTemplate]))
                {
                    
$template $templates[$priorityTemplate];
                    
$template $this->reparseTemplate($templatefalse)->getMergedData();
                    
$this->compileParsedAdminTemplate(
                        
$template['template_id'], unserialize($template['template_parsed']), $template['title']
                    );
                }
            }
        }

        foreach (
$templates AS $template)
        {
            
$lastTemplate++;
            if (
$lastTemplate $startTemplate)
            {
                continue;
            }

            
$this->compileParsedAdminTemplate(
                
$template['template_id'], unserialize($template['template_parsed']), $template['title']
            );

            if (
$maxExecution && (microtime(true) - $startTime) > $maxExecution)
            {
                
$complete false;
                break;
            }
        }

        if (
$complete)
        {
            
$compiledRemove $db->fetchAll("
                SELECT DISTINCT c.title
                FROM xf_admin_template_compiled AS c
                LEFT JOIN xf_admin_template AS m ON (c.title = m.title)
                WHERE m.title IS NULL
            "
);
            foreach (
$compiledRemove AS $remove)
            {
                
$db->delete('xf_admin_template_compiled',
                    
"title = " $db->quote($remove['title'])
                );
            }

            
$this->updateAdminStyleLastModifiedDate();
        }

        
XenForo_Db::commit($db);

        if (
$complete)
        {
            return 
true;
        }
        else
        {
            return 
$lastTemplate 1;
        }
    }

    
/**
     * Compiles the specified, pre-parsed admin templates.
     *
     * @param array $templates
     */
    
public function compileParsedAdminTemplates(array $templates)
    {
        if (!
$templates)
        {
            return;
        }

        
$db $this->_getDb();
        
XenForo_Db::beginTransaction($db);

        foreach (
$templates AS $template)
        {
            
$this->compileParsedAdminTemplate(
                
$template['template_id'], unserialize($template['template_parsed']), $template['title']
            );
        }

        
XenForo_Db::commit($db);
    }

    
/**
     * Compiles any admin templates that include the specified phrase title.
     *
     * @param string $phraseTitle
     * @param boolean $deferred
     */
    
public function compileAdminTemplatesThatIncludePhrase($phraseTitle$deferred true)
    {
        
$templates $this->getAdminTemplatesThatIncludePhrase($phraseTitle);
        if (
$deferred)
        {
            
XenForo_Application::defer('AdminTemplatePartialCompile', array(
                
'recompileTemplateIds' => array_keys($templates)
            ), 
nulltrue);
        }
        else
        {
            
$this->compileParsedAdminTemplates($templates);
        }
    }

    
/**
     * Compiles a single admin template
     *
     * @param array Template
     */
    
public function compileParsedAdminTemplate($templateId, array $parsedTemplate$title)
    {
        
$isCss = (substr($title, -4) == '.css');

        
$languages $this->getModelFromCache('XenForo_Model_Language')->getAllLanguages();
        
$db $this->_getDb();

        
$compiler = new XenForo_Template_Compiler_Admin('');

        if (
$isCss)
        {
            
$compiledTemplate $compiler->compileParsed($parsedTemplate$title00);
            
$db->query('
                INSERT INTO xf_admin_template_compiled
                    (language_id, title, template_compiled)
                VALUES
                    (?, ?, ?)
                ON DUPLICATE KEY UPDATE template_compiled = VALUES(template_compiled)
            '
, array(0$title$compiledTemplate));
        }
        else
        {
            foreach (
$languages AS $language)
            {
                
$compiledTemplate $compiler->compileParsed($parsedTemplate$title0$language['language_id']);
                
$db->query('
                    INSERT INTO xf_admin_template_compiled
                        (language_id, title, template_compiled)
                    VALUES
                        (?, ?, ?)
                    ON DUPLICATE KEY UPDATE template_compiled = VALUES(template_compiled)
                '
, array($language['language_id'], $title$compiledTemplate));
            }
        }

        
$ins = array();
        foreach (
$compiler->getIncludedTemplates() AS $includedId)
        {
            
$ins[] = '(' $db->quote($templateId) . ', ' $db->quote($includedId) . ')';
            
//TODO: this system doesn't handle includes for templates that don't exist yet
        
}
        
$db->delete('xf_admin_template_include''source_id = ' $db->quote($templateId));
        if (
$ins)
        {
            
$db->query("
                INSERT IGNORE INTO xf_admin_template_include
                    (source_id, target_id)
                VALUES
                    " 
implode(','$ins)
            );
        }

        
$ins = array();
        foreach (
$compiler->getIncludedPhrases() AS $includedPhrase)
        {
            if (
strlen($includedPhrase) > 75)
            {
                continue; 
// too long, can't be a valid phrase
            
}

            
$ins[] = '(' $db->quote($templateId) . ', ' $db->quote($includedPhrase) . ')';
        }
        
$db->delete('xf_admin_template_phrase''template_id = ' $db->quote($templateId));
        if (
$ins)
        {
            
$db->query('
                INSERT IGNORE INTO xf_admin_template_phrase
                    (template_id, phrase_title)
                VALUES
                    ' 
implode(','$ins)
            );
        }
    }
}
Онлайн: 1
Реклама