Version 4.1.2

This commit is contained in:
Neo committed 2025-12-19 05:32:19 -08:00
1 parent 3ba79295ee
commit 28bd025b35
1131 files changed
+63658 -20579

No files matched your search

+67 -14
View File
@@ -625,9 +625,10 @@ class _Output
* @param array $httpHeaders Additional HTTP Headers
* @param bool $cacheThisPage Can/should this page be cached?
* @param bool $pageIsCached Is the page from a cache? If TRUE, no language parsing will be done
* @param bool $parseFileObjects Should <fileStore.xxx> and <___base_url___> be replaced in the output?
* @return void
*/
public function sendOutput( $output='', $httpStatusCode=200, $contentType='text/html', $httpHeaders=array(), $cacheThisPage=TRUE, $pageIsCached=FALSE )
public function sendOutput( $output='', $httpStatusCode=200, $contentType='text/html', $httpHeaders=array(), $cacheThisPage=TRUE, $pageIsCached=FALSE, $parseFileObjects=TRUE )
{
/* Replace language stack keys with actual content */
if ( \IPS\Dispatcher::hasInstance() and !in_array( $contentType, array( 'text/javascript', 'text/css', 'application/json' ) ) and $output and !$pageIsCached )
@@ -636,11 +637,11 @@ class _Output
}
/* Parse file storage URLs */
if ( $output )
if ( $output and $parseFileObjects )
{
$this->parseFileObjectUrls( $output );
}
/* Full page caching for guests */
if (
\IPS\CACHE_PAGE_TIMEOUT and // Page caching is enabled
@@ -651,7 +652,7 @@ class _Output
\IPS\Dispatcher::hasInstance() and class_exists( 'IPS\Dispatcher', FALSE ) and \IPS\Dispatcher::i()->controllerLocation === 'front' and // Is a normal, front-end page (necessary to know if user is logged in)
!\IPS\Member::loggedIn()->member_id // User is not logged in
) {
\IPS\Data\Cache::i()->storeWithExpire( 'page_' . md5( $_SERVER['REQUEST_URI'] ) . '_' . \IPS\Member::loggedIn()->language()->id . '_' . \IPS\Theme::i()->id, array(
\IPS\Data\Cache::i()->storeWithExpire( 'page_' . md5( ( !empty( $_SERVER['HTTP_HOST'] ) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'] ) . '/' . $_SERVER['REQUEST_URI'] ) . '_' . \IPS\Member::loggedIn()->language()->id . '_' . \IPS\Theme::i()->id, array(
'output' => str_replace( \IPS\Session::i()->csrfKey, '{{csrfKey}}', $output ),
'code' => $httpStatusCode,
'contentType' => $contentType,
@@ -710,9 +711,16 @@ class _Output
}
/* Send headers */
$this->sendHeader( "Content-type: {$contentType};charset=UTF-8" );
$size = ob_get_length();
$this->sendHeader( "Content-Length: {$size}" ); // Makes sure the connection closes after sending output so that tasks etc aren't holding it open
$this->sendHeader( "Content-type: {$contentType};charset=UTF-8" );
/* Send content-length header, but only if not using zlib.output_compression, because in that case the length we send in the header
will not match the length of the actual content sent to the browser, breaking things (particularly json) */
if( (bool) ini_get('zlib.output_compression') === false )
{
$size = ob_get_length();
$this->sendHeader( "Content-Length: {$size}" ); // Makes sure the connection closes after sending output so that tasks etc aren't holding it open
}
foreach ( $httpHeaders as $key => $header )
{
$this->sendHeader( $key . ': ' . $header );
@@ -778,6 +786,10 @@ class _Output
}
elseif ( $forceScreen === TRUE or ( $message and !$url->isInternal ) )
{
/* We cannot send a 3xx status code without a Location header, or some browsers (cough IE) will not actually redirect. We are showing
an intermediary page performing the redirect through a meta refresh tag, so a 200 status is appropriate in this case. */
$httpStatusCode = ( mb_substr( $httpStatusCode, 0, 1 ) == 3 ) ? 200 : $httpStatusCode;
$this->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->redirect( $url, $message ), $httpStatusCode );
}
else
@@ -848,7 +860,8 @@ class _Output
*/
public function showOffline()
{
$this->bodyClasses[] = 'ipsLayout_minimal ipsLayout_minimalNoHome';
$this->bodyClasses[] = 'ipsLayout_minimal';
$this->bodyClasses[] = 'ipsLayout_minimalNoHome';
$this->output = \IPS\Theme::i()->getTemplate( 'system', 'core' )->offline( \IPS\Settings::i()->site_offline_message );
$this->title = \IPS\Settings::i()->board_name;
@@ -895,7 +908,7 @@ class _Output
/* Add Admin-specified ones */
if( !$this->metaTagsUrl )
{
$this->metaTagsUrl = \IPS\Request::i()->url()->queryPath();
$this->metaTagsUrl = \IPS\Request::i()->url()->getFurlQuery();
if ( isset( \IPS\Data\Store::i()->metaTags ) )
{
@@ -913,7 +926,7 @@ class _Output
{
if( \strpos( $row['meta_url'], '*' ) !== FALSE )
{
if( preg_match( "#^" . str_replace( '*', '(.*)', trim( $row['meta_url'], '/' ) ) . "$#i", trim( $this->metaTagsUrl, '/' ) ) )
if( preg_match( "#^" . str_replace( '\*', '(.*)', trim( preg_quote( $row['meta_url'], '#' ), '/' ) ) . "$#i", trim( $this->metaTagsUrl, '/' ) ) )
{
$_tags = json_decode( $row['meta_tags'], TRUE );
@@ -958,6 +971,35 @@ class _Output
}
}
}
$baseUrl = parse_url( \IPS\Settings::i()->base_url );
$lookFor = '//' . $baseUrl['host'];
foreach( $this->metaTags as $name => $value )
{
if ( ! is_array( $value ) )
{
$value = array( $value );
}
foreach( $value as $tag )
{
if ( mb_substr( $tag, 0, mb_strlen( $lookFor ) ) === $lookFor )
{
/* Try to preserve http vs https */
if( isset( $baseUrl['scheme'] ) )
{
$tag = str_replace( $lookFor, $baseUrl['scheme'] . '://' . $baseUrl['host'], $tag );
}
else
{
$tag = str_replace( $lookFor, 'http://' . $baseUrl['host'], $tag );
}
$this->metaTags[ $name ] = $tag;
}
}
}
}
/**
@@ -996,6 +1038,11 @@ class _Output
* @brief Contextual search menu options
*/
public $contextualSearchOptions = array();
/**
* @brief Default search option
*/
public $defaultSearchOption = array( 'all', 'search_everything' );
/**
* Retrieve options for search menu
@@ -1010,14 +1057,20 @@ class _Output
{
if( is_subclass_of( $class, 'IPS\Content\Searchable' ) )
{
$type = mb_strtolower( str_replace( '\\', '_', mb_substr( $class, 4 ) ) );
$this->globalSearchMenuOptions[ $type ] = $type . '_pl';
if ( $class::$includeInSiteSearch )
{
$type = mb_strtolower( str_replace( '\\', '_', mb_substr( $class, 4 ) ) );
$this->globalSearchMenuOptions[ $type ] = $type . '_pl';
}
}
}
}
/* This is also supported, but is not a content item class implementing \Searchable */
$this->globalSearchMenuOptions['core_members'] = 'core_members_pl';
if ( \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'members', 'front' ) ) )
{
$this->globalSearchMenuOptions['core_members'] = 'core_members_pl';
}
return $this->globalSearchMenuOptions;
}