Version 4.6.0
This commit is contained in:
1 parent
f79dcf067a
commit
517a5e1f70
2036 files changed
+110041
-26162
No files matched your search
@@ -48,7 +48,7 @@ abstract class _Cache
|
||||
{
|
||||
$classname = 'IPS\Output\Cache\\' . \IPS\OUTPUT_CACHE_METHOD;
|
||||
|
||||
if ( $classname::supported() )
|
||||
if ( \class_exists( $classname ) and $classname::supported() )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -89,13 +89,14 @@ class _Database extends \IPS\Output\Cache
|
||||
/**
|
||||
* Remove all expired caches
|
||||
*
|
||||
* @param boolean $truncate Truncate the table
|
||||
* @return void
|
||||
*/
|
||||
public function deleteExpired()
|
||||
public function deleteExpired( $truncate=FALSE )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_output_cache', array( 'cache_expire<?', time() ) );
|
||||
\IPS\Db::i()->delete( 'core_output_cache', ( ! $truncate ? array( 'cache_expire<?', time() ) : NULL ) );
|
||||
}
|
||||
catch ( \IPS\Db\Exception $e ) { }
|
||||
}
|
||||
|
||||
@@ -187,9 +187,10 @@ class _Redis extends \IPS\Output\Cache
|
||||
/**
|
||||
* Remove all expired caches
|
||||
*
|
||||
* @param boolean $truncate Truncate the table
|
||||
* @return void
|
||||
*/
|
||||
public function deleteExpired()
|
||||
public function deleteExpired( $truncate=FALSE )
|
||||
{
|
||||
/* Redis handles this for us automatically */
|
||||
}
|
||||
|
||||
@@ -188,13 +188,19 @@ class _Javascript extends \IPS\Patterns\ActiveRecord
|
||||
|
||||
if ( \IPS\IN_DEV AND $this->location == 'plugins' )
|
||||
{
|
||||
/* Write the file to disk in the correct location */
|
||||
$file = \IPS\ROOT_PATH . '/plugins/' . $this->plugin . '/dev/js/' . $this->name;
|
||||
|
||||
if ( \is_file( $file ) )
|
||||
try
|
||||
{
|
||||
\unlink( $file );
|
||||
$plugin = \IPS\Plugin::load( $this->plugin );
|
||||
|
||||
/* Write the file to disk in the correct location */
|
||||
$file = \IPS\ROOT_PATH . '/plugins/' . $plugin->location . '/dev/js/' . $this->name;
|
||||
|
||||
if ( \is_file( $file ) )
|
||||
{
|
||||
\unlink( $file );
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $e ) {}
|
||||
}
|
||||
|
||||
$_where = "javascript_app=? AND javascript_location=? AND javascript_path=? AND javascript_name=?";
|
||||
@@ -373,8 +379,7 @@ class _Javascript extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
|
||||
/* Open XML file */
|
||||
$xml = new \IPS\Xml\XMLReader;
|
||||
$xml->open( $file );
|
||||
$xml = \IPS\Xml\XMLReader::safeOpen( $file );
|
||||
$xml->read();
|
||||
|
||||
$app = $xml->getAttribute('app');
|
||||
@@ -502,8 +507,7 @@ class _Javascript extends \IPS\Patterns\ActiveRecord
|
||||
/* Open XML file */
|
||||
if( file_exists( \IPS\ROOT_PATH . '/applications/' . $app . '/data/javascript.xml' ) )
|
||||
{
|
||||
$xml = new \IPS\Xml\XMLReader;
|
||||
$xml->open( \IPS\ROOT_PATH . '/applications/' . $app . '/data/javascript.xml' );
|
||||
$xml = \IPS\Xml\XMLReader::safeOpen( \IPS\ROOT_PATH . '/applications/' . $app . '/data/javascript.xml' );
|
||||
$xml->read();
|
||||
|
||||
while( $xml->read() )
|
||||
|
||||
+126
-97
@@ -226,6 +226,11 @@ class _Output
|
||||
*/
|
||||
public $pageCaching = TRUE;
|
||||
|
||||
/**
|
||||
* @brief pageName for data-pageName in the <body> tag
|
||||
*/
|
||||
public $pageName = NULL;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -244,6 +249,12 @@ class _Output
|
||||
{
|
||||
$this->httpHeaders['X-Frame-Options'] = 'sameorigin';
|
||||
}
|
||||
|
||||
/* 2 = entire suite, 1 = ACP only */
|
||||
if( \IPS\Settings::i()->referrer_policy_header == 2 OR ( \IPS\Settings::i()->referrer_policy_header == 1 AND \IPS\Dispatcher::hasInstance() and \IPS\Dispatcher::i()->controllerLocation === 'admin' ) )
|
||||
{
|
||||
$this->httpHeaders['Referrer-Policy'] = 'strict-origin-when-cross-origin';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,13 +297,23 @@ class _Output
|
||||
if ( \in_array( $file, static::$globalJavascript ) )
|
||||
{
|
||||
/* Global bundle (admin.js, front.js, library.js, framework.js, map.js) */
|
||||
return array( static::_getJavascriptFileObject( 'global', 'root', $file )->url );
|
||||
$fileObj = static::_getJavascriptFileObject( 'global', 'root', $file );
|
||||
|
||||
if ( $fileObj !== NULL )
|
||||
{
|
||||
return array( $fileObj->url->setQueryString( 'v', \IPS\Output\Javascript::javascriptCacheBustKey() ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Languages JS file */
|
||||
if ( mb_substr( $file, 0, 8 ) === 'js_lang_' )
|
||||
{
|
||||
return array( static::_getJavascriptFileObject( 'global', 'root', $file )->url );
|
||||
$fileObj = static::_getJavascriptFileObject( 'global', 'root', $file );
|
||||
|
||||
if ( $fileObj !== NULL )
|
||||
{
|
||||
return array( $fileObj->url->setQueryString( 'v', \IPS\Output\Javascript::javascriptCacheBustKey() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -307,7 +328,7 @@ class _Output
|
||||
|
||||
if ( $pluginsJs !== NULL )
|
||||
{
|
||||
return array( $pluginsJs->url );
|
||||
return array( $pluginsJs->url->setQueryString( 'v', \IPS\Output\Javascript::javascriptCacheBustKey() ) );
|
||||
}
|
||||
}
|
||||
/* app.js - all models and ui */
|
||||
@@ -317,7 +338,7 @@ class _Output
|
||||
|
||||
if ( $fileObj !== NULL )
|
||||
{
|
||||
return array( $fileObj->url );
|
||||
return array( $fileObj->url->setQueryString( 'v', \IPS\Output\Javascript::javascriptCacheBustKey() ) );
|
||||
}
|
||||
}
|
||||
/* {location}_{section}.js */
|
||||
@@ -331,7 +352,7 @@ class _Output
|
||||
|
||||
if ( $fileObj !== NULL )
|
||||
{
|
||||
return array( $fileObj->url );
|
||||
return array( $fileObj->url->setQueryString( 'v', \IPS\Output\Javascript::javascriptCacheBustKey() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -431,14 +452,26 @@ class _Output
|
||||
* @param int $cacheSeconds Number of seconds to cache for
|
||||
* @return array
|
||||
*/
|
||||
public static function getCacheHeaders( $lastModified, $cacheSeconds )
|
||||
public static function getCacheHeaders( int $lastModified, int $cacheSeconds ): array
|
||||
{
|
||||
return array(
|
||||
'Date' => \IPS\DateTime::ts( time(), TRUE )->rfc1123(),
|
||||
'Last-Modified' => \IPS\DateTime::ts( $lastModified, TRUE )->rfc1123(),
|
||||
'Expires' => \IPS\DateTime::ts( ( time() + $cacheSeconds ), TRUE )->rfc1123(),
|
||||
'Cache-Control' => "max-age=" . $cacheSeconds . ", public",
|
||||
'Pragma' => "public",
|
||||
'Cache-Control' => "max-age=" . $cacheSeconds . ", public, s-maxage=" . $cacheSeconds . ", stale-while-revalidate, stale-if-error",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get No Cache Headers
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getNoCacheHeaders(): array
|
||||
{
|
||||
return array(
|
||||
'Expires' => 0,
|
||||
'Cache-Control' => "no-cache, no-store, must-revalidate"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -490,7 +523,7 @@ class _Output
|
||||
* @param string|null $app Application
|
||||
* @param string|null $location Location (e.g. 'admin', 'front')
|
||||
* @param string $file Filename
|
||||
* @return string URL to JS file object
|
||||
* @return string|null URL to JS file object
|
||||
*/
|
||||
protected static function _getJavascriptFileObject( $app, $location, $file )
|
||||
{
|
||||
@@ -629,6 +662,14 @@ class _Output
|
||||
{
|
||||
$message = $adminMessage;
|
||||
}
|
||||
else if ( \IPS\Dispatcher::i()->dispatcherController instanceof \IPS\Content\Controller and mb_substr( $message, 0, 10 ) == 'node_error' )
|
||||
{
|
||||
if ( \IPS\Member::loggedIn()->language()->checkKeyExists( $httpStatusCode . '_' . \IPS\Dispatcher::i()->application->directory . '_' . \IPS\Dispatcher::i()->controller ) )
|
||||
{
|
||||
$message = $httpStatusCode . '_' . \IPS\Dispatcher::i()->application->directory . '_' . \IPS\Dispatcher::i()->controller;
|
||||
}
|
||||
}
|
||||
|
||||
if ( \IPS\Member::loggedIn()->language()->checkKeyExists( $message ) )
|
||||
{
|
||||
$message = \IPS\Member::loggedIn()->language()->addToStack( $message );
|
||||
@@ -680,13 +721,21 @@ class _Output
|
||||
$faulty = \IPS\Member::loggedIn()->language()->addToStack( 'faulty_app', FALSE, array( 'sprintf' => array( $app->_title, \IPS\Http\Url::internal( 'app=core&module=applications&controller=applications', 'admin' ) ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Do not cache error pages
|
||||
|
||||
/* Send default Cache Headers if this is a front-end page. */
|
||||
$allowGuestCache = FALSE;
|
||||
if ( !isset( $httpHeaders['Cache-Control'] ) AND ( $httpStatusCode == 404 OR $httpStatusCode == 403 ) )
|
||||
{
|
||||
if ( \IPS\CACHE_PAGE_TIMEOUT AND $this->pageCaching AND \IPS\Dispatcher::hasInstance() AND \IPS\Dispatcher::i()->controllerLocation === 'front' AND !\IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
$httpHeaders += static::getCacheHeaders( time(), \IPS\CACHE_PAGE_TIMEOUT );
|
||||
$allowGuestCache = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Send output */
|
||||
\IPS\Output::i()->sidebar['enabled'] = FALSE;
|
||||
$this->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( $title, \IPS\Theme::i()->getTemplate( 'global', 'core' )->error( $title, $message, $code, $extra, $member, $faulty ), array( 'app' => \IPS\Dispatcher::i()->application ? \IPS\Dispatcher::i()->application->directory : NULL, 'module' => \IPS\Dispatcher::i()->module ? \IPS\Dispatcher::i()->module->key : NULL, 'controller' => \IPS\Dispatcher::i()->controller ) ), $httpStatusCode, 'text/html', $httpHeaders, $allowGuestCache, FALSE );
|
||||
$this->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( $title, \IPS\Theme::i()->getTemplate( 'global', 'core' )->error( $title, $message, $code, $extra, $member, $faulty, $httpStatusCode ), array( 'app' => \IPS\Dispatcher::i()->application ? \IPS\Dispatcher::i()->application->directory : NULL, 'module' => \IPS\Dispatcher::i()->module ? \IPS\Dispatcher::i()->module->key : NULL, 'controller' => \IPS\Dispatcher::i()->controller ) ), $httpStatusCode, 'text/html', $httpHeaders, $allowGuestCache, FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -725,6 +774,11 @@ class _Output
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Flag to bypass CSRF IN_DEV check
|
||||
*/
|
||||
public $bypassCsrfKeyCheck = FALSE;
|
||||
|
||||
/**
|
||||
* Send output
|
||||
*
|
||||
@@ -741,6 +795,12 @@ class _Output
|
||||
*/
|
||||
public function sendOutput( $output='', $httpStatusCode=200, $contentType='text/html', $httpHeaders=array(), $cacheThisPage=TRUE, $pageIsCached=FALSE, $parseFileObjects=TRUE, $parseEmoji=TRUE )
|
||||
{
|
||||
if( \IPS\IN_DEV AND !$this->bypassCsrfKeyCheck AND mb_substr( $httpStatusCode, 0, 1 ) === '2' AND isset( $_GET['csrfKey'] ) AND $_GET['csrfKey'] AND !\IPS\Request::i()->isAjax() AND ( !isset( $httpHeaders['Content-Disposition'] ) OR mb_strpos( $httpHeaders['Content-Disposition'], 'attachment' ) === FALSE ) )
|
||||
{
|
||||
trigger_error( "An {$httpStatusCode} response is being sent however the CSRF key is present in the requested URL. CSRF keys should be sent via POST or the request should be redirected to a URL not containing a CSRF key once finished.", E_USER_ERROR );
|
||||
exit;
|
||||
}
|
||||
|
||||
/* 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 )
|
||||
{
|
||||
@@ -769,34 +829,54 @@ class _Output
|
||||
}
|
||||
}
|
||||
|
||||
/* Combine some common checks for re-use */
|
||||
$canCache = function( $contentType, $obj ) {
|
||||
if( $obj->pageCaching and
|
||||
( mb_strtolower( $_SERVER['REQUEST_METHOD'] ) == 'get' OR mb_strtolower( $_SERVER['REQUEST_METHOD'] ) == 'head' ) and // Is a HTTP GET/HEAD request (don't cache output for POSTs)
|
||||
( $contentType == 'text/html' or $contentType == 'text/xml' or $contentType == 'application/manifest+json' ) and // Output is HTML, XML or [PWA] application manifest (don't cache JSON output, etc)
|
||||
\IPS\Dispatcher::hasInstance() and class_exists( 'IPS\Dispatcher', FALSE ) and \IPS\Dispatcher::i()->controllerLocation === 'front' // Is a normal, front-end page (necessary to know if user is logged in)
|
||||
)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
/* Full page caching for guests */
|
||||
if (
|
||||
\IPS\CACHE_PAGE_TIMEOUT and $this->pageCaching and // Page caching is enabled
|
||||
$cacheThisPage and // Some pages can specify not to be cached (for example, when displaying a cached page, you don't want it recached)
|
||||
!isset( \IPS\Request::i()->cookie['noCache'] ) and // A noCache cookie might get set to not cache a particular guest (for example, if they have added items to their cart in the store)
|
||||
( mb_strtolower( $_SERVER['REQUEST_METHOD'] ) == 'get' OR mb_strtolower( $_SERVER['REQUEST_METHOD'] ) == 'head' ) and // Is a HTTP GET/HEAD request (don't cache output for POSTs)
|
||||
!isset( \IPS\Request::i()->csrfKey ) and // CSRF key isn't present (which would be like a POST request)
|
||||
( $contentType == 'text/html' or $contentType == 'text/xml' or $contentType == 'application/manifest+json' ) and // Output is HTML, XML or [PWA] application manifest (don't cache JSON output, etc)
|
||||
\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\CACHE_PAGE_TIMEOUT and // Page caching is enabled
|
||||
$cacheThisPage and // Some pages can specify not to be cached (for example, when displaying a cached page, you don't want it recached)
|
||||
!isset( \IPS\Request::i()->cookie['noCache'] ) and // A noCache cookie might get set to not cache a particular guest (for example, if they have added items to their cart in the store)
|
||||
$canCache( $contentType, $this ) and // Common checks, see above
|
||||
!isset( \IPS\Request::i()->csrfKey ) and // CSRF key isn't present (which would be like a POST request)
|
||||
!\IPS\Member::loggedIn()->member_id // User is not logged in
|
||||
) {
|
||||
$theme = isset( \IPS\Request::i()->cookie['theme'] ) ? \IPS\Request::i()->cookie['theme'] : '';
|
||||
/* Store copy of cached page if output caching is enabled */
|
||||
if( !empty( \IPS\OUTPUT_CACHE_METHOD ) AND \IPS\OUTPUT_CACHE_METHOD !== 'None' )
|
||||
{
|
||||
$theme = isset( \IPS\Request::i()->cookie['theme'] ) ? \IPS\Request::i()->cookie['theme'] : '';
|
||||
|
||||
\IPS\Output\Cache::i()->set( 'page_' . md5( (string) \IPS\Request::i()->url() ) . '_' . \IPS\Member::loggedIn()->language()->id . '_' . $theme,
|
||||
str_replace( \IPS\Session::i()->csrfKey, '{{csrfKey}}', $output ),
|
||||
array(
|
||||
'code' => $httpStatusCode,
|
||||
'contentType' => $contentType,
|
||||
'httpHeaders' => array_merge( $httpHeaders, array( 'X-IPS-Cached-Response' => \IPS\DateTime::create()->rfc1123() ) ),
|
||||
'lastUpdated' => time()
|
||||
), \IPS\DateTime::create()->add( new \DateInterval( 'PT' . \IPS\CACHE_PAGE_TIMEOUT . 'S' ) ), TRUE );
|
||||
}
|
||||
|
||||
\IPS\Output\Cache::i()->set( 'page_' . md5( (string) \IPS\Request::i()->url() ) . '_' . \IPS\Member::loggedIn()->language()->id . '_' . $theme,
|
||||
str_replace( \IPS\Session::i()->csrfKey, '{{csrfKey}}', $output ),
|
||||
array(
|
||||
'code' => $httpStatusCode,
|
||||
'contentType' => $contentType,
|
||||
'httpHeaders' => array_merge( $httpHeaders, array( 'X-IPS-Cached-Response' => \IPS\DateTime::create()->rfc1123() ) ),
|
||||
'lastUpdated' => time()
|
||||
), \IPS\DateTime::create()->add( new\DateInterval( 'PT' . \IPS\CACHE_PAGE_TIMEOUT . 'S' ) ), TRUE );
|
||||
|
||||
/* Add caching headers */
|
||||
if( !isset( $httpHeaders['Cache-Control'] ) )
|
||||
{
|
||||
$httpHeaders += \IPS\Output::getCacheHeaders( time(), \IPS\CACHE_PAGE_TIMEOUT );
|
||||
}
|
||||
}
|
||||
/* Send no-cache headers if we got to this point without any cache-control headers being set, or page caching is forced off */
|
||||
elseif( !isset( $httpHeaders['Cache-Control'] ) OR !$this->pageCaching )
|
||||
{
|
||||
$httpHeaders += \IPS\Output::getNoCacheHeaders();
|
||||
}
|
||||
|
||||
/* Include headers set in constructor, intentionally after guest caching. */
|
||||
$httpHeaders = $this->httpHeaders + $httpHeaders;
|
||||
@@ -842,6 +922,12 @@ class _Output
|
||||
$output = str_replace( '<!--ipsCachingLog-->', \IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->cachingLog( $cachingLog ), $output );
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for any autosave cookies */
|
||||
if ( \count( \IPS\Request::i()->clearAutoSaveCookie ) )
|
||||
{
|
||||
\IPS\Request::i()->setCookie( 'clearAutosave', implode( ',', \IPS\Request::i()->clearAutoSaveCookie ), NULL, FALSE );
|
||||
}
|
||||
|
||||
/* Remove anything from the output buffer that should not be there as it can confuse content-length */
|
||||
@ob_end_clean();
|
||||
@@ -860,8 +946,9 @@ class _Output
|
||||
{
|
||||
$this->sendHeader( "X-IPS-LoggedIn: " . ( ( \IPS\Member::loggedIn()->member_id ) ? 1 : 0 ) );
|
||||
}
|
||||
|
||||
$vary = array( 'cookie' );
|
||||
|
||||
/* We want to vary on the cookie so that browser caches are not used when changing themes or languages */
|
||||
$vary = array( 'Cookie' );
|
||||
|
||||
/* Can we compress the content? */
|
||||
if ( $output and isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) )
|
||||
@@ -1049,7 +1136,7 @@ class _Output
|
||||
'message' => $message
|
||||
) );
|
||||
}
|
||||
elseif ( $forceScreen === TRUE or ( $message and !$url->isInternal ) )
|
||||
elseif ( $forceScreen === TRUE or ( $message and !( $url instanceof \IPS\Http\Url\Internal ) ) )
|
||||
{
|
||||
/* 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. */
|
||||
@@ -1073,12 +1160,7 @@ class _Output
|
||||
}
|
||||
|
||||
/* Send location and no-cache headers to prevent redirects from being cached */
|
||||
$headers = array(
|
||||
"Location" => (string) $url,
|
||||
"Cache-Control" => "no-cache, no-store, must-revalidate",
|
||||
"Pragma" => "no-cache",
|
||||
"Expires" => "0",
|
||||
);
|
||||
$headers = \array_merge( array( "Location" => (string) $url ), \IPS\Output::getNoCacheHeaders() );
|
||||
|
||||
$this->sendOutput( '', $httpStatusCode, '', $headers );
|
||||
}
|
||||
@@ -1294,7 +1376,7 @@ class _Output
|
||||
/* Add Admin-specified ones */
|
||||
if( !$this->metaTagsUrl )
|
||||
{
|
||||
$this->metaTagsUrl = \IPS\Request::i()->url()->getFurlQuery();
|
||||
$this->metaTagsUrl = ( \IPS\Request::i()->url() instanceof \IPS\Http\Url\Friendly ) ? \IPS\Request::i()->url()->friendlyUrlComponent : NULL;
|
||||
|
||||
if ( isset( \IPS\Data\Store::i()->metaTags ) )
|
||||
{
|
||||
@@ -1311,6 +1393,8 @@ class _Output
|
||||
/* We duplicate these so we can know what is generated automatically for the live meta tag editor */
|
||||
$this->autoMetaTags = $this->metaTags;
|
||||
|
||||
$rootPath = \IPS\Http\Url::external( \IPS\Settings::i()->base_url )->data['path'];
|
||||
|
||||
foreach ( $rows as $row )
|
||||
{
|
||||
if( \strpos( $row['meta_url'], '*' ) !== FALSE )
|
||||
@@ -1346,7 +1430,6 @@ class _Output
|
||||
}
|
||||
else
|
||||
{
|
||||
$rootPath = \IPS\Http\Url::external( \IPS\Settings::i()->base_url )->data['path'];
|
||||
if( trim( $row['meta_url'], '/' ) == trim( $this->metaTagsUrl, '/' ) and ( ( $row['meta_url'] == '/' and \IPS\Request::i()->url()->data['path'] == $rootPath ) or $row['meta_url'] !== '/' ) )
|
||||
{
|
||||
$_tags = json_decode( $row['meta_tags'], TRUE );
|
||||
@@ -1527,60 +1610,6 @@ class _Output
|
||||
$this->jsonLd = array_merge( $this->jsonLd, $jsonLd );
|
||||
}
|
||||
|
||||
/**
|
||||
* License Warning
|
||||
*
|
||||
* @return string|NULL "none" = no license key. "expired" = license key expired. NULL = no error
|
||||
* @deprecated to be removed in 4.5
|
||||
*/
|
||||
public function licenseKeyWarning()
|
||||
{
|
||||
if ( !\IPS\Settings::i()->ipb_reg_number and \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'settings', 'licensekey_manage' ) )
|
||||
{
|
||||
return 'none';
|
||||
}
|
||||
else
|
||||
{
|
||||
$licenseKey = \IPS\IPS::licenseKey();
|
||||
if ( ( $licenseKey === NULL or ( isset( $licenseKey['legacy'] ) and $licenseKey['legacy'] ) ) and \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'settings', 'licensekey_manage' ) )
|
||||
{
|
||||
return 'none';
|
||||
}
|
||||
elseif ( ( ( isset( $licenseKey['expires'] ) and strtotime( $licenseKey['expires'] ) < time() ) or ! isset( $licenseKey['active'] ) or !$licenseKey['active'] ) and \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'settings', 'licensekey_manage' ) )
|
||||
{
|
||||
return 'expired';
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Days remaining before license expires
|
||||
*
|
||||
* @return int|NULL NULL or the number of days remaining
|
||||
* @deprecated to be removed in 4.5
|
||||
*/
|
||||
public function licenseKeyDaysRemaining()
|
||||
{
|
||||
$licenseData = \IPS\IPS::licenseKey();
|
||||
if( !isset( $licenseData['expires'] ) OR !$licenseData['expires'] )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Work out days remaining, we can't use ->days here because it doesn't differentiate between postive and negative */
|
||||
$daysLeft = (int) (new \IPS\DateTime)->diff( \IPS\DateTime::ts( strtotime( $licenseData['expires'] ) ) )->format('%r%a');
|
||||
|
||||
/* Return zero if the days remaining is negative */
|
||||
if( $daysLeft < 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $daysLeft;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Global search menu options
|
||||
*/
|
||||
@@ -1650,7 +1679,7 @@ class _Output
|
||||
*/
|
||||
protected static function getInlineMessage()
|
||||
{
|
||||
if ( ( \IPS\Dispatcher::hasInstance() and \IPS\Dispatcher::i()->controllerLocation == 'front' ) and ( \IPS\Session\Front::loggedIn() or isset( \IPS\Request::i()->cookie['noCache'] ) ) ) # Don't attempt to initiate a full member object here
|
||||
if ( \IPS\Dispatcher::hasInstance() and \IPS\Dispatcher::i()->controllerLocation == 'front' and \IPS\Session\Front::loggedIn() ) # Don't attempt to initiate a full member object here
|
||||
{
|
||||
return ( ( isset( $_SESSION['inlineMessage'] ) and ! empty( $_SESSION['inlineMessage'] ) ) ? $_SESSION['inlineMessage'] : NULL );
|
||||
}
|
||||
@@ -1670,7 +1699,7 @@ class _Output
|
||||
*/
|
||||
protected static function setInlineMessage( $message=NULL )
|
||||
{
|
||||
if ( ( \IPS\Dispatcher::hasInstance() and \IPS\Dispatcher::i()->controllerLocation == 'front' ) and ( \IPS\Session\Front::loggedIn() or isset( \IPS\Request::i()->cookie['noCache'] ) ) ) # Don't attempt to initiate a full member object here
|
||||
if ( \IPS\Dispatcher::hasInstance() and \IPS\Dispatcher::i()->controllerLocation == 'front' and \IPS\Session\Front::loggedIn() ) # Don't attempt to initiate a full member object here
|
||||
{
|
||||
$_SESSION['inlineMessage'] = $message;
|
||||
}
|
||||
|
||||
@@ -57,6 +57,6 @@ class _Fontsize
|
||||
}
|
||||
|
||||
// e.g. 100 * 0.14 = 14px
|
||||
return '"' . $number . 'px"';
|
||||
return '"' . number_format( $number, 1 ) . 'px"';
|
||||
}
|
||||
}
|
||||
@@ -42,12 +42,6 @@ class _Theme
|
||||
case 'logo_front':
|
||||
return "\IPS\Theme::i()->logo_front";
|
||||
break;
|
||||
case 'logo_sharer':
|
||||
return "\IPS\Theme::i()->logo_sharer";
|
||||
break;
|
||||
case 'logo_favicon':
|
||||
return "\IPS\Theme::i()->logo_favicon";
|
||||
break;
|
||||
case 'logo_height':
|
||||
return ( isset( \IPS\Theme::i()->logo['front']['height'] ) ) ? '\IPS\Theme::i()->logo[\'front\'][\'height\']' : 100;
|
||||
break;
|
||||
|
||||
Reference in new issue
Block a user