<?php
/**
* This file implements the UI controller for skins management.
*
* b2evolution - {@link http://b2evolution.net/}
*
* @license GNU GPL v2 - {@link http://b2evolution.net/about/gnu-gpl-license}
*
* @copyright (c)2003-2020 by Francois Planque - {@link http://fplanque.com/}
* Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.
*
* Released under GNU GPL License - {@link http://b2evolution.net/about/gnu-gpl-license}
*
* @package admin
*/
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
load_funcs( 'skins/_skin.funcs.php' );
param( 'action', 'string', 'list' );
param( 'tab', 'string', 'manage_skins', true );
param( 'skin_type', 'string', '' );
if( $action != 'reset_coll' )
{ // Check permission to display site options:
// (exception for reset collection skin settings where we should check permission to edit collection properties)
check_user_perm( 'options', 'view', true );
}
if( $tab == 'system' )
{ // Check minimum permission:
check_user_perm( 'admin', 'normal', true );
}
param( 'redirect_to', 'url', $admin_url.'?ctrl=skins&tab='.$tab.( isset( $blog ) ? '&blog='.$blog : '' ) );
if( $tab != 'system' && $tab != 'site_skin' )
{ // Memorize this as the last "tab" used in the Blog Settings:
$UserSettings->set( 'pref_coll_settings_tab', $tab );
$UserSettings->dbupdate();
}
if( param( 'skin_ID', 'integer', '', true ) )
{// Load file type:
$SkinCache = & get_SkinCache();
if( ($edited_Skin = & $SkinCache->get_by_ID( $skin_ID, false )) === false )
{ // We could not find the skin to edit:
unset( $edited_Skin );
forget_param( 'skin_ID' );
$Messages->head = TB_('Cannot edit skin!');
$Messages->add( TB_('Requested skin is not installed any longer.'), 'error' );
$action = 'nil';
}
}
/**
* Perform action:
*/
switch( $action )
{
case 'create':
param( 'skin_folder', 'string', true );
// Check validity of requested skin name:
if( preg_match( '~([^-A-Za-z0-9._]|\.\.)~', $skin_folder ) )
{
debug_die( 'The requested skin name is invalid.' );
}
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'skin' );
// Check permission to edit:
check_user_perm( 'options', 'edit', true );
// CREATE NEW SKIN:
$edited_Skin = & skin_install( $skin_folder );
$Messages->add( TB_('Skin has been installed.'), 'success' );
if( $tab == 'coll_skin' && ! empty( $blog ) )
{ // We installed the skin for the selected collection:
$BlogCache = & get_BlogCache();
$edited_Blog = & $BlogCache->get_by_ID( $blog );
if( ! skin_check_compatibility( $edited_Skin->ID, 'coll' ) )
{ // Redirect to admin skins page selector if the skin cannot be selected:
$Messages->add( TB_('The skin cannot be used for collections.'), 'error' );
header_redirect( $admin_url.'?ctrl=coll_settings&tab=skin&blog='.$edited_Blog->ID.'&skinpage=selection&skin_type='.$edited_Skin->type );
break;
}
// Set new installed skins for the selected collection:
$edited_Blog->set( $skin_type.'_skin_ID', $edited_Skin->ID );
$edited_Blog->dbupdate();
if( param( 'reset_widgets', 'integer', 0 ) )
{ // Reset previous widgets with new from skin default widget declarations:
$edited_Blog->reset_widgets( $skin_type );
}
$Messages->add( TB_('The blog skin has been changed.')
.' <a href="'.$admin_url.'?ctrl=coll_settings&tab=skin&blog='.$edited_Blog->ID.'">'.TB_('Edit...').'</a>', 'success' );
if( ( ! $Session->is_mobile_session() && ! $Session->is_tablet_session() && ! $Session->is_alt_session() && $skin_type == 'normal' ) ||
( $Session->is_mobile_session() && $skin_type == 'mobile' ) ||
( $Session->is_tablet_session() && $skin_type == 'tablet' ) ||
( $Session->is_alt_session() && $skin_type == 'alt' ) )
{ // Redirect to blog home page if we change the skin for current device type:
header_redirect( $edited_Blog->gen_blogurl() );
}
else
{ // Redirect to admin skins page if we change the skin for another device type:
header_redirect( $admin_url.'?ctrl=coll_settings&tab=skin&blog='.$edited_Blog->ID.'&skin_type='.$skin_type );
}
}
elseif( $tab == 'site_skin' )
{ // We installed the skin for the site:
if( ! skin_check_compatibility( $edited_Skin->ID, 'site' ) )
{ // Redirect to admin skins page selector if the skin cannot be selected:
$Messages->add( TB_('This skin cannot be used as a site skin.'), 'error' );
header_redirect( $admin_url.'?ctrl=collections&tab=site_skin&skinpage=selection'.( !empty( $skin_type ) ? '&skin_type='.$skin_type : '' ) );
break;
}
if( ! empty( $skin_type ) )
{
$Settings->set( $skin_type.'_skin_ID', $edited_Skin->ID );
if( $Settings->dbupdate() )
{
$Messages->add( TB_('The site skin has been changed.')
.' <a href="'.$admin_url.'?ctrl=collections&tab=site_skin">'.TB_('Edit...').'</a>', 'success' );
if( ( ! $Session->is_mobile_session() && ! $Session->is_tablet_session() && ! $Session->is_alt_session() && $skin_type == 'normal' ) ||
( $Session->is_mobile_session() && $skin_type == 'mobile' ) ||
( $Session->is_tablet_session() && $skin_type == 'tablet' ) ||
( $Session->is_alt_session() && $skin_type == 'alt' ) )
{ // Redirect to home page if we change the skin for current device type:
header_redirect( $baseurl );
}
else
{ // Redirect to admin skins page if we change the skin for another device type:
header_redirect( $admin_url.'?ctrl=collections&tab=site_skin&skin_type='.$skin_type );
}
}
}
else
{ // Redirect to admin skins page if we installed a site skin for an unknown device:
header_redirect( $admin_url.'?ctrl=skins&tab=site_skin' );
}
}
else
{
// We want to highlight the edited object on next list display:
$Session->set( 'fadeout_array', array( 'skin_ID' => array( $edited_Skin->ID ) ) );
// Replace a mask by value. Used for install skin on creating of new blog
$redirect_to = str_replace( '$skin_ID$', $edited_Skin->ID, $redirect_to );
}
// PREVENT RELOAD & Switch to list mode:
header_redirect( $redirect_to );
break;
case 'upgrade':
case 'downgrade':
param( 'skin_folder', 'string', true );
// Check validity of requested skin name:
if( preg_match( '~([^-A-Za-z0-9._]|\.\.)~', $skin_folder ) )
{
debug_die( 'The requested skin name is invalid.' );
}
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'skin' );
// Check permission to edit:
check_user_perm( 'options', 'edit', true );
$SkinCache = & get_SkinCache();
$new_Skin = & $SkinCache->new_obj( NULL, $skin_folder );
$edited_Skin = & $SkinCache->get_by_class( $new_Skin->class );
$edited_Skin->set( 'folder', $new_Skin->folder );
$edited_Skin->dbupdate();
if( $action == 'upgrade' )
{
$Messages->add( TB_('Skin has been upgraded to a later version.'), 'success' );
}
else
{
$Messages->add( TB_('Skin has been downgraded to an earlier version.'), 'success' );
}
$new_installed_skin_IDs = array( $edited_Skin->ID );
// We want to highlight the edited object on next list display:
$Session->set( 'fadeout_array', array( 'skin_ID' => $new_installed_skin_IDs ) );
// PREVENT RELOAD & Switch to list mode:
header_redirect( $redirect_to );
break;
case 'install':
// Install several skins
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'skin' );
// Check permission to edit:
check_user_perm( 'options', 'edit', true );
param( 'skin_folders', 'array:/([-A-Za-z0-9._]|\.\.)/', array() );
if( empty( $skin_folders ) )
{ // No selected skins
$Messages->add( TB_('Please select at least one skin to install.'), 'error' );
header_redirect( $admin_url.'?ctrl=skins&action=new' );
}
$new_installed_skin_IDs = array();
foreach( $skin_folders as $skin_folder )
{ // CREATE NEW SKIN:
$edited_Skin = & skin_install( $skin_folder );
$new_installed_skin_IDs[] = $edited_Skin->ID;
}
$Messages->add( TB_('The selected skins have been installed.'), 'success' );
// We want to highlight the edited object on next list display:
$Session->set( 'fadeout_array', array( 'skin_ID' => $new_installed_skin_IDs ) );
// PREVENT RELOAD & Switch to list mode:
header_redirect( $redirect_to );
break;
case 'update':
// Update skin properties:
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'skin' );
// Check permission:
check_user_perm( 'options', 'edit', true );
// Make sure we got an skin_ID:
param( 'skin_ID', 'integer', true );
// load data from request
if( $edited_Skin->load_from_Request() )
{ // We could load data from form without errors:
// Update in DB:
$edited_Skin->dbupdate();
$Messages->add( TB_('Skin properties updated.'), 'success' );
// We want to highlight the edited object on next list display:
$Session->set( 'fadeout_array', array( 'skin_ID' => array($edited_Skin->ID) ) );
// Redirect so that a reload doesn't write to the DB twice:
header_redirect( $redirect_to, 303 ); // Will EXIT
// We have EXITed already at this point!!
}
break;
case 'delete':
// Uninstall a skin:
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'skin' );
// Check permission:
check_user_perm( 'options', 'edit', true );
// Make sure we got an skin_ID:
param( 'skin_ID', 'integer', true );
if( param( 'confirm', 'integer', 0 ) )
{ // confirmed, Delete from DB:
$msg = sprintf( TB_('Skin «%s» uninstalled.'), $edited_Skin->dget('name') );
$edited_Skin->dbdelete();
//unset( $edited_Skin );
//forget_param( 'skin_ID' );
$Messages->add( $msg, 'success' );
// Redirect so that a reload doesn't write to the DB twice:
header_redirect( $redirect_to, 303 ); // Will EXIT
// We have EXITed already at this point!!
}
else
{ // not confirmed, Check for restrictions:
if( ! $edited_Skin->check_delete( sprintf( TB_('Cannot uninstall skin «%s»'), $edited_Skin->dget('name') ) ) )
{ // There are restrictions:
$action = 'edit';
}
}
break;
case 'reset_site':
case 'reset_coll':
// Reset site/collection settings to default values:
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'skin' );
// Make sure we got skin and blog IDs:
param( 'skin_ID', 'integer', true );
param( 'blog', 'integer', true );
if( $action == 'reset_coll' )
{ // Collection skin:
// Check permission:
check_user_perm( 'blog_properties', 'edit', true, $blog );
// At some point we may want to remove skin settings from all blogs
$DB->query( 'DELETE FROM T_coll_settings
WHERE cset_coll_ID = '.$DB->quote( $blog ).'
AND cset_name REGEXP "^skin'.$skin_ID.'_"' );
$redirect_to = $admin_url.'?ctrl=coll_settings&tab=skin&blog='.$blog.'&skin_type='.$skin_type.( empty( $mode ) ? '' : '&mode='.$mode );
}
else
{ // Site skin:
// Check permission:
check_user_perm( 'options', 'edit', true );
// At some point we may want to remove skin settings from all blogs
$DB->query( 'DELETE FROM T_settings
WHERE set_name REGEXP "^skin'.$skin_ID.'_"' );
$redirect_to = $admin_url.'?ctrl=collections&tab=site_skin&skin_type='.$skin_type.( empty( $mode ) ? '' : '&mode='.$mode );
}
$Messages->add( TB_('Skin params have been reset to defaults.'), 'success' );
// Redirect so that a reload doesn't write to the DB twice:
header_redirect( $redirect_to ); // Will EXIT
// We have EXITed already at this point!!
break;
}
if( $tab == 'system' )
{ // From System tab:
$AdminUI->set_path( 'options', 'skins' );
$AdminUI->breadcrumbpath_init( false );
$AdminUI->breadcrumbpath_add( TB_('System'), $admin_url.'?ctrl=system',
TB_('Global settings are shared between all blogs; see Blog settings for more granular settings.') );
$AdminUI->breadcrumbpath_add( TB_('Skins'), $admin_url.'?ctrl=skins' );
}
elseif( $tab == 'site_skin' )
{ // From Site Skin tab:
$AdminUI->set_path( 'site', 'skin', 'manage_skins' );
$AdminUI->breadcrumbpath_init( false );
$AdminUI->breadcrumbpath_add( TB_('Site'), $admin_url.'?ctrl=dashboard' );
$AdminUI->breadcrumbpath_add( TB_('Site skin'), $admin_url.'?ctrl=collections&tab=site_skin' );
$AdminUI->breadcrumbpath_add( TB_('Manage skins'), $admin_url.'?ctrl=skins&tab=site_skin' );
}
else
{ // From Blog settings:
// We should activate toolbar menu items for this controller and tab
$activate_collection_toolbar = true;
$AdminUI->set_path( 'collections', 'skin', empty( $skin_type ) ? $tab : 'skin_'.$skin_type );
/**
* Display page header, menus & messages:
*/
$AdminUI->set_coll_list_params( 'blog_properties', 'edit', array( 'ctrl' => 'coll_settings', 'tab' => 'skin' ) );
$AdminUI->breadcrumbpath_init( true, array( 'text' => TB_('Collections'), 'url' => $admin_url.'?ctrl=collections' ) );
$AdminUI->breadcrumbpath_add( TB_('Skin'), $admin_url.'?ctrl=coll_settings&tab=skin&blog=$blog$' );
$AdminUI->breadcrumbpath_add( TB_('Manage skins'), $admin_url.'?ctrl=skins' );
}
// Set an url for manual page:
switch( $action )
{
case 'delete':
case 'edit':
case 'update':
$AdminUI->set_page_manual_link( 'skin-system-settings' );
break;
default:
$AdminUI->set_page_manual_link( 'manage-skins' );
break;
}
// Display <html><head>...</head> section! (Note: should be done early if actions do not redirect)
$AdminUI->disp_html_head();
// Display title, menu, messages, etc. (Note: messages MUST be displayed AFTER the actions)
$AdminUI->disp_body_top();
// Begin payload block:
$AdminUI->disp_payload_begin();
/**
* Display Payload:
*/
switch( $action )
{
case 'new':
// Display VIEW:
$AdminUI->disp_view( 'skins/views/_skin_list_available.view.php' );
break;
case 'delete':
// We need to ask for confirmation:
$edited_Skin->confirm_delete(
sprintf( TB_('Uninstall skin «%s»?'), $edited_Skin->dget( 'name' ) ),
'skin', $action, get_memorized( 'action' ) );
case 'edit':
case 'update': // we return in this state after a validation error
// Display VIEW:
$AdminUI->disp_view( 'skins/views/_skin.form.php' );
break;
case 'list':
// Display VIEW:
$AdminUI->disp_view( 'skins/views/_skin_list.view.php' );
break;
}
// End payload block:
$AdminUI->disp_payload_end();
// Display body bottom, debug info and close </html>:
$AdminUI->disp_global_footer();
?>