Вход Регистрация
Файл: contao-3.5.8/system/modules/core/classes/Ajax.php
Строк: 292
<?php

/**
 * Contao Open Source CMS
 *
 * Copyright (c) 2005-2016 Leo Feyer
 *
 * @license LGPL-3.0+
 */

namespace Contao;


/**
 * Provide methods to handle Ajax requests.
 *
 * @author Leo Feyer <https://github.com/leofeyer>
 */
class Ajax extends Backend
{

    
/**
     * Ajax action
     * @var string
     */
    
protected $strAction;

    
/**
     * Ajax id
     * @var string
     */
    
protected $strAjaxId;

    
/**
     * Ajax key
     * @var string
     */
    
protected $strAjaxKey;

    
/**
     * Ajax name
     * @var string
     */
    
protected $strAjaxName;


    
/**
     * Get the current action
     *
     * @param string $strAction
     *
     * @throws Exception
     */
    
public function __construct($strAction)
    {
        if (
$strAction == '')
        {
            throw new 
Exception('Missing Ajax action');
        }

        
$this->strAction = $strAction;
        
parent::__construct();
    }


    
/**
     * Ajax actions that do not require a data container object
     */
    
public function executePreActions()
    {
        switch (
$this->strAction)
        {
            
// Toggle navigation menu
            
case 'toggleNavigation':
                
$bemod = $this->Session->get('backend_modules');
                
$bemod[Input::post('id')] = intval(Input::post('state'));
                
$this->Session->set('backend_modules', $bemod);
                exit; break;

            
// Load a navigation menu group
            
case 'loadNavigation':
                
$bemod = $this->Session->get('backend_modules');
                
$bemod[Input::post('id')] = intval(Input::post('state'));
                
$this->Session->set('backend_modules', $bemod);

                
$this->import('BackendUser', 'User');

                
/** @var BackendTemplate|object $objTemplate */
                
$objTemplate = new BackendTemplate('be_navigation');
                
$navigation = $this->User->navigation();
                
$objTemplate->modules = $navigation[Input::post('id')]['modules'];

                echo 
$objTemplate->parse();
                exit; break;

            
// Toggle nodes of the file or page tree
            
case 'toggleStructure':
            case 
'toggleFileManager':
            case 
'togglePagetree':
            case 
'toggleFiletree':
                
$this->strAjaxId = preg_replace('/.*_([0-9a-zA-Z]+)$/', '$1', Input::post('id'));
                
$this->strAjaxKey = str_replace('_' . $this->strAjaxId, '', Input::post('id'));

                if (
Input::get('act') == 'editAll')
                {
                    
$this->strAjaxKey = preg_replace('/(.*)_[0-9a-zA-Z]+$/', '$1', $this->strAjaxKey);
                    
$this->strAjaxName = preg_replace('/.*_([0-9a-zA-Z]+)$/', '$1', Input::post('name'));
                }

                
$nodes = $this->Session->get($this->strAjaxKey);
                
$nodes[$this->strAjaxId] = intval(Input::post('state'));
                
$this->Session->set($this->strAjaxKey, $nodes);
                exit; break;

            
// Load nodes of the file or page tree
            
case 'loadStructure':
            case 
'loadFileManager':
            case 
'loadPagetree':
            case 
'loadFiletree':
                
$this->strAjaxId = preg_replace('/.*_([0-9a-zA-Z]+)$/', '$1', Input::post('id'));
                
$this->strAjaxKey = str_replace('_' . $this->strAjaxId, '', Input::post('id'));

                if (
Input::get('act') == 'editAll')
                {
                    
$this->strAjaxKey = preg_replace('/(.*)_[0-9a-zA-Z]+$/', '$1', $this->strAjaxKey);
                    
$this->strAjaxName = preg_replace('/.*_([0-9a-zA-Z]+)$/', '$1', Input::post('name'));
                }

                
$nodes = $this->Session->get($this->strAjaxKey);
                
$nodes[$this->strAjaxId] = intval(Input::post('state'));
                
$this->Session->set($this->strAjaxKey, $nodes);
                break;

            
// Toggle the visibility of a fieldset
            
case 'toggleFieldset':
                
$fs = $this->Session->get('fieldset_states');
                
$fs[Input::post('table')][Input::post('id')] = intval(Input::post('state'));
                
$this->Session->set('fieldset_states', $fs);
                exit; break;

            
// Check whether the temporary directory is writeable
            
case 'liveUpdate':
                
Config::set('liveUpdateId', Input::post('id'));
                
Config::persist('liveUpdateId', Input::post('id'));

                
// Check whether the temp directory is writeable
                
try
                {
                    
$objFile = new File('system/tmp/' . md5(uniqid(mt_rand(), true)));
                    
$objFile->close();
                    
$objFile->delete();
                }
                catch (
Exception $e)
                {
                    if (
$e->getCode() == 0)
                    {
                        
System::loadLanguageFile('tl_maintenance');
                        echo 
'<p class="tl_error">' . $GLOBALS['TL_LANG']['tl_maintenance']['notWriteable'] . '</p>';
                        exit; break;
                    }
                }
                exit; break;

            
// Toggle checkbox groups
            
case 'toggleCheckboxGroup':
                
$state = $this->Session->get('checkbox_groups');
                
$state[Input::post('id')] = intval(Input::post('state'));
                
$this->Session->set('checkbox_groups', $state);
                break;

            
// HOOK: pass unknown actions to callback functions
            
default:
                if (isset(
$GLOBALS['TL_HOOKS']['executePreActions']) && is_array($GLOBALS['TL_HOOKS']['executePreActions']))
                {
                    foreach (
$GLOBALS['TL_HOOKS']['executePreActions'] as $callback)
                    {
                        
$this->import($callback[0]);
                        
$this->{$callback[0]}->{$callback[1]}($this->strAction);
                    }
                }
                break;
        }
    }


    
/**
     * Ajax actions that do require a data container object
     *
     * @param DataContainer $dc
     */
    
public function executePostActions(DataContainer $dc)
    {
        
header('Content-Type: text/html; charset=' . Config::get('characterSet'));

        
// Bypass any core logic for non-core drivers (see #5957)
        
if (!$dc instanceof DC_File && !$dc instanceof DC_Folder && !$dc instanceof DC_Table)
        {
            
$this->executePostActionsHook($dc);
            exit;
        }

        switch (
$this->strAction)
        {
            
// Load nodes of the page structure tree
            
case 'loadStructure':
                echo 
$dc->ajaxTreeView($this->strAjaxId, intval(Input::post('level')));
                exit; break;

            
// Load nodes of the file manager tree
            
case 'loadFileManager':
                echo 
$dc->ajaxTreeView(Input::post('folder', true), intval(Input::post('level')));
                exit; break;

            
// Load nodes of the page tree
            
case 'loadPagetree':
                
$strField = $dc->field = Input::post('name');

                
/** @var PageSelector $strClass */
                
$strClass = $GLOBALS['BE_FFL']['pageSelector'];

                
/** @var PageSelector $objWidget */
                
$objWidget = new $strClass($strClass::getAttributesFromDca($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField], $dc->field, null, $strField, $dc->table, $dc));

                echo 
$objWidget->generateAjax($this->strAjaxId, Input::post('field'), intval(Input::post('level')));
                exit; break;

            
// Load nodes of the file tree
            
case 'loadFiletree':
                
$strField = $dc->field = Input::post('name');

                
/** @var FileSelector $strClass */
                
$strClass = $GLOBALS['BE_FFL']['fileSelector'];

                
/** @var FileSelector $objWidget */
                
$objWidget = new $strClass($strClass::getAttributesFromDca($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField], $dc->field, null, $strField, $dc->table, $dc));

                
// Load a particular node
                
if (Input::post('folder', true) != '')
                {
                    echo 
$objWidget->generateAjax(Input::post('folder', true), Input::post('field'), intval(Input::post('level')));
                }
                else
                {
                    echo 
$objWidget->generate();
                }
                exit; break;

            
// Reload the page/file picker
            
case 'reloadPagetree':
            case 
'reloadFiletree':
                
$intId = Input::get('id');
                
$strField = $dc->field = Input::post('name');

                
// Handle the keys in "edit multiple" mode
                
if (Input::get('act') == 'editAll')
                {
                    
$intId = preg_replace('/.*_([0-9a-zA-Z]+)$/', '$1', $strField);
                    
$strField = preg_replace('/(.*)_[0-9a-zA-Z]+$/', '$1', $strField);
                }

                
// The field does not exist
                
if (!isset($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField]))
                {
                    
$this->log('Field "' . $strField . '" does not exist in DCA "' . $dc->table . '"', __METHOD__, TL_ERROR);
                    
header('HTTP/1.1 400 Bad Request');
                    die(
'Bad Request');
                }

                
$objRow = null;
                
$varValue = null;

                
// Load the value
                
if ($GLOBALS['TL_DCA'][$dc->table]['config']['dataContainer'] == 'File')
                {
                    
$varValue = Config::get($strField);
                }
                elseif (
$intId > 0 && $this->Database->tableExists($dc->table))
                {
                    
$objRow = $this->Database->prepare("SELECT * FROM " . $dc->table . " WHERE id=?")
                                             ->
execute($intId);

                    
// The record does not exist
                    
if ($objRow->numRows < 1)
                    {
                        
$this->log('A record with the ID "' . $intId . '" does not exist in table "' . $dc->table . '"', __METHOD__, TL_ERROR);
                        
header('HTTP/1.1 400 Bad Request');
                        die(
'Bad Request');
                    }

                    
$varValue = $objRow->$strField;
                    
$dc->activeRecord = $objRow;
                }

                
// Call the load_callback
                
if (is_array($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField]['load_callback']))
                {
                    foreach (
$GLOBALS['TL_DCA'][$dc->table]['fields'][$strField]['load_callback'] as $callback)
                    {
                        if (
is_array($callback))
                        {
                            
$this->import($callback[0]);
                            
$varValue = $this->{$callback[0]}->{$callback[1]}($varValue, $dc);
                        }
                        elseif (
is_callable($callback))
                        {
                            
$varValue = $callback($varValue, $dc);
                        }
                    }
                }

                
// Set the new value
                
$varValue = Input::post('value', true);
                
$strKey = ($this->strAction == 'reloadPagetree') ? 'pageTree' : 'fileTree';

                
// Convert the selected values
                
if ($varValue != '')
                {
                    
$varValue = trimsplit("t", $varValue);

                    
// Automatically add resources to the DBAFS
                    
if ($strKey == 'fileTree')
                    {
                        foreach (
$varValue as $k=>$v)
                        {
                            if (
Dbafs::shouldBeSynchronized($v))
                            {
                                
$varValue[$k] = Dbafs::addResource($v)->uuid;
                            }
                        }
                    }

                    
$varValue = serialize($varValue);
                }

                
/** @var FileTree|PageTree $strClass */
                
$strClass = $GLOBALS['BE_FFL'][$strKey];

                
/** @var FileTree|PageTree $objWidget */
                
$objWidget = new $strClass($strClass::getAttributesFromDca($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField], $dc->field, $varValue, $strField, $dc->table, $dc));

                echo 
$objWidget->generate();
                exit; break;

            
// Feature/unfeature an element
            
case 'toggleFeatured':
                if (
class_exists($dc->table, false))
                {
                    
$dca = new $dc->table();

                    if (
method_exists($dca, 'toggleFeatured'))
                    {
                        
$dca->toggleFeatured(Input::post('id'), ((Input::post('state') == 1) ? true : false));
                    }
                }
                exit; break;

            
// Toggle subpalettes
            
case 'toggleSubpalette':
                
$this->import('BackendUser', 'User');

                
// Check whether the field is a selector field and allowed for regular users (thanks to Fabian Mihailowitsch) (see #4427)
                
if (!is_array($GLOBALS['TL_DCA'][$dc->table]['palettes']['__selector__']) || !in_array(Input::post('field'), $GLOBALS['TL_DCA'][$dc->table]['palettes']['__selector__']) || ($GLOBALS['TL_DCA'][$dc->table]['fields'][Input::post('field')]['exclude'] && !$this->User->hasAccess($dc->table . '::' . Input::post('field'), 'alexf')))
                {
                    
$this->log('Field "' . Input::post('field') . '" is not an allowed selector field (possible SQL injection attempt)', __METHOD__, TL_ERROR);
                    
header('HTTP/1.1 400 Bad Request');
                    die(
'Bad Request');
                }

                if (
$dc instanceof DC_Table)
                {
                    if (
Input::get('act') == 'editAll')
                    {
                        
$this->strAjaxId = preg_replace('/.*_([0-9a-zA-Z]+)$/', '$1', Input::post('id'));
                        
$this->Database->prepare("UPDATE " . $dc->table . " SET " . Input::post('field') . "='" . (intval(Input::post('state') == 1) ? 1 : '') . "' WHERE id=?")->execute($this->strAjaxId);

                        if (
Input::post('load'))
                        {
                            echo 
$dc->editAll($this->strAjaxId, Input::post('id'));
                        }
                    }
                    else
                    {
                        
$this->Database->prepare("UPDATE " . $dc->table . " SET " . Input::post('field') . "='" . (intval(Input::post('state') == 1) ? 1 : '') . "' WHERE id=?")->execute($dc->id);

                        if (
Input::post('load'))
                        {
                            echo 
$dc->edit(false, Input::post('id'));
                        }
                    }
                }
                elseif (
$dc instanceof DC_File)
                {
                    
$val = (intval(Input::post('state') == 1) ? true : false);
                    
Config::persist(Input::post('field'), $val);

                    if (
Input::post('load'))
                    {
                        
Config::set(Input::post('field'), $val);
                        echo 
$dc->edit(false, Input::post('id'));
                    }
                }
                exit; break;

            
// DropZone file upload
            
case 'fileupload':
                
$dc->move();
                exit; break;

            
// HOOK: pass unknown actions to callback functions
            
default:
                
$this->executePostActionsHook($dc);
                exit; break;
        }
    }


    
/**
     * Execute the post actions hook
     *
     * @param DataContainer $dc
     */
    
protected function executePostActionsHook(DataContainer $dc)
    {
        if (isset(
$GLOBALS['TL_HOOKS']['executePostActions']) && is_array($GLOBALS['TL_HOOKS']['executePostActions']))
        {
            foreach (
$GLOBALS['TL_HOOKS']['executePostActions'] as $callback)
            {
                
$this->import($callback[0]);
                
$this->{$callback[0]}->{$callback[1]}($this->strAction, $dc);
            }
        }
    }
}
Онлайн: 3
Реклама