Invision Power Services, Inc. * @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc. * @license http://www.invisionpower.com/legal/standards/ * @package IPS Social Suite * @subpackage Core * @since 30 Jun 2015 * @version SVN_VERSION_NUMBER */ namespace IPS\core; /* 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; } /** * Front Navigation Extension: Custom Item */ class _FrontNavigation { /** * @brief Singleton Instances * @note This needs to be declared in any child classes as well, only declaring here for editor code-complete/error-check functionality */ protected static $instance = NULL; /** * Get instance * * @return static */ public static function i() { if( static::$instance === NULL ) { $classname = get_called_class(); static::$instance = new $classname; } return static::$instance; } /** * Get data store * * @param bool $noStore If true, will skip datastore and get from DB (used for ACP preview) * @return array */ public static function frontNavigation( $noStore=FALSE ) { if ( $noStore or !isset( \IPS\Data\Store::i()->frontNavigation ) ) { $frontNavigation = array( 0 => array(), 1 => array() ); $select = \IPS\Db::i()->select( '*', 'core_menu', NULL, 'position' ); if ( count( $select ) ) { foreach ( $select as $item ) { if ( \IPS\Application::appIsEnabled( $item['app'] ) ) { $frontNavigation[ intval( $item['parent'] ) ][ $item['id'] ] = $item; } } } elseif ( !$noStore ) { static::buildDefaultFrontNavigation(); return static::frontNavigation(); } if ( $noStore ) { return $frontNavigation; } \IPS\Data\Store::i()->frontNavigation = $frontNavigation; } return \IPS\Data\Store::i()->frontNavigation; } /** * Delete front navigation items by application * * @param \IPS\Application $app Application deleted * @return void */ public static function deleteByApplication( \IPS\Application $app ) { foreach( \IPS\Db::i()->select( '*', 'core_menu', array( array( 'extension=?', 'CustomItem' ) ) ) as $row ) { $config = json_decode( $row['config'], TRUE ); if ( isset( $config['menu_custom_item_url'] ) and $config['menu_custom_item_url'] and isset( $config['internal'] ) and $config['internal'] ) { try { $data = \IPS\Http\Url::internal( $config['menu_custom_item_url'], NULL, $config['internal'] )->getFriendlyUrlData(); if ( ! empty( $data['app'] ) and $data['app'] === $app->directory ) { \IPS\Db::i()->delete( 'core_menu', array( 'id=?', $row['id'] ) ); } } catch( \Exception $e ) { } } } \IPS\Db::i()->delete( 'core_menu', array( 'app=?', $app->directory ) ); unset( \IPS\Data\Store::i()->frontNavigation ); } /** * Build default front navigation * * @return void */ public static function buildDefaultFrontNavigation() { \IPS\Db::i()->delete( 'core_menu' ); $topLevelPosition = 1; /* Browse */ \IPS\Db::i()->insert( 'core_menu', array( 'id' => 1, 'app' => 'core', 'extension' => 'CustomItem', 'config' => json_encode( array( 'menu_custom_item_url' => '', 'internal' => '' ) ), 'position' => $topLevelPosition++, 'parent' => NULL, 'permissions' => '*', ) ); /* Activity */ \IPS\Db::i()->insert( 'core_menu', array( 'id' => 2, 'app' => 'core', 'extension' => 'CustomItem', 'config' => json_encode( array( 'menu_custom_item_url' => 'app=core&module=discover&controller=streams', 'internal' => 'discover_all' ) ), 'position' => $topLevelPosition++, 'parent' => NULL, 'permissions' => '*', ) ); /* Commerce requires a bit of a special set up */ if ( \IPS\Application::appIsEnabled('nexus') ) { /* Store */ \IPS\Db::i()->insert( 'core_menu', array( 'id' => 4, 'app' => 'nexus', 'extension' => 'Store', 'config' => json_encode( array() ), 'position' => $topLevelPosition++, 'parent' => NULL, 'permissions' => '*', ) ); /* Support */ \IPS\Db::i()->insert( 'core_menu', array( 'id' => 5, 'app' => 'core', 'extension' => 'CustomItem', 'config' => json_encode( array( 'menu_custom_item_url' => 'app=nexus&module=support&controller=home', 'internal' => 'support' ) ), 'position' => $topLevelPosition++, 'parent' => NULL, 'permissions' => '*', ) ); /* My Details */ \IPS\Db::i()->insert( 'core_menu', array( 'id' => 6, 'app' => 'core', 'extension' => 'Menu', 'config' => json_encode( array() ), 'position' => 5, 'parent' => 4, 'permissions' => '*', ) ); } /* Browse subitems */ $communityApps = array( 'forums', 'gallery', 'downloads', 'cms', 'blog', 'calendar', 'chat' ); $browsePosition = 1; $toInsert = array(); foreach ( $communityApps as $app ) { if ( \IPS\Application::appIsEnabled( $app ) ) { foreach ( array_keys( \IPS\Application::load( $app )->extensions( 'core', 'FrontNavigation', FALSE ) ) as $key ) { $config = array(); if ( $app === 'cms' and $key === 'Cms' ) { /* Cms.php was added to prevent upgrades breaking */ continue; } if ( $app === 'cms' and $key === 'Pages' ) { try { $defaultPage = \IPS\cms\Pages\Page::getDefaultPage(); $config = array( 'menu_content_page' => $defaultPage->id, 'menu_title_page_type' => 0 ); } catch( \OutOfRangeException $ex ) { continue; } } $toInsert[] = array( 'app' => $app, 'extension' => $key, 'config' => json_encode( $config ), 'position' => $browsePosition++, 'parent' => 1, 'permissions' => '', ); } } } /* Insert Apps */ \IPS\Db::i()->insert( 'core_menu', $toInsert ); /* Other 'browse' items */ foreach ( array( 'Guidelines', 'StaffDirectory', 'OnlineUsers' ) as $k ) { \IPS\Db::i()->insert( 'core_menu', array( 'app' => 'core', 'extension' => $k, 'config' => json_encode( array() ), 'position' => $browsePosition++, 'parent' => 1, 'permissions' => '', ) ); } /* Activity Subitems */ $activityPosition = 1; foreach ( array( 'AllActivity', 'YourActivityStreams' ) as $k ) { \IPS\Db::i()->insert( 'core_menu', array( 'app' => 'core', 'extension' => $k, 'config' => json_encode( array() ), 'position' => $activityPosition++, 'parent' => 2, 'permissions' => '', ) ); } foreach ( array( 1, 2 ) as $k ) { try { \IPS\core\Stream::load( $k ); \IPS\Db::i()->insert( 'core_menu', array( 'app' => 'core', 'extension' => 'YourActivityStreamsItem', 'config' => json_encode( array( 'menu_stream_id' => $k ) ), 'position' => $activityPosition++, 'parent' => 2, 'permissions' => '', ) ); } catch ( \Exception $e ) { } } foreach ( array( 'Search' ) as $k ) { \IPS\Db::i()->insert( 'core_menu', array( 'app' => 'core', 'extension' => $k, 'config' => json_encode( array() ), 'position' => $activityPosition++, 'parent' => 2, 'permissions' => '', ) ); } /* Commerce requires a bit of a special set up */ if ( \IPS\Application::appIsEnabled('nexus') ) { $storePosition = 1; foreach ( array( 'Donations', 'Orders', 'Purchases' ) as $k ) { \IPS\Db::i()->insert( 'core_menu', array( 'app' => 'nexus', 'extension' => $k, 'config' => json_encode( array() ), 'position' => $storePosition++, 'parent' => 4, 'permissions' => '', ) ); } $myDetailsPosition = 1; foreach ( array( 'Info', 'Addresses', 'Cards', 'Credit', 'Alternatives', 'Referrals' ) as $k ) { \IPS\Db::i()->insert( 'core_menu', array( 'app' => 'nexus', 'extension' => $k, 'config' => json_encode( array() ), 'position' => $myDetailsPosition++, 'parent' => 6, 'permissions' => '', ) ); } $supportPosition = 1; foreach ( array( 'Support', 'NetworkStatus' ) as $k ) { \IPS\Db::i()->insert( 'core_menu', array( 'app' => 'nexus', 'extension' => $k, 'config' => json_encode( array() ), 'position' => $supportPosition++, 'parent' => 5, 'permissions' => '', ) ); } } /* Other apps */ $toGiveToParents = array(); $parentIds = array(); foreach ( \IPS\Application::allExtensions( 'core', 'FrontNavigation', FALSE, NULL, NULL, FALSE ) as $key => $class ) { $exploded = explode( '_', $key ); if ( !in_array( $exploded[0], array_merge( $communityApps, array( 'core', 'nexus' ) ) ) ) { $parentIds[ $exploded[0] ][ $exploded[1] ] = \IPS\Db::i()->insert( 'core_menu', array( 'app' => $exploded[0], 'extension' => $exploded[1], 'config' => json_encode( array() ), 'position' => $topLevelPosition++, 'parent' => NULL, 'permissions' => '', ) ); } } } /** * @brief The active primary navigation bar */ public $activePrimaryNavBar = NULL; /** * Get roots * * @param bool $noStore If true, will skip datastore and get from DB (used for ACP preview) * @return array */ public function roots( $noStore=FALSE ) { $frontNavigation = static::frontNavigation( $noStore ); $return = array(); foreach ( $frontNavigation[0] as $item ) { $class = 'IPS\\' . $item['app'] . '\extensions\core\FrontNavigation\\' . $item['extension']; $object = new $class( json_decode( $item['config'], TRUE ), $item['id'], $item['permissions'] ); if ( !$this->activePrimaryNavBar ) { $this->activePrimaryNavBar = $item['id']; } $return[ $item['id'] ] = $object; } return $return; } /** * Get sub-bars * * @param bool $noStore If true, will skip datastore and get from DB (used for ACP preview) * @return array */ public function subBars( $noStore=FALSE ) { $frontNavigation = static::frontNavigation( $noStore ); $return = array(); $parentIDs = array(); // Changed so that empty sub bars don't add an array to their parent, allowing us to do count( $subBars ) and figure // out if there's any to show. foreach ( $frontNavigation[0] as $item ) { $parentIDs[] = $item['id']; } foreach ( $parentIDs as $i ) { if ( isset( $frontNavigation[$i] ) ) { foreach ( $frontNavigation[$i] as $item ) { $class = 'IPS\\' . $item['app'] . '\extensions\core\FrontNavigation\\' . $item['extension']; $return[ $item['parent'] ][ $item['id'] ] = new $class( json_decode( $item['config'], TRUE ), $item['id'], $item['permissions'] ); } } } return $return; } }