Version 4.7.0
This commit is contained in:
1 parent
517a5e1f70
commit
8ba7d43898
1933 files changed
+65613
-11332
No files matched your search
+207
-31
@@ -273,9 +273,8 @@ class _Theme extends \IPS\Node\Model
|
||||
if ( static::$inDevTheme === NULL )
|
||||
{
|
||||
static::$inDevTheme = new \IPS\Theme\Dev\Theme;
|
||||
|
||||
static::themes();
|
||||
|
||||
|
||||
/* Add in the default theme properties (_data array, etc) */
|
||||
$default = ( isset( static::$multitons[ \IPS\DEFAULT_THEME_ID ] ) ) ? static::$multitons[ \IPS\DEFAULT_THEME_ID ] : reset( static::$multitons );
|
||||
|
||||
@@ -283,6 +282,12 @@ class _Theme extends \IPS\Node\Model
|
||||
{
|
||||
static::$inDevTheme->$k = $v;
|
||||
}
|
||||
|
||||
if ( static::isUsingEasyModeEditor() )
|
||||
{
|
||||
$setId = \intval( \IPS\Request::i()->cookie['vseThemeId'] );
|
||||
static::$memberTheme = empty( $setId ) ? static::defaultTheme() : static::load( $setId );
|
||||
}
|
||||
}
|
||||
|
||||
return static::$inDevTheme;
|
||||
@@ -354,7 +359,7 @@ class _Theme extends \IPS\Node\Model
|
||||
$setId = static::defaultTheme();
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Request::i()->cookie['vseThemeId'] ) AND \IPS\Member::loggedIn()->isAdmin() AND \IPS\Member::loggedIn()->members_bitoptions['bw_using_skin_gen'] )
|
||||
if ( static::isUsingEasyModeEditor() )
|
||||
{
|
||||
$setId = \intval( \IPS\Request::i()->cookie['vseThemeId'] );
|
||||
|
||||
@@ -455,22 +460,42 @@ class _Theme extends \IPS\Node\Model
|
||||
/**
|
||||
* Returns only the visible themes for the member
|
||||
*
|
||||
* @return array|bool
|
||||
* @return array
|
||||
*/
|
||||
public static function getThemesWithAccessPermission()
|
||||
{
|
||||
$visibleThemes = array();
|
||||
|
||||
foreach ( static::themes() AS $themeId => $theme )
|
||||
foreach( \IPS\Theme::roots() as $theme )
|
||||
{
|
||||
if ( $theme->canAccess() )
|
||||
{
|
||||
$visibleThemes[$theme->id] = $theme;
|
||||
}
|
||||
|
||||
static::getChildrenWithAccessPermission( $theme, $visibleThemes );
|
||||
}
|
||||
|
||||
return $visibleThemes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns only the visible children
|
||||
* @param \IPS\Theme $theme Parent theme
|
||||
* @param Array $visibleThemes Visible themes array passed by reference
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function getChildrenWithAccessPermission( \IPS\Theme $theme, Array &$visibleThemes )
|
||||
{
|
||||
foreach ( $theme->children() as $child )
|
||||
{
|
||||
if( $child->canAccess() )
|
||||
{
|
||||
$visibleThemes[ $child->id ] = $child;
|
||||
static::getChildrenWithAccessPermission( $child, $visibleThemes );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the master theme object
|
||||
@@ -1055,6 +1080,43 @@ class _Theme extends \IPS\Node\Model
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add in the header and footer special tags if they are not already present in globalTemplate
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function fixHeaderAndFooterTags()
|
||||
{
|
||||
/* Check the globalTemplate for the special tags we need */
|
||||
try
|
||||
{
|
||||
$template = \IPS\Db::i()->select( '*', 'core_theme_templates', [ 'template_set_id=? AND template_app=? AND template_group=? AND template_location=? and template_name=?', $this->_id, 'core', 'global', 'front', 'globalTemplate'] )->first();
|
||||
$update = FALSE;
|
||||
|
||||
if ( ! \stristr( $template['template_content'], '{theme="headerHtml"}') )
|
||||
{
|
||||
$template['template_content'] = preg_replace( '#(<body.*>\n)#i', "$1\n{theme=\"headerHtml\"}\n", $template['template_content'] );
|
||||
$update = TRUE;
|
||||
}
|
||||
|
||||
if ( ! \stristr( $template['template_content'], '{theme="footerHtml"}') )
|
||||
{
|
||||
$template['template_content'] = preg_replace( '#(</body>\n)#i', "{theme=\"footerHtml\"}\n$1", $template['template_content'] );
|
||||
$update = TRUE;
|
||||
}
|
||||
|
||||
if ( $update )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_theme_templates', [ 'template_content' => $template['template_content'] ], [ 'template_id=?', $template['template_id'] ] );
|
||||
}
|
||||
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
/* No custom template, so we're good */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save Changed Columns
|
||||
@@ -1073,7 +1135,22 @@ class _Theme extends \IPS\Node\Model
|
||||
|
||||
parent::save();
|
||||
unset( \IPS\Data\Store::i()->themes );
|
||||
|
||||
|
||||
/* If we are using a customized globalTemplate, we need to slap in the header/footer tags */
|
||||
if ( ! empty( $this->custom_footer ) or ! empty( $this->customer_header ) )
|
||||
{
|
||||
$this->fixHeaderAndFooterTags();
|
||||
}
|
||||
|
||||
foreach( [ 'header', 'footer' ] as $type )
|
||||
{
|
||||
$key = 'custom_' . $type . '_' . $this->_id;
|
||||
if ( isset( \IPS\Data\Store::i()->$key ) )
|
||||
{
|
||||
unset( \IPS\Data\Store::i()->$key );
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset map arrays */
|
||||
if ( !isset( $this->_data['resource_map'] ) OR ! \is_array( $this->_data['resource_map'] ) )
|
||||
{
|
||||
@@ -1668,7 +1745,11 @@ class _Theme extends \IPS\Node\Model
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'core_theme_set_editor_new', NULL, FALSE, array( 'allowedFileTypes' => array( 'zip' ), 'temporary' => TRUE ), NULL, NULL, NULL, 'core_theme_set_editor_new' ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$form->addTab('core_theme_set_header_and_footer_header');
|
||||
$form->add( new \IPS\Helpers\Form\Codemirror( 'theme_simple_header_settings', $this->custom_header, FALSE, [ 'mode' => 'htmlmixed', 'height' => 400 ] ) );
|
||||
$form->add( new \IPS\Helpers\Form\Codemirror( 'theme_simple_footer_settings', $this->custom_footer, FALSE, [ 'mode' => 'htmlmixed', 'height' => 400 ] ) );
|
||||
|
||||
/* THEME SETTINGS */
|
||||
if ( $this->id )
|
||||
{
|
||||
@@ -2199,6 +2280,16 @@ class _Theme extends \IPS\Node\Model
|
||||
$this->parent_id = ( $values['core_theme_parent_id'] instanceof \IPS\Theme ) ? $values['core_theme_parent_id']->id : 0;
|
||||
$this->css_updated = time();
|
||||
|
||||
if ( isset( $values['theme_simple_header_settings'] ) )
|
||||
{
|
||||
$this->custom_header = $values['theme_simple_header_settings'];
|
||||
}
|
||||
|
||||
if ( isset( $values['theme_simple_footer_settings'] ) )
|
||||
{
|
||||
$this->custom_footer = $values['theme_simple_footer_settings'];
|
||||
}
|
||||
|
||||
$this->save();
|
||||
|
||||
if ( $creating === TRUE AND $this->id )
|
||||
@@ -2942,11 +3033,11 @@ EOF;
|
||||
}
|
||||
else
|
||||
{
|
||||
# Remove it from ALL template sets
|
||||
# Remove it from the theme set and any children
|
||||
\IPS\Db::i()->delete( 'core_theme_templates', array(
|
||||
"template_name=? AND template_group=? AND template_app=? AND template_location=?",
|
||||
$template['template_name'], $template['template_group'], $template['template_app'], $template['template_location']
|
||||
) );
|
||||
"template_name=? AND template_group=? AND template_app=? AND template_location=? AND " . \IPS\Db::i()->in( 'template_set_id', $children ),
|
||||
$template['template_name'], $template['template_group'], $template['template_app'], $template['template_location']
|
||||
) );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -3203,7 +3294,41 @@ EOF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get theme header and footer
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaderAndFooter(): array
|
||||
{
|
||||
$return = [ 'header' => null, 'footer' => null ];
|
||||
|
||||
if ( $this->custom_header )
|
||||
{
|
||||
$key = 'custom_header_' . $this->_id;
|
||||
if ( ! isset( \IPS\Data\Store::i()->$key ) )
|
||||
{
|
||||
\IPS\Data\Store::i()->$key = static::compileTemplate( $this->custom_header, NULL );
|
||||
}
|
||||
|
||||
$return['header'] = \IPS\Data\Store::i()->$key;
|
||||
}
|
||||
|
||||
if ( $this->custom_footer )
|
||||
{
|
||||
$key = 'custom_footer_' . $this->_id;
|
||||
if ( ! isset( \IPS\Data\Store::i()->$key ) )
|
||||
{
|
||||
\IPS\Data\Store::i()->$key = static::compileTemplate( $this->custom_footer, NULL );
|
||||
}
|
||||
|
||||
$return['footer'] = \IPS\Data\Store::i()->$key;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get raw CSS. Raw means {resource..} tags and uncompiled
|
||||
*
|
||||
@@ -4383,25 +4508,25 @@ EOF;
|
||||
{
|
||||
$return = preg_replace( '#' . $matches[1] . '="json--' . $id . '--"#', $matches[0], $return );
|
||||
}
|
||||
|
||||
|
||||
/* Fix ---cln--- classes */
|
||||
preg_match_all( '#class\s?=\s?[\'"]([^\'"]+?)[\'"]#', $return, $classes, PREG_SET_ORDER );
|
||||
|
||||
foreach( $classes as $idx => $data )
|
||||
{
|
||||
$return = str_replace( $data[1], str_replace( '---cln---', ':', $data[1] ), $return );
|
||||
}
|
||||
|
||||
/* Put our {{PHP code}} back */
|
||||
$return = preg_replace_callback( '/he-(.+?)--/', function( $matches ) use ( $phpQueryStore )
|
||||
{
|
||||
return isset( $phpQueryStore[ $matches[1] ] ) ? $phpQueryStore[ $matches[1] ] : '';
|
||||
}, $return );
|
||||
|
||||
/* Fix ---cln--- classes */
|
||||
preg_match_all( '#class\s?=\s?[\'"]([^\'"]+?)[\'"]#', $return, $classes, PREG_SET_ORDER );
|
||||
|
||||
foreach( $classes as $idx => $data )
|
||||
{
|
||||
$return = str_replace( $data[1], str_replace( '---cln---', ':', $data[1] ), $return );
|
||||
}
|
||||
|
||||
/* Swap back certain tags that confuse phpQuery */
|
||||
$return = preg_replace( '/<(\/)?temp(html|head|body)(.*?)>/', '<$1$2$3>', $return );
|
||||
$return = str_replace( '<tempdoctype></tempdoctype>', '<!DOCTYPE html>', $return );
|
||||
|
||||
|
||||
/* Return */
|
||||
return $return;
|
||||
}
|
||||
@@ -4543,7 +4668,7 @@ EOF;
|
||||
* Process template into executable code.
|
||||
*
|
||||
* @param string $content Content with variables and parse tags
|
||||
* @param string $functionName Desired function name
|
||||
* @param string|NULL $functionName Desired function name if given, otherwise <<<CONTENT CONTENT; is returned without a function wrapper or $return .= statement
|
||||
* @param string $params Parameter list
|
||||
* @param bool $isHTML If TRUE, HTML will automatically be escaped
|
||||
* @param bool $isCSS If TRUE, the plugins will be checked for $canBeUsedInCss
|
||||
@@ -4624,7 +4749,17 @@ PHP;
|
||||
}
|
||||
else
|
||||
{
|
||||
$function = <<<PHP
|
||||
if ( ! $functionName )
|
||||
{
|
||||
$function = <<<PHP
|
||||
<<<CONTENT\n
|
||||
{$content}
|
||||
CONTENT;\n
|
||||
PHP;
|
||||
}
|
||||
else
|
||||
{
|
||||
$function = <<<PHP
|
||||
function {$functionName}( {$params} ) {
|
||||
\$return = '';
|
||||
\$return .= <<<CONTENT\n
|
||||
@@ -4633,6 +4768,7 @@ CONTENT;\n
|
||||
return \$return;
|
||||
}
|
||||
PHP;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse {plugin="foo"} tags */
|
||||
@@ -5499,12 +5635,7 @@ PHP;
|
||||
public static function isUsingTemplateDiskCache()
|
||||
{
|
||||
if ( \IPS\CIC and ! \IPS\Settings::i()->theme_disk_cache_templates )
|
||||
{
|
||||
if ( \IPS\CIC2 )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
{
|
||||
\IPS\Settings::i()->theme_disk_cache_templates = 1;
|
||||
\IPS\Settings::i()->theme_disk_cache_path = \IPS\ROOT_PATH . '/uploads';
|
||||
}
|
||||
@@ -5556,5 +5687,50 @@ PHP;
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_cache', array( 'cache_key=?', 'locking_' . $key ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Are we actively editing an easy mode theme?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isUsingEasyModeEditor(): bool
|
||||
{
|
||||
return isset( \IPS\Request::i()->cookie['vseThemeId'] ) AND \IPS\Member::loggedIn()->isAdmin() AND \IPS\Member::loggedIn()->members_bitoptions['bw_using_skin_gen'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre output handling for easy mode theme if actively used
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function easyModePreOutput()
|
||||
{
|
||||
/* We are using the easy mode editor, and we're a logged in admin and the theme is an easy mode theme */
|
||||
if ( static::isUsingEasyModeEditor() and static::$memberTheme->by_skin_gen )
|
||||
{
|
||||
$storage = \IPS\File::getClass( 'core_Theme' );
|
||||
$baseUrl = parse_url( \IPS\Http\Url::internal('') );
|
||||
$storageUrl = parse_url( $storage->baseUrl() );
|
||||
|
||||
/* is it a different host? */
|
||||
if ( $storageUrl['host'] != $baseUrl['host'] )
|
||||
{
|
||||
$cssFiles = [];
|
||||
foreach( \IPS\Output::i()->cssFiles as $css )
|
||||
{
|
||||
if ( $css->data['host'] == $storageUrl['host'] )
|
||||
{
|
||||
$cssFiles[] = \IPS\Http\Url::internal('app=core&module=system&controller=easymode&do=proxy')->setQueryString( [ 'f' => base64_encode( (string) $css ) ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
$cssFiles[] = $css;
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->cssFiles = $cssFiles;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user