<?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 ) );
}
}