Invision Power Services, Inc. * @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 ) ); } }