Version 4.1.19

This commit is contained in:
Neo committed 2025-12-19 05:38:56 -08:00
1 parent 28bd025b35
commit 2bd5025018
2674 files changed
+233518 -77766

No files matched your search

+2 -2
View File
@@ -2,9 +2,9 @@
/**
* @brief Magic Template Class for advanced theme (designers) mode
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @package IPS Community Suite
* @since 06 Aug 2013
* @version SVN_VERSION_NUMBER
*/
+54 -26
View File
@@ -2,9 +2,9 @@
/**
* @brief Advanced theming mode
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @package IPS Community Suite
* @since 06 Aug 2013
* @version SVN_VERSION_NUMBER
*/
@@ -38,6 +38,11 @@ class _Theme extends \IPS\Theme\Dev\Theme
*/
public static $toBuild = null;
/**
* @brief [ActiveRecord] Multiton Store
*/
protected static $multitons;
/**
* Constructor
*
@@ -58,7 +63,7 @@ class _Theme extends \IPS\Theme\Dev\Theme
if ( \IPS\Theme::load( $setId )->canAccess() !== true )
{
$setId = \IPS\Theme::defaultTheme();
$setId = ( $column == 'skin' ? \IPS\Theme::defaultTheme() : \IPS\Theme::defaultAcpTheme() );
/* Restore default theme for member */
\IPS\Member::loggedIn()->$column = $setId;
@@ -67,13 +72,13 @@ class _Theme extends \IPS\Theme\Dev\Theme
}
else
{
$setId = \IPS\Theme::defaultTheme();
$setId = ( $column == 'skin' ? \IPS\Theme::defaultTheme() : \IPS\Theme::defaultAcpTheme() );
}
static::$currentThemeId = ( static::$currentThemeId ) ? static::$currentThemeId : $setId;
/* Check to make sure the files are there */
if ( ! is_dir( static::_getHtmlPath('core') ) OR ! is_dir( static::_getCssPath('core') ) OR ! is_dir( static::_getResourcePath('core') ) )
if ( static::$buildingFiles === FALSE and ( ! is_dir( static::_getHtmlPath('core') ) OR ! is_dir( static::_getCssPath('core') ) OR ! is_dir( static::_getResourcePath('core') ) ) )
{
/* Toggle the setting as something has gone wrong */
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 0 ), array( 'conf_key=?', 'theme_designers_mode' ) );
@@ -359,28 +364,31 @@ class _Theme extends \IPS\Theme\Dev\Theme
\IPS\Output::i()->error( 'theme_dm_err_cant_write_into_theme_id', '4S142/4', 403, '' );
}
if ( !file_exists( $dirToWrite . '/lang.php' ) )
/* Make sure previous versions of this file are removed */
if ( file_exists( $dirToWrite . '/lang.php' ) )
{
$languageStrings = \IPS\Db::i()->select( 'word_key, word_default', 'core_sys_lang_words', array( 'word_theme=?', static::$currentThemeId ) )->setKeyField('word_key')->setValueField('word_default');
if( count( $languageStrings ) )
{
$langToWrite = "\$lang = array(\n";
foreach( $languageStrings as $key => $string )
{
$langToWrite .= "'{$key}'\t\t=> '" . str_replace( "'", "\\'", $string ) . "',\n";
}
$langToWrite .= ");";
}
else
{
$langToWrite = "\$lang = array(\n\t\n);";
}
@\file_put_contents( $dirToWrite . '/lang.php', '<?' . "php\n\n{$langToWrite}\n" );
unlink( $dirToWrite . '/lang.php' );
}
$languageStrings = \IPS\Db::i()->select( 'word_key, word_default', 'core_sys_lang_words', array( 'word_theme=?', static::$currentThemeId ) )->setKeyField('word_key')->setValueField('word_default');
if( count( $languageStrings ) )
{
$langToWrite = "\$lang = array(\n";
foreach( $languageStrings as $key => $string )
{
$langToWrite .= "'{$key}'\t\t=> '" . str_replace( "'", "\\'", $string ) . "',\n";
}
$langToWrite .= ");";
}
else
{
$langToWrite = "\$lang = array(\n\t\n);";
}
@\file_put_contents( $dirToWrite . '/lang.php', '<?' . "php\n\n{$langToWrite}\n" );
return $dirToWrite;
}
@@ -594,11 +602,31 @@ class _Theme extends \IPS\Theme\Dev\Theme
{
$pathToWrite = static::_writeThemePathDirectory( $app, 'html', $app . '/' . $location . '/' . $group );
/* On case sensitive file systems, ensure that a template with the same name but different case doesn't exist */
$fileMap = array();
foreach( new \DirectoryIterator( $pathToWrite ) as $file )
{
if ( $file->isDot() || mb_substr( $file->getFilename(), 0, 1 ) === '.' || $file == 'index.html' )
{
continue;
}
$fileMap[ mb_strtolower( $file->getFilename() ) ][] = $file->getFilename();
}
foreach( $templates[ $app ][ $location ][ $group ] as $name => $data )
{
$write = '<ips:template parameters="' . $data['template_data'] . '" />' . "\n";
$write .= $data['template_content'];
if ( isset( $fileMap[ mb_strtolower( $data['template_name'] . '.phtml' ) ] ) )
{
foreach( $fileMap[ mb_strtolower( $data['template_name'] . '.phtml' ) ] as $file )
{
@unlink( $pathToWrite . '/' . $file );
}
}
if ( ! @\file_put_contents( $pathToWrite . '/' . $data['template_name'] . '.phtml', $write ) )
{
\IPS\Output::i()->error( 'theme_dm_err_cant_write_template', '4S142/9', 403, '' );
+143
View File
@@ -0,0 +1,143 @@
<?php
/**
* @brief Magic Template Class for advanced theme (designers) mode
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @since 06 Aug 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\Theme\Cache;
/* 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;
}
/**
* Magic Template Class for cachable templates
*/
class _Template extends \IPS\Theme\Template
{
/**
* @brief Source File
*/
protected static $file = NULL;
/**
* @brief Template object
*/
protected static $object = NULL;
/**
* @brief Theme object
*/
protected static $theme = NULL;
/**
* @brief Class name
*/
protected static $className = NULL;
/**
* Contructor
*
* @param string $app Application Key
* @param string $templateLocation Template location (admin/public/etc.)
* @param string $templateName Template Name
* @return void
*/
public function __construct( $app, $templateLocation, $templateName )
{
parent::__construct( $app, $templateLocation, $templateName );
static::$theme = \IPS\Theme::$memberTheme;
if ( ! static::$theme->cache_key )
{
/* This theme has never received a cache key, so lets create one now */
static::$theme->resetCacheKey();
}
static::$className = 'class_' . $app . '_' . $templateLocation . '_' . $templateName;
$key = \strtolower( 'template_' . static::$theme->id . '_' . \IPS\Theme::makeBuiltTemplateLookupHash( $app, $templateLocation, $templateName ) . '_' . \IPS\Theme::cleanGroupName( $templateName ) );
static::$file = \IPS\Settings::i()->theme_disk_cache_path . "/" . $key . ".php";
}
/**
* Does this template bit exist
* This checks that it exists and also that the theme key matches
*
* @return boolean
*/
public function exists()
{
if ( file_exists( static::$file ) )
{
include_once( static::$file );
$class = "\\IPS\\Theme\\Cache\\" . \IPS\Theme::overloadHooks( static::$className, "IPS\\Theme\\Cache" );
if ( class_exists( $class ) )
{
static::$object = new $class( $this->app, $this->templateLocation, $this->templateName );
if ( static::$theme->cache_key != static::$object->cache_key )
{
@unlink( static::$file );
/* Clear zend opcache if enabled */
if ( function_exists( 'opcache_invalidate' ) )
{
@opcache_invalidate( static::$file );
}
static::$object = NULL;
return false;
}
return true;
}
}
return false;
}
/**
* Return the template object
*
* @throws UnderflowException if the template bit does not exist
* @return boolean
*/
public function get()
{
if ( ! static::$object and ! $this->exists() )
{
throw new \UnderflowException;
}
return static::$object;
}
/**
* Write the template object
* @param string $template PHP $template data to write
*
* @throws RuntimeException If the template bit cannot be written
* @return void
*/
public function set( $template )
{
if ( ! is_writable( \IPS\Settings::i()->theme_disk_cache_path ) )
{
throw new \RuntimeException;
}
@file_put_contents( static::$file, "<?php\n" . $template );
}
}
+17 -10
View File
@@ -2,9 +2,9 @@
/**
* @brief Magic Template Class for IN_DEV mode
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @package IPS Community Suite
* @since 18 Feb 2013
* @version SVN_VERSION_NUMBER
*/
@@ -82,24 +82,31 @@ class _Template extends \IPS\Theme\Template
$file = $this->sourceFolder . $bit . '.phtml';
}
/* Get the content */
/* Get the content or return an BadMethodCallException if the template doesn't exist */
if ( $file === NULL or !file_exists( $file ) )
{
throw new \BadMethodCallException( 'NO_TEMPLATE_FILE - ' . $file );
if ( !$file AND $this->sourceFolder === \IPS\ROOT_PATH . '/plugins' )
{
throw new \BadMethodCallException( 'NO_PLUGIN_TEMPLATE_FILE - ' . $bit );
}
else
{
throw new \BadMethodCallException( 'NO_TEMPLATE_FILE - ' . $file );
}
}
$output = file_get_contents( $file );
/* Parse the header tag */
if ( !preg_match( '/^<ips:template parameters="(.+?)?" \/>(\r\n?|(\r\n?|\n))/', $output, $matches ) )
if ( !preg_match( '/^<ips:template parameters="(.+?)?"(\s+)?\/>(\r\n?|(\r\n?|\n))/', $output, $matches ) )
{
throw new \BadMethodCallException( 'NO_HEADER - ' . $file );
}
/* Strip it */
$output = preg_replace( '/^<ips:template parameters="(.+?)?" \/>(\r\n?|\n)/', '', $output );
if ( \IPS\DEV_DEBUG_TEMPLATES )
$output = preg_replace( '/^<ips:template parameters="(.+?)?"(\s+)?\/>(\r\n?|\n)/', '', $output );
if ( \IPS\DEBUG_TEMPLATES and ! \IPS\Request::i()->isAjax() )
{
$output = "<!-- " . $functionName . " -->" . $output;
}
@@ -125,7 +132,7 @@ class _Template extends \IPS\Theme\Template
$allowedScriptBlocks = array(
'globalTemplate', 'blankTemplate', 'loginTemplate', 'includeJS', 'dashboard',
'onlineUsers', 'registrations', 'viglink', 'linkedin', 'reddit', 'poll',
'giftvoucherPrint', 'packingLabel', 'packingSheet'
'giftvoucherPrint', 'packingLabel', 'packingSheet', 'streamWrapper', 'embedExternal'
);
/* Check we're not being naughty */
@@ -137,7 +144,7 @@ class _Template extends \IPS\Theme\Template
{
// trigger_error( "There is a style block in {$functionName}. Please move all styling into CSS files.", E_USER_ERROR );
}
if( preg_match( "/<.+?\son(blur|change|click|contextmenu|copy|cut|dblclick|error|focus|focusin|focusout|hashchange|keydown|keypress|keyup|load|mousedown|mouseenter|mouseleave|mousemove|mouseout|mouseover|mouseup|mousewheel|paste|reset|resize|scroll|select|submit|textinput|unload|wheel)=['\"].+?>/i", $output ) )
if( preg_match( '/<[^>]+?\son(blur|change|click|contextmenu|copy|cut|dblclick|error|focus|focusin|focusout|hashchange|keydown|keypress|keyup|load|mousedown|mouseenter|mouseleave|mousemove|mouseout|mouseover|mouseup|mousewheel|paste|reset|resize|scroll|select|submit|textinput|unload|wheel)=[\'\"].+?>/i', $output ) )
{
trigger_error( "There is a inline JavaScript {$functionName}. Please move all JavaScript into JS files.", E_USER_ERROR );
}
+15 -19
View File
@@ -2,9 +2,9 @@
/**
* @brief IN_DEV Skin Set
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @package IPS Community Suite
* @since 16 Apr 2013
* @version SVN_VERSION_NUMBER
*/
@@ -126,7 +126,7 @@ class _Theme extends \IPS\Theme
if ( !isset( $this->templates[ $app ][ $location ][ $group ] ) )
{
$class = 'Template';
if ( isset( \IPS\IPS::$hooks[ "\IPS\Theme\class_{$app}_{$location}_{$group}" ] ) )
if ( isset( \IPS\IPS::$hooks[ "\IPS\Theme\class_{$app}_{$location}_{$group}" ] ) AND \IPS\RECOVERY_MODE === FALSE )
{
foreach ( \IPS\IPS::$hooks[ "\IPS\Theme\class_{$app}_{$location}_{$group}" ] as $id => $data )
{
@@ -226,7 +226,7 @@ class _Theme extends \IPS\Theme
{
foreach ( new \GlobIterator( \IPS\ROOT_PATH . '/plugins/' . $plugin->location . '/dev/css/*' ) as $file )
{
$return[] = str_replace( \IPS\ROOT_PATH, rtrim( \IPS\Settings::i()->base_url, '/' ), $file );
$return[] = str_replace( array( 'http://', 'https://' ), '//', \IPS\Settings::i()->base_url ) . "applications/core/interface/css/css.php?css=" . 'plugins/' . $plugin->location . '/dev/css/' . $file->getFilename();
}
}
}
@@ -307,7 +307,7 @@ class _Theme extends \IPS\Theme
* @param string $path Path to resource
* @param string|null $app Application key
* @param string|null $location Location
* @return string URL to resource
* @return \IPS\Http\Url|NULL URL to resource
*/
public function resource( $path, $app=NULL, $location=NULL, $noProtocol=FALSE )
{
@@ -320,10 +320,10 @@ class _Theme extends \IPS\Theme
return \IPS\Settings::i()->base_url . "/applications/{$app}/interface/{$path}";
}
$url = $baseUrl . str_replace( \IPS\ROOT_PATH . '/', '', static::_getResourcePath( $app, $location, $path ) );
if( $noProtocol )
$url = \IPS\Http\Url::createFromString( $baseUrl . str_replace( \IPS\ROOT_PATH . '/', '', static::_getResourcePath( $app, $location, $path ) ), false );
if( $noProtocol and $url instanceof \IPS\Http\Url )
{
$url = str_replace( array( 'http://', 'https://' ), '//', $url );
$url = $url->setScheme(NULL);
}
return $url;
}
@@ -408,7 +408,7 @@ class _Theme extends \IPS\Theme
{
if ( isset( $currentTemplates[ $app ][ $location->getFilename() ][ $group->getFilename() ][ $name ] ) )
{
if ( md5( trim( $currentTemplates[ $app ][ $location->getFilename() ][ $group->getFilename() ][ $name ]['template_content'] ) ) == md5( trim( $html ) ) )
if( \IPS\Login::compareHashes( md5( trim( $html ) ), md5( trim( $currentTemplates[ $app ][ $location->getFilename() ][ $group->getFilename() ][ $name ]['template_content'] ) ) ) )
{
/* No change */
continue;
@@ -585,7 +585,7 @@ class _Theme extends \IPS\Theme
$css = str_replace( '/* No Content */', '', $css );
if ( isset( $currentCss[ $app ][ $location ][ $finalPath ][ $file->getFilename() ] ) )
{
if ( md5( trim( $currentCss[ $app ][ $location ][ $finalPath ][ $file->getFilename() ]['css_content'] ) ) == md5( trim( $css ) ) )
if( \IPS\Login::compareHashes( md5( trim( $css ) ), md5( trim( $currentCss[ $app ][ $location ][ $finalPath ][ $file->getFilename() ]['css_content'] ) ) ) )
{
/* No change */
continue;
@@ -720,7 +720,7 @@ class _Theme extends \IPS\Theme
/* files larger than 1.5mb don't base64_encode() as they may not get stored in the resources_data column */
if ( filesize( $root . $path . $file->getFilename() ) > ( 1.5 * 1024 * 1024 ) )
{
\IPS\Log::i( LOG_INFO )->write( $root . $path . $file->getFilename() . " too large to import", 'designers_mode_import' );
\IPS\Log::log( $root . $path . $file->getFilename() . " too large to import", 'designers_mode_import' );
continue;
}
@@ -728,7 +728,7 @@ class _Theme extends \IPS\Theme
if ( ! base64_encode( $content ) )
{
\IPS\Log::i( LOG_INFO )->write( $root . $path . $file->getFilename() . " could not be saved correctly", 'designers_mode_import' );
\IPS\Log::log( $root . $path . $file->getFilename() . " could not be saved correctly", 'designers_mode_import' );
continue;
}
@@ -736,7 +736,7 @@ class _Theme extends \IPS\Theme
$name = self::makeBuiltTemplateLookupHash($app, $location, $path) . '_' . $file->getFilename();
$fileName = (string) \IPS\File::create( 'core_Theme', $name, $content, 'set_resources_' . ( $id == 0 ? 1 : $id ) );
if ( ! isset( $master[ $file->getFilename() ] ) or $master[ $file->getFilename() ] != md5( $content ) )
if ( ! isset( $master[ $file->getFilename() ] ) or !\IPS\Login::compareHashes( md5( $content ), $master[ $file->getFilename() ] ) )
{
$custom = 1;
}
@@ -1086,14 +1086,11 @@ class _Theme extends \IPS\Theme
\IPS\Db::i()->select(
'sv.*, core_theme_settings_fields.*',
'core_theme_settings_fields',
array( 'sc_set_id=?', 1 ),
NULL,
NULL,
'sc_key'
array( 'sc_set_id=?', 1 )
)->join(
array('core_theme_settings_values', 'sv'),
'sv.sv_id=core_theme_settings_fields.sc_id'
) as $row
)->setKeyField('sc_key') as $row
)
{
$row['sc_default'] = ( $row['sv_value'] ) ? $row['sv_value'] : $row['sc_default'];
@@ -1102,7 +1099,6 @@ class _Theme extends \IPS\Theme
$data[ $row['sc_app'] ][] = $row;
}
foreach( $data as $app => $json )
{
$file = \IPS\ROOT_PATH . "/applications/{$app}/data/themesettings.json";
+6 -4
View File
@@ -2,9 +2,9 @@
/**
* @brief Sameboxed Template
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @package IPS Community Suite
* @since 18 Feb 2013
* @version SVN_VERSION_NUMBER
*/
@@ -26,7 +26,7 @@ class _SandboxedTemplate
/**
* @brief Template
*/
protected $template;
public $template;
/**
* Contructor
@@ -54,10 +54,12 @@ class _SandboxedTemplate
{
try
{
return call_user_func_array( array( $this->template, $name ), $args );
return $this->template->$name( ...$args );
}
catch ( \ErrorException $e )
{
\IPS\Log::log( $e, 'template_error' );
return "<span style='background:black;color:white;padding:6px;'>[[Template {$this->template->app}/{$this->template->templateLocation}/{$this->template->templateName}/{$name} is throwing an error. This theme may be out of date. Run the support tool in the AdminCP to restore the default theme.]]</span>";
}
}
+2 -2
View File
@@ -2,9 +2,9 @@
/**
* @brief Setup Skin Set
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @package IPS Community Suite
* @since 25 Jun 2013
* @version SVN_VERSION_NUMBER
*/
+2 -2
View File
@@ -2,9 +2,9 @@
/**
* @brief Magic Template Class for BASIC mode
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @package IPS Community Suite
* @since 17 Oct 2013
* @version SVN_VERSION_NUMBER
*/
+2 -2
View File
@@ -2,9 +2,9 @@
/**
* @brief Basic template support
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @package IPS Community Suite
* @since 25 Jun 2013
* @version SVN_VERSION_NUMBER
*/
+2 -2
View File
@@ -2,9 +2,9 @@
/**
* @brief Template Class
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @package IPS Community Suite
* @since 18 Feb 2013
* @version SVN_VERSION_NUMBER
*/
+601 -232
View File
File diff suppressed because it is too large. Load diff