Seditio Source
Root |
./othercms/ips_4.3.4/applications/core/modules/front/system/widgets.php
<?php
/**
 * @brief        Sidebar Widgets
 * @author        <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
 * @copyright    (c) Invision Power Services, Inc.
 * @license        https://www.invisioncommunity.com/legal/standards/
 * @package        Invision Community
 * @since        19 Nov 2013
 */

namespace IPS\core\modules\front\system;

/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
   
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
    exit;
}

/**
 * Sidebar Widgets
 */
class _widgets extends \IPS\Dispatcher\Controller
{
   
/**
     * Execute
     *
     * @return    void
     */
   
public function execute()
    {
       
/* Check Permissions */
       
if ( ! \IPS\Member::loggedIn()->modPermission('can_manage_sidebar') )
        {
            \
IPS\Output::i()->error( 'no_permission_manage_sidebar', '3S172/1', 403, '' );
        }
       
       
parent::execute();
    }
   
   
/**
     * Build The Block List For Front End
     *
     * @return    void
     */
   
protected function getBlockList()
    {
       
$availableBlocks = array();
       
        foreach ( \
IPS\Db::i()->select( "*", 'core_widgets' ) as $widget )
        {
            try
            {
               
$appOrPlugin = isset( $widget['plugin'] ) ? \IPS\Plugin::load( $widget['plugin'] ) : \IPS\Application::load( $widget['app'] );

                if ( isset(
$widget['plugin'] ) )
                {
                    if ( !
$appOrPlugin->enabled )
                    {
                        continue;
                    }
                }
                else
                {
                    if ( !\
IPS\Application::appIsEnabled( $appOrPlugin->directory ) or !\IPS\Application::load( $appOrPlugin->directory )->canAccess() )
                    {
                        continue;
                    }
                }

               
$block = \IPS\Widget::load( $appOrPlugin, $widget['key'], mt_rand(), array(), $widget['restrict'], null );
               
$block->allowReuse = (boolean) $widget['allow_reuse'];
               
$block->menuStyle  = $widget['menu_style'];
               
                if ( !
$block->isExecutableByApp( array( \IPS\Request::i()->pageApp, 'sidebar' ) ) )
                {
                    throw new \
OutOfRangeException;
                }
            }
            catch( \
Exception $e )
            {
                continue;
            }
           
            if( isset(
$widget['app'] ) )
            {
               
$availableBlocks['apps'][ $widget['app'] ][] = $block;
            }
            else
            {
               
$availableBlocks['plugin'][ $widget['plugin'] ][] = $block;
            }
        }

        \
IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'widgets' )->blockList( $availableBlocks );
    }
   
   
/**
     * Get Output For Adding A New Block
     *
     * @return    void
     */
   
protected function getBlock()
    {        
       
$key = $block = explode( "_", \IPS\Request::i()->blockID );

        if ( isset( \
IPS\Request::i()->pageApp ) )
        {
            try
            {
                foreach (
json_decode( \IPS\Db::i()->select( 'widgets', 'core_widget_areas', array( 'app=? AND module=? AND controller=? AND area=?', \IPS\Request::i()->pageApp, \IPS\Request::i()->pageModule, \IPS\Request::i()->pageController, \IPS\Request::i()->pageArea ) )->first(), TRUE ) as $k => $block )
                {
                    switch(
$key[0] )
                    {
                        case
'app':

                            if( ( isset(
$block['app'] ) and $block['app'] == $key[1] ) AND $block['key'] == $key[2] AND $block['unique'] == $key[3] )
                            {
                               
$widget = \IPS\Widget::load( \IPS\Application::load( $block['app'] ), $block['key'], $block['unique'], $block['configuration'], null, \IPS\Request::i()->orientation );
                                break
2;
                            }
                            break;
                       
                        case
'plugin':
                            if( ( isset(
$block['plugin'] ) and $block['plugin'] == $key[1] ) AND $block['key'] == $key[2] AND $block['unique'] == $key[3] )
                            {
                               
$widget = \IPS\Widget::load( \IPS\Plugin::load( $block['plugin'] ), $block['key'], $block['unique'], $block['configuration'], null, \IPS\Request::i()->orientation );
                                break
2;
                            }
                            break;
                    }
                }
            }
            catch ( \
OutOfRangeException $e ) { }
            catch ( \
UnderflowException $e ) { }
        }
       
        if ( !isset(
$widget ) )
        {
            try
            {
               
$widget = \IPS\Widget::load( ( $key[0] == 'plugin' ) ? \IPS\Plugin::load( $key[1] ) : \IPS\Application::load( $key[1] ), $key[2], $key[3], array(), null, \IPS\Request::i()->orientation );
            }
            catch( \
OutOfRangeException $e )
            {
               
$widget = '';
            }
        }

        \
IPS\Output::i()->sendOutput( (string) $widget );
    }
   
   
/**
     * Get Configuration
     *
     * @return    void
     */
   
protected function getConfiguration()
    {
       
$key    = explode( "_", \IPS\Request::i()->block );
       
$blocks    = array();

        try
        {
           
$where = ( $key[0] ) == 'app' ? '`key`=? AND `app`=?' : '`key`=? AND `plugin`=?';
           
$widgetMaster = \IPS\Db::i()->select( '*', 'core_widgets', array( $where, $key[2], $key[1] ) )->first();

           
$blocks = \IPS\Db::i()->select( '*', 'core_widget_areas', array( 'app=? AND module=? AND controller=? AND area=?', \IPS\Request::i()->pageApp, \IPS\Request::i()->pageModule, \IPS\Request::i()->pageController, \IPS\Request::i()->pageArea ) )->first();
           
$blocks    = json_decode( $blocks['widgets'], TRUE );
        }
        catch ( \
UnderflowException $e )
        {
            switch(
$key[0] )
            {
                case
'app':
                   
$blocks = array( array( 'app' => $key[1], 'key' => $key[2], 'unique' => $key[3], 'configuration' => array() ) );
                    break;
                       
                case
'plugin':
                   
$blocks = array( array( 'plugin' => $key[1], 'key' => $key[2], 'unique' => $key[3], 'configuration' => array() ) );
                    break;
            }
        }
       
       
$widget    = NULL;

        if( !empty(
$blocks ) )
        {
            foreach (
$blocks as $k => $block )
            {
                switch(
$key[0] )
                {
                    case
'app':
                        if( ( isset(
$block['app'] ) AND $block['app'] == $key[1] ) AND $block['key'] == $key[2] AND $block['unique'] == $key[3] )
                        {
                           
$widget = \IPS\Widget::load( \IPS\Application::load( $block['app'] ), $block['key'], $block['unique'], $block['configuration'] );
                        }
                        break;
                   
                    case
'plugin':
                        if( ( isset(
$block['plugin'] ) AND $block['plugin'] == $key[1] ) AND $block['key'] == $key[2] AND $block['unique'] == $key[3] )
                        {
                           
$widget = \IPS\Widget::load( \IPS\Plugin::load( $block['plugin'] ), $block['key'], $block['unique'], $block['configuration'] );
                        }
                        break;
                }

                if(
$widget !== NULL AND method_exists( $widget, 'configuration' ) )
                {
                    if ( \
IPS\Request::i()->isAjax() )
                    {
                        \
IPS\Output::i()->jsFiles = array();
                    }
                   
                   
$widget->menuStyle = $widgetMaster['menu_style'];
                   
$form = new \IPS\Helpers\Form( 'form', 'saveSettings' );
                    if (
$widget->configuration( $form ) !== NULL )
                    {
                        if (
$values = $form->values() )
                        {
                            if (
method_exists( $widget, 'preConfig' ) )
                            {
                               
$values = $widget->preConfig( $values );
                            }
                           
                           
$blocks[ $k ]['configuration'] = $values;
                            \
IPS\Db::i()->insert( 'core_widget_areas', array( 'app' => \IPS\Request::i()->pageApp, 'module' => \IPS\Request::i()->pageModule, 'controller' => \IPS\Request::i()->pageController, 'area' => \IPS\Request::i()->pageArea, 'widgets' => json_encode( $blocks ) ), TRUE );
                            \
IPS\Widget::deleteCaches( $block['key'], ( isset( $block['app'] ) ) ? $block['app'] : NULL, ( isset( $block['plugin'] ) ) ? $block['plugin'] : NULL );
                            \
IPS\Output::i()->json( 'OK' );
                        }
                        \
IPS\Output::i()->output = $widget->configuration()->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'widgets', 'core' ) ), 'formTemplate' ), $widget );
                    }
                }
            }
        }
    }
   
   
/**
     * Reorder Blocks
     *
     * @return    void
     */
   
protected function saveOrder()
    {
        if( !
in_array( \IPS\Request::i()->area, array( 'sidebar', 'header', 'footer' ) ) )
        {
            \
IPS\Output::i()->error( 'invalid_widget_area', '3S172/2', 403, '' );
        }

        \
IPS\Session::i()->csrfCheck();
       
       
$newOrder = array();
       
$seen     = array();
       
        try
        {
           
$currentConfig = \IPS\Db::i()->select( '*', 'core_widget_areas', array( 'app=? AND module=? AND controller=? AND area=?', \IPS\Request::i()->pageApp, \IPS\Request::i()->pageModule, \IPS\Request::i()->pageController, \IPS\Request::i()->area ) )->first();
           
$widgets = json_decode( $currentConfig['widgets'], TRUE );
        }
        catch ( \
UnderflowException $e )
        {
           
$widgets = array();
        }
   
       
/* Loop over the new order and merge in current blocks so we don't lose config */
       
if ( isset ( \IPS\Request::i()->order ) )
        {
            foreach ( \
IPS\Request::i()->order as $block )
            {
               
$block = explode( "_", $block );
               
               
$added = FALSE;
                foreach(
$widgets as $widget )
                {
                    if (
$widget['key'] == $block[2] AND $widget['unique'] == $block[3] )
                    {
                       
$seen[]     = $widget['unique'];
                       
$newOrder[] = $widget;
                       
$added = TRUE;
                        break;
                    }
                }
                if( !
$added )
                {
                   
$newBlock = array();
                   
                    if (
$block[0] == 'app' )
                    {
                       
$newBlock['app'] = $block[1];
                    }
                    else
                    {
                       
$newBlock['plugin'] = $block[1];
                    }
                   
                   
$newBlock['key']         = $block[2];
                   
$newBlock['unique']        = $block[3];
                   
$newBlock['configuration']    = array();
                   
                   
/* Make sure this widget doesn't have configuration in another area */
                   
$newBlock['configuration'] = \IPS\Widget::getConfiguration( $newBlock['unique'] );

                   
$seen[]     = $block[3];
                   
$newOrder[] = $newBlock;
                }
            }
        }

       
/* Anything to update? */
       
if ( count( $widgets ) > count( $newOrder ) )
        {
           
/* No items left in area, or one has been removed */
           
foreach( $widgets as $widget )
            {
               
/* If we haven't seen this widget, it's been removed, so add to trash */
               
if ( ! in_array( $widget['unique'], $seen ) )
                {
                    \
IPS\Widget::trash( $widget['unique'], $widget );
                }
            }
        }

       
/* Expire Caches so up to date information displays */
       
\IPS\Widget::deleteCaches();

       
/* Save to database */
       
\IPS\Db::i()->replace( 'core_widget_areas', array( 'app' => \IPS\Request::i()->pageApp, 'module' => \IPS\Request::i()->pageModule, 'controller' => \IPS\Request::i()->pageController, 'widgets' => json_encode( $newOrder ), 'area' => \IPS\Request::i()->area ) );
    }
}