From f59f3032c61bdda45181866636ddceed6fd062b8 Mon Sep 17 00:00:00 2001
From: Laurent Destailleur <eldy@destailleur.fr>
Date: Sun, 1 May 2016 16:34:50 +0200
Subject: [PATCH] NEW: Rename path for generic medias files into '/medias'
 instead of fckeditor. Add location of medias into title of media browser of
 ckeditor. Work on website module

---
 htdocs/core/class/doleditor.class.php         |   2 +-
 .../browser/default/browser.php               |  11 +-
 .../filemanagerdol/connectors/php/config.php  |   7 +-
 .../filemanagerdol/connectors/php/upload.php  |   2 +-
 htdocs/core/lib/files.lib.php                 |  16 +-
 htdocs/core/modules/modFckeditor.class.php    |   4 +-
 htdocs/core/modules/modWebsites.class.php     |   6 +-
 htdocs/document.php                           |   6 +-
 htdocs/install/upgrade2.php                   |   2 +
 htdocs/langs/en_US/main.lang                  |   1 +
 htdocs/langs/en_US/website.lang               |   6 +-
 htdocs/main.inc.php                           |   2 +-
 htdocs/public/websites/index.php              |  90 ++++++-
 htdocs/theme/eldy/ckeditor/config.js          |   2 -
 htdocs/theme/eldy/style.css.php               |   6 +-
 htdocs/theme/md/ckeditor/config.js            |   2 -
 htdocs/theme/md/style.css.php                 |   6 +-
 htdocs/viewimage.php                          |   4 +-
 htdocs/websites/index.php                     | 236 ++++++++++++++++--
 19 files changed, 353 insertions(+), 58 deletions(-)

diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php
index 8564a18822e..2a9114cbd2c 100644
--- a/htdocs/core/class/doleditor.class.php
+++ b/htdocs/core/class/doleditor.class.php
@@ -52,7 +52,7 @@ class DolEditor
      *      @param 	string	$content		        Content of WYSIWIG field
      *      @param	int		$width					Width in pixel of edit area (auto by default)
      *      @param 	int		$height			        Height in pixel of edit area (200px by default)
-     *      @param 	string	$toolbarname	        Name of bar set to use ('Full', 'dolibarr_notes[_encoded]', 'dolibarr_details[_encoded]'=the less featured, 'dolibarr_mailings[_encoded]', ')
+     *      @param 	string	$toolbarname	        Name of bar set to use ('Full', 'dolibarr_notes[_encoded]', 'dolibarr_details[_encoded]'=the less featured, 'dolibarr_mailings[_encoded]', 'dolibarr_readonly')
      *      @param  string	$toolbarlocation       	Where bar is stored :
      *                       		             	'In' each window has its own toolbar
      *                              		      	'Out:name' share toolbar into the div called 'name'
diff --git a/htdocs/core/filemanagerdol/browser/default/browser.php b/htdocs/core/filemanagerdol/browser/default/browser.php
index f542bdf59b6..15e44621bcf 100644
--- a/htdocs/core/filemanagerdol/browser/default/browser.php
+++ b/htdocs/core/filemanagerdol/browser/default/browser.php
@@ -19,15 +19,20 @@
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-define('NOTOKENRENEWAL',1); // Disables token renewal
+//define('NOTOKENRENEWAL',1); // Disables token renewal
+//require '../../../../main.inc.php';
+require '../../connectors/php/config.php';      // This include the define('NOTOKENRENEWAL',1) and the require main.in.php
+
+global $Config;
+
+
 
-require '../../../../main.inc.php';
 ?>
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
    "http://www.w3.org/TR/html4/frameset.dtd">
 <html>
 	<head>
-		<title>FCKeditor - Resources Browser</title>
+		<title><?php echo $langs->trans("MediaBrowser").' - '.$Config['UserFilesAbsolutePathRelative']; ?></title>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 		<script type="text/javascript" src="js/fckxml.js"></script>
 		<script type="text/javascript">
diff --git a/htdocs/core/filemanagerdol/connectors/php/config.php b/htdocs/core/filemanagerdol/connectors/php/config.php
index 0c3b0a4884c..7b5bea4e97b 100644
--- a/htdocs/core/filemanagerdol/connectors/php/config.php
+++ b/htdocs/core/filemanagerdol/connectors/php/config.php
@@ -23,6 +23,7 @@
  */
 
 global $Config ;
+global $website;
 
 define('NOTOKENRENEWAL',1); // Disables token renewal
 
@@ -44,13 +45,15 @@ $Config['Enabled'] = true ;
 
 
 // Path to user files relative to the document root.
-$Config['UserFilesPath'] = DOL_URL_ROOT.'/viewimage.php?modulepart=fckeditor&file=' ;
+$Config['UserFilesPath'] = DOL_URL_ROOT.'/viewimage.php?modulepart=medias'.(empty($website)?'':'_'.$website).'&file=' ;
+
+$Config['UserFilesAbsolutePathRelative'] = (empty($website) ? ((!empty($entity) ? '/' . $entity : '') . '/medias/') : ('/websites/'.$website));
 
 // Fill the following value it you prefer to specify the absolute path for the
 // user files directory. Useful if you are using a virtual directory, symbolic
 // link or alias. Examples: 'C:\\MySite\\userfiles\\' or '/root/mysite/userfiles/'.
 // Attention: The above 'UserFilesPath' must point to the same directory.
-$Config['UserFilesAbsolutePath'] = $dolibarr_main_data_root . (!empty($entity) ? '/' . $entity : '') . '/fckeditor/';
+$Config['UserFilesAbsolutePath'] = $dolibarr_main_data_root . $Config['UserFilesAbsolutePathRelative'];
 
 // Due to security issues with Apache modules, it is recommended to leave the
 // following setting enabled.
diff --git a/htdocs/core/filemanagerdol/connectors/php/upload.php b/htdocs/core/filemanagerdol/connectors/php/upload.php
index eb9600b20a9..dc7235dc8a8 100644
--- a/htdocs/core/filemanagerdol/connectors/php/upload.php
+++ b/htdocs/core/filemanagerdol/connectors/php/upload.php
@@ -42,7 +42,7 @@ function SendError($number, $text)
 
 // Check if this uploader has been enabled.
 if ( !$Config['Enabled'] )
-	SendUploadResults('1', '', '', 'This file uploader is disabled. Please check the "editor/filemanager/connectors/php/config.php" file');
+	SendUploadResults('1', '', '', 'This file uploader is disabled. Please check the "filemanagerdol/connectors/php/config.php" file');
 
 $sCommand = 'QuickUpload' ;
 
diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php
index 9be021b975e..95cb980e754 100644
--- a/htdocs/core/lib/files.lib.php
+++ b/htdocs/core/lib/files.lib.php
@@ -2213,8 +2213,6 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu
 	// Wrapping for import module
 	else if ($modulepart == 'import')
 	{
-		// Aucun test necessaire car on force le rep de download sur
-		// le rep export qui est propre a l'utilisateur
 		$accessallowed=1;
 		$original_file=$conf->import->dir_temp.'/'.$original_file;
 	}
@@ -2222,13 +2220,19 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu
 	// Wrapping pour l'editeur wysiwyg
 	else if ($modulepart == 'editor')
 	{
-		// Aucun test necessaire car on force le rep de download sur
-		// le rep export qui est propre a l'utilisateur
 		$accessallowed=1;
 		$original_file=$conf->fckeditor->dir_output.'/'.$original_file;
 	}
-
-	// Wrapping pour les backups
+	
+	// Wrapping for miscellaneous medias files
+	elseif ($modulepart == 'medias')
+	{
+	    $accessallowed=1;
+	    global $dolibarr_main_data_root;
+	    $original_file=$dolibarr_main_data_root.'/medias/'.$original_file;
+	}
+	
+	// Wrapping for backups
 	else if ($modulepart == 'systemtools')
 	{
 		if ($fuser->admin)
diff --git a/htdocs/core/modules/modFckeditor.class.php b/htdocs/core/modules/modFckeditor.class.php
index 31b3fafff16..ec7ce4dda14 100644
--- a/htdocs/core/modules/modFckeditor.class.php
+++ b/htdocs/core/modules/modFckeditor.class.php
@@ -57,7 +57,7 @@ class modFckeditor extends DolibarrModules
 		$this->picto='list';
 
 		// Data directories to create when module is enabled
-		$this->dirs = array("/fckeditor/temp","/fckeditor/image");
+		$this->dirs = array("/medias/temp","/medias/image");
 
 		// Config pages
 		$this->config_page_url = array("fckeditor.php");
@@ -65,7 +65,7 @@ class modFckeditor extends DolibarrModules
 		// Dependencies
 		$this->disabled = (in_array(constant('JS_CKEDITOR'),array('disabled','disabled/'))?1:0);	// A condition to disable module (used for native debian packages)
 		$this->depends = array();
-		$this->requiredby = array();
+		$this->requiredby = array('modWebsites');
 
 		// Constants
 		$this->const = array();
diff --git a/htdocs/core/modules/modWebsites.class.php b/htdocs/core/modules/modWebsites.class.php
index e3b500b0e0d..30795c6c0fa 100644
--- a/htdocs/core/modules/modWebsites.class.php
+++ b/htdocs/core/modules/modWebsites.class.php
@@ -58,8 +58,8 @@ class modWebsites extends DolibarrModules
         // Name of image file used for this module.
         $this->picto='globe';
 
-        // Data directories to create when module is enabled
-        $this->dirs = array();
+		// Data directories to create when module is enabled
+		$this->dirs = array("/websites/temp");
 
         // Config pages
         //-------------
@@ -68,7 +68,7 @@ class modWebsites extends DolibarrModules
         // Dependancies
         //-------------
 		$this->hidden = ! empty($conf->global->WEBSITE_MODULE_DISABLED);	// A condition to disable module
-		$this->depends = array();		// List of modules id that must be enabled if this module is enabled
+		$this->depends = array('modFckeditor');		// List of modules id that must be enabled if this module is enabled
         $this->requiredby = array();	// List of modules id to disable if this one is disabled
 		$this->conflictwith = array();	// List of modules id this module is in conflict with
         $this->langfiles = array("websites");
diff --git a/htdocs/document.php b/htdocs/document.php
index 1b3d494d1a1..52b1584e7af 100644
--- a/htdocs/document.php
+++ b/htdocs/document.php
@@ -65,6 +65,7 @@ $entity=GETPOST('entity')?GETPOST('entity','int'):$conf->entity;
 
 // Security check
 if (empty($modulepart)) accessforbidden('Bad value for parameter modulepart');
+if ($modulepart == 'fckeditor') $modulepart='medias';   // For backward compatibility
 
 $socid=0;
 if ($user->societe_id > 0) $socid = $user->societe_id;
@@ -97,7 +98,7 @@ if (preg_match('/\.(html|htm)$/i',$original_file)) $attachment = false;
 if (isset($_GET["attachment"])) $attachment = GETPOST("attachment")?true:false;
 if (! empty($conf->global->MAIN_DISABLE_FORCE_SAVEAS)) $attachment=false;
 
-// Suppression de la chaine de caractere ../ dans $original_file
+// Security: Delete string ../ into $original_file
 $original_file = str_replace("../","/", $original_file);
 
 // Find the subdirectory name as the reference
@@ -169,7 +170,6 @@ if (! file_exists($original_file_osencoded))
 }
 
 // Permissions are ok and file found, so we return it
-
 header('Content-Description: File Transfer');
 if ($encoding)   header('Content-Encoding: '.$encoding);
 if ($type)       header('Content-Type: '.$type.(preg_match('/text/',$type)?'; charset="'.$conf->file->character_set_client:''));
@@ -183,7 +183,7 @@ header('Pragma: public');
 
 //ob_clean();
 //flush();
-
+    
 readfile($original_file_osencoded);
 
 if (is_object($db)) $db->close();
diff --git a/htdocs/install/upgrade2.php b/htdocs/install/upgrade2.php
index c9fa2ba39a6..9ee3d842e51 100644
--- a/htdocs/install/upgrade2.php
+++ b/htdocs/install/upgrade2.php
@@ -401,6 +401,8 @@ if (! GETPOST("action") || preg_match('/upgrade/i',GETPOST('action')))
         $beforeversionarray=explode('.','4.0.9');
         if (versioncompare($versiontoarray,$afterversionarray) >= 0 && versioncompare($versiontoarray,$beforeversionarray) <= 0)
         {
+            migrate_directories($db,$langs,$conf,'/fckeditor','/medias');
+            
         	// Reload modules (this must be always and only into last targeted version)
         	$listofmodule=array(
         	    'MAIN_MODULE_BARCODE'=>'newboxdefonly',
diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
index 4b69e2c0dde..90ccde2474a 100644
--- a/htdocs/langs/en_US/main.lang
+++ b/htdocs/langs/en_US/main.lang
@@ -120,6 +120,7 @@ Home=Home
 Help=Help
 OnlineHelp=Online help
 PageWiki=Wiki page
+MediaBrowser=Media browser
 Always=Always
 Never=Never
 Under=under
diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang
index 13659bc5954..668ec7b3c07 100644
--- a/htdocs/langs/en_US/website.lang
+++ b/htdocs/langs/en_US/website.lang
@@ -4,7 +4,11 @@ WebsiteSetupDesc=Create here as much entry as number of different websites you n
 DeleteWebsite=Delete website
 ConfirmDeleteWebsite=Are you sure you want to delete this web site. All its pages and content will also be removed. 
 WEBSITE_PAGENAME=Page name/alias
-WEBSITE_URL=Page real URL
+WEBSITE_URL=Web site URL
+WEBSITE_CSS_URL=URL of external CSS file
+WEBSITE_CSS_INLINE=CSS content
+MediaFiles=Media library
+EditCss=Edit Style/CSS
 EditMenu=Edit menu
 EditPageMeta=Edit Meta
 EditPageContent=Edit Content
diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php
index 7f4c71bc915..bea4a20afcd 100644
--- a/htdocs/main.inc.php
+++ b/htdocs/main.inc.php
@@ -866,7 +866,7 @@ else
     define('ROWS_9',8);
 }
 
-$heightforframes=52;
+$heightforframes=48;
 
 // Init menu manager
 if (! defined('NOREQUIREMENU'))
diff --git a/htdocs/public/websites/index.php b/htdocs/public/websites/index.php
index fb3133df7cc..aa7d5d4941d 100644
--- a/htdocs/public/websites/index.php
+++ b/htdocs/public/websites/index.php
@@ -22,10 +22,98 @@
  *		\author	    Laurent Destailleur
  */
 
+define('NOTOKENRENEWAL',1); // Disables token renewal
+define("NOLOGIN",1);
+define("NOCSRFCHECK",1);	// We accept to go on this page from external web site.
+if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1');
+if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1');
+if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1');
+
+/**
+ * Header empty
+ *
+ * @return	void
+ */
+function llxHeader() { }
+/**
+ * Footer empty
+ *
+ * @return	void
+ */
+function llxFooter() { }
+
 require '../../master.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+
+
+$error=0;
+$website=GETPOST('website', 'alpha');
+$page=GETPOST('page', 'alpha');
+$pageid=GETPOST('pageid', 'alpha');
+
+$accessallowed = 1;
+$type='';
+
+
+/*
+ * View
+ */
 
 $appli=constant('DOL_APPLICATION_TITLE');
 if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $appli=$conf->global->MAIN_APPLICATION_TITLE;
 
-print 'Directory with '.$appli.' websites.<br>';
+//print 'Directory with '.$appli.' websites.<br>';
+
+
+// Security: Delete string ../ into $original_file
+global $dolibarr_main_data_root;
+
+if ($pageid == 'css')
+{
+    $original_file=$dolibarr_main_data_root.'/websites/'.$website.'/styles.css';
+}
+else
+{
+    $original_file=$dolibarr_main_data_root.'/websites/'.$website.'/page'.$pageid.'.tpl.php';
+}
+
+// Find the subdirectory name as the reference
+$refname=basename(dirname($original_file)."/");
+
+// Security:
+// Limite acces si droits non corrects
+if (! $accessallowed)
+{
+    accessforbidden();
+}
+
+// Security:
+// On interdit les remontees de repertoire ainsi que les pipe dans
+// les noms de fichiers.
+if (preg_match('/\.\./',$original_file) || preg_match('/[<>|]/',$original_file))
+{
+    dol_syslog("Refused to deliver file ".$original_file);
+    $file=basename($original_file);		// Do no show plain path of original_file in shown error message
+    dol_print_error(0,$langs->trans("ErrorFileNameInvalid",$file));
+    exit;
+}
+
+clearstatcache();
+
+$filename = basename($original_file);
+
+// Output file on browser
+dol_syslog("index.php include $original_file $filename content-type=$type");
+$original_file_osencoded=dol_osencode($original_file);	// New file name encoded in OS encoding charset
+
+// This test if file exists should be useless. We keep it to find bug more easily
+if (! file_exists($original_file_osencoded))
+{
+    dol_print_error(0,$langs->trans("ErrorFileDoesNotExists",$original_file));
+    exit;
+}
+
+include_once $original_file_osencoded;
+
+if (is_object($db)) $db->close();
 
diff --git a/htdocs/theme/eldy/ckeditor/config.js b/htdocs/theme/eldy/ckeditor/config.js
index cffaadfba6e..cf7163671a3 100644
--- a/htdocs/theme/eldy/ckeditor/config.js
+++ b/htdocs/theme/eldy/ckeditor/config.js
@@ -32,14 +32,12 @@ CKEDITOR.editorConfig = function( config )
 	    ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'],
 	    ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
 	    ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'],
-	    '/',
 	    ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],
 	    ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'],
 	    ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
 	    ['BidiLtr', 'BidiRtl'],
 	    ['Link','Unlink','Anchor'],
 	    ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak','Iframe'],
-	    '/',
 	    ['Styles','Format','Font','FontSize'],
 	    ['TextColor','BGColor'],
 	    ['Maximize', 'ShowBlocks','-','About']
diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php
index 59238e786f1..c33489e46fe 100644
--- a/htdocs/theme/eldy/style.css.php
+++ b/htdocs/theme/eldy/style.css.php
@@ -3126,19 +3126,21 @@ td.hidden {
 
 .websitebar {
 	border-bottom: 1px solid #888;
-	height: 30px; 
+	background: #eee;
 }
 .websiteselection {
 	display: inline-block;
 	padding-left: 10px;
 	vertical-align: middle; 
-	margin-bottom: 5px;
 	line-height: 29px;
 }
 .websitetools {
 	float: right;
 	padding-top: 2px;
 }
+.websiteiframenoborder {
+	border: 0px;
+}
 
 
 /* ============================================================================== */
diff --git a/htdocs/theme/md/ckeditor/config.js b/htdocs/theme/md/ckeditor/config.js
index cffaadfba6e..cf7163671a3 100644
--- a/htdocs/theme/md/ckeditor/config.js
+++ b/htdocs/theme/md/ckeditor/config.js
@@ -32,14 +32,12 @@ CKEDITOR.editorConfig = function( config )
 	    ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'],
 	    ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
 	    ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'],
-	    '/',
 	    ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],
 	    ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'],
 	    ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
 	    ['BidiLtr', 'BidiRtl'],
 	    ['Link','Unlink','Anchor'],
 	    ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak','Iframe'],
-	    '/',
 	    ['Styles','Format','Font','FontSize'],
 	    ['TextColor','BGColor'],
 	    ['Maximize', 'ShowBlocks','-','About']
diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php
index c45055a96f5..58629477e76 100644
--- a/htdocs/theme/md/style.css.php
+++ b/htdocs/theme/md/style.css.php
@@ -2988,19 +2988,21 @@ td.hidden {
 
 .websitebar {
 	border-bottom: 1px solid #888;
-	height: 30px; 
+	background: #eee;
 }
 .websiteselection {
 	display: inline-block;
 	padding-left: 10px;
 	vertical-align: middle; 
-	margin-bottom: 5px;
 	line-height: 29px;
 }
 .websitetools {
 	float: right;
 	padding-top: 2px;
 }
+.websiteiframenoborder {
+	border: 0px;
+}
 
 
 /* ============================================================================== */
diff --git a/htdocs/viewimage.php b/htdocs/viewimage.php
index 949884df6e9..585db4c343e 100644
--- a/htdocs/viewimage.php
+++ b/htdocs/viewimage.php
@@ -62,7 +62,7 @@ $entity=GETPOST('entity')?GETPOST('entity','int'):$conf->entity;
 
 // Security check
 if (empty($modulepart)) accessforbidden('Bad value for parameter modulepart');
-
+if ($modulepart == 'fckeditor') $modulepart='medias';   // For backward compatibility
 
 
 /*
@@ -95,7 +95,7 @@ $type = 'application/octet-stream';
 if (! empty($_GET["type"])) $type=$_GET["type"];
 else $type=dol_mimetype($original_file);
 
-// Suppression de la chaine de caractere ../ dans $original_file
+// Security: Delete string ../ into $original_file
 $original_file = str_replace("../","/", $original_file);
 
 // Find the subdirectory name as the reference
diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php
index 417484c2269..ea03c9fd7b7 100644
--- a/htdocs/websites/index.php
+++ b/htdocs/websites/index.php
@@ -63,6 +63,7 @@ function llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0,
 
 require '../main.inc.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/websites/class/website.class.php';
 require_once DOL_DOCUMENT_ROOT.'/websites/class/websitepage.class.php';
 
@@ -82,6 +83,8 @@ $action=GETPOST('action','alpha');
 
 if (GETPOST('preview')) $action='preview';
 if (GETPOST('create')) { $action='create'; }
+if (GETPOST('editmedia')) { $action='editmedia'; }
+if (GETPOST('editcss')) { $action='editcss'; }
 if (GETPOST('editmenu')) { $action='editmenu'; }
 if (GETPOST('editmeta')) { $action='editmeta'; }
 if (GETPOST('editcontent')) { $action='editcontent'; }
@@ -112,6 +115,12 @@ if ($pageid)
     $res = $objectpage->fetch($pageid);
 }
 
+global $dolibarr_main_data_root;
+$pathofwebsite=$dolibarr_main_data_root.'/websites/'.$website;
+$filecss=$pathofwebsite.'/styles.css';
+$filetpl=$pathofwebsite.'/page'.$pageid.'.tpl.php';
+
+
 
 /*
  * Actions
@@ -127,7 +136,7 @@ if ($action == 'add')
     $objectpage->title = GETPOST('WEBSITE_TITLE');
     $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME');
     $objectpage->description = GETPOST('WEBSITE_DESCRIPTION');
-    $objectpage->keyword = GETPOST('WEBSITE_KEYWORD');
+    $objectpage->keywords = GETPOST('WEBSITE_KEYWORD');
     
     if (empty($objectpage->title))
     {
@@ -198,18 +207,84 @@ if ($action == 'update')
     }
 }
 
+// Update css
+if ($action == 'updatecss')
+{
+    $db->begin();
+
+    $res = $object->fetch(0, $website);
+    /*
+    $res = $object->update($user);
+    if ($res > 0)
+    {
+        $db->commit();
+        setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
+        $action='';
+    }
+    else
+    {
+       $db->rollback();
+    }*/
+    
+    $csscontent = GETPOST('WEBSITE_CSS_INLINE');
+    
+    dol_mkdir($pathofwebsite);
+    file_put_contents($filecss, $csscontent);
+    if (! empty($conf->global->MAIN_UMASK))
+        @chmod($filecss, octdec($conf->global->MAIN_UMASK));
+    
+    $action='preview';
+}
+
+// Update page
+if ($action == 'updatemeta')
+{
+    $db->begin();
+    $object->fetch(0, $website);
+
+    $objectpage->fk_website = $object->id;
+
+    $res = $objectpage->fetch($pageid, $object->fk_website);
+    if ($res > 0)
+    {
+        $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME');
+        $objectpage->title = GETPOST('WEBSITE_TITLE');
+        $objectpage->description = GETPOST('WEBSITE_DESCRIPTION');
+        $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS');
+
+        $res = $objectpage->update($user);
+        if (! $res > 0)
+        {
+            $error++;
+            setEventMessages($objectpage->error, $objectpage->errors, 'errors');
+        }
+
+        if (! $error)
+        {
+            $db->commit();
+            setEventMessages($langs->trans("Saved"), null, 'mesgs');
+            $action='preview';
+        }
+        else
+        {
+            $db->rollback();
+        }
+    }
+    else
+    {
+        dol_print_error($db, 'Page not found');
+    }
+}
+
 // Update page
 if ($action == 'updatecontent')
 {
     $db->begin();
-    
     $object->fetch(0, $website);
-    
+
     $objectpage->fk_website = $object->id;
-    $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME');
-    
-    $res = $objectpage->fetch(0, $object->fk_website, $objectpage->pageurl);
     
+    $res = $objectpage->fetch($pageid, $object->fk_website);
     if ($res > 0)
     {
         $objectpage->content = GETPOST('PAGE_CONTENT');
@@ -225,7 +300,15 @@ if ($action == 'updatecontent')
     	{
     		$db->commit();
     	    setEventMessages($langs->trans("Saved"), null, 'mesgs');
-    	    $action='';
+    	    
+    	    dol_mkdir($pathofwebsite);
+    	    dol_delete_file($filetpl);
+    	    file_put_contents($filetpl, $objectpage->content);
+    	    if (! empty($conf->global->MAIN_UMASK))
+    	        @chmod($filetpl, octdec($conf->global->MAIN_UMASK));
+    	    
+   	        header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid);
+   	        exit;
     	}
     	else
     	{
@@ -234,7 +317,7 @@ if ($action == 'updatecontent')
     }
     else
     {
-        dol_print_error($db);
+        dol_print_error($db, 'Page not found');
     }
 }
 
@@ -256,6 +339,18 @@ if ($action == 'create')
 {
     print '<input type="hidden" name="action" value="add">';
 }
+if ($action == 'editcss')
+{
+    print '<input type="hidden" name="action" value="updatecss">';
+}
+if ($action == 'editmenu')
+{
+    print '<input type="hidden" name="action" value="updatemenu">';
+}
+if ($action == 'editmeta')
+{
+    print '<input type="hidden" name="action" value="updatemeta">';
+}
 if ($action == 'editcontent')
 {
     print '<input type="hidden" name="action" value="updatecontent">';
@@ -306,6 +401,8 @@ if (count($object->records) > 0)
         $disabled='';
         if (empty($user->rights->websites->create)) $disabled=' disabled="disabled"';
 
+        //print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("MediaFiles")).'" name="editmedia">';
+        print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditCss")).'" name="editcss">';
         print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditMenu")).'" name="editmenu">';
         print '<input type="submit"'.$disabled.' class="button" value="'.dol_escape_htmltag($langs->trans("AddPage")).'" name="create">';
     }
@@ -390,45 +487,96 @@ $head = array();
  * Edit mode
  */
 
-if ($action == 'editmeta' || $action == 'create')
+if ($action == 'editcss')
 {
     print '<div class="fiche">';
-    
+
+    print '<br>';
+
+    $csscontent = @file_get_contents($filecss);
+        
     dol_fiche_head();
-    
+
     print '<table class="border" width="100%">';
-    
+
     print '<tr><td>';
-    print $langs->trans('WEBSITE_PAGENAME');
+    print $langs->trans('WebSite');
+    print '</td><td>';
+    print $website;
+    print '</td></tr>';
+
+    print '<tr><td valign="top">';
+    print $langs->trans('WEBSITE_CSS_INLINE');
     print '</td><td>';
-    print '<input type="text" class="flat" size="96" name="WEBSITE_PAGENAME" value="'.dol_escape_htmltag($page).'">';
+    print '<textarea class="flat centpercent" rows="32" name="WEBSITE_CSS_INLINE">';
+    print $csscontent;
+    print '</textarea>';
     print '</td></tr>';
+
+    /*print '<tr><td>';
+    print $langs->trans('WEBSITE_CSS_URL');
+    print '</td><td>';
+    print '<input type="text" class="flat" size="96" name="WEBSITE_CSS_URL" value="'.dol_escape_htmltag($obj->WEBSITE_CSS_URL).'">';
+    print '</td></tr>';*/
+
+    print '</table>';
+
+    dol_fiche_end();
+
+    print '</div>';
+
+    print '<br>';
+}
+
+if ($action == 'editmeta' || $action == 'create')
+{
+    print '<div class="fiche">';
+ 
+    print '<br>';
+    
+    dol_fiche_head();
+    
+    print '<table class="border" width="100%">';
     
     if ($action != 'create')
     {
         print '<tr><td>';
-        print $langs->trans('WEBSITE_URL');
+        print $langs->trans('WEBSITE_PAGEURL');
         print '</td><td>';
-        print '/public/websites/'.$website.'/index.php?pageid='.urlencode($pageid);
+        print '/public/websites/index.php?website='.urlencode($website).'&pageid='.urlencode($pageid);
         print '</td></tr>';
+        $pageurl=dol_escape_htmltag($objectpage->pageurl);
+        $pagetitle=dol_escape_htmltag($objectpage->title);
+        $pagedescription=dol_escape_htmltag($objectpage->description);
+        $pagekeywords=dol_escape_htmltag($objectpage->keywords);
     }
+    if (GETPOST('WEBSITE_PAGENAME'))    $pageurl=GETPOST('WEBSITE_PAGENAME');
+    if (GETPOST('WEBSITE_TITLE'))       $pagetitle=GETPOST('WEBSITE_TITLE');
+    if (GETPOST('WEBSITE_DESCRIPTION')) $pagedescription=GETPOST('WEBSITE_DESCRIPTION');
+    if (GETPOST('WEBSITE_KEYWORDS'))    $pagekeywords=GETPOST('WEBSITE_KEYWORDS');
+    
+    print '<tr><td>';
+    print $langs->trans('WEBSITE_PAGENAME');
+    print '</td><td>';
+    print '<input type="text" class="flat" size="96" name="WEBSITE_PAGENAME" value="'.$pageurl.'">';
+    print '</td></tr>';
     
     print '<tr><td>';
     print $langs->trans('WEBSITE_TITLE');
     print '</td><td>';
-    print '<input type="text" class="flat" size="96" name="WEBSITE_TITLE" value="'.dol_escape_htmltag($obj->WEBSITE_TITLE).'">';
+    print '<input type="text" class="flat" size="96" name="WEBSITE_TITLE" value="'.$pagetitle.'">';
     print '</td></tr>';
     
     print '<tr><td>';
     print $langs->trans('WEBSITE_DESCRIPTION');
     print '</td><td>';
-    print '<input type="text" class="flat" size="96" name="WEBSITE_DESCRIPTION" value="'.dol_escape_htmltag($obj->WEBSITE_DESCRIPTION).'">';
+    print '<input type="text" class="flat" size="96" name="WEBSITE_DESCRIPTION" value="'.$pagedescription.'">';
     print '</td></tr>';
     
     print '<tr><td>';
     print $langs->trans('WEBSITE_KEYWORDS');
     print '</td><td>';
-    print '<input type="text" class="flat" size="128" name="WEBSITE_KEYWORDS" value="'.dol_escape_htmltag($obj->WEBSITE_KEYWORDS).'">';
+    print '<input type="text" class="flat" size="128" name="WEBSITE_KEYWORDS" value="'.$pagekeywords.'">';
     print '</td></tr>';
     
     print '</table>';
@@ -440,6 +588,11 @@ if ($action == 'editmeta' || $action == 'create')
     print '<br>';
 }
 
+if ($action == 'editmedia')
+{
+    print '<div class="center">'.$langs->trans("FeatureNotYetAvailable").'</center>';
+}
+
 if ($action == 'editmenu')
 {
     print '<div class="center">'.$langs->trans("FeatureNotYetAvailable").'</center>';
@@ -451,7 +604,7 @@ if ($action == 'editcontent')
      * Editing global variables not related to a specific theme
      */
     require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
-    $doleditor=new DolEditor('PAGE_CONTENT',$obj->value,'',160,'dolibarr_notes','',false,false,$conf->fckeditor->enabled,5,60);
+    $doleditor=new DolEditor('PAGE_CONTENT',$objectpage->content,'',500,'Full','',true,true,true,5,60);
     $doleditor->Create();
 }
 
@@ -465,10 +618,45 @@ if ($action == 'preview')
     {
         $objectpage->fetch($pageid);
         
-        print '<!-- Page content -->'."\n";
-        print '<div class="websitecontent">';
-        print $objectpage->content;
-        print '</div>';
+        print "\n".'<!-- Page content '.$filetpl.' c-->'."\n";
+
+        
+        $csscontent = @file_get_contents($filecss);
+        
+        $out='';
+        
+        $out.='<div id="websitecontent" class="websitecontent">'."\n";
+        
+        $out.='<style scoped>'."\n";        // "scoped" means "apply to parent element only". Not yet supported by browsers
+        $out.=$csscontent;
+        $out.='</style>'."\n";
+        
+        $out.=$objectpage->content."\n";
+        
+        $out.='</div>';
+        
+        print $out;
+        
+        /*file_put_contents($filetpl, $out);
+        if (! empty($conf->global->MAIN_UMASK))
+            @chmod($filetpl, octdec($conf->global->MAIN_UMASK));
+
+        // Output file on browser
+        dol_syslog("index.php include $filetpl $filename content-type=$type");
+        $original_file_osencoded=dol_osencode($filetpl);	// New file name encoded in OS encoding charset
+        
+        // This test if file exists should be useless. We keep it to find bug more easily
+        if (! file_exists($original_file_osencoded))
+        {
+            dol_print_error(0,$langs->trans("ErrorFileDoesNotExists",$original_file));
+            exit;
+        }
+        
+        //include_once $original_file_osencoded;
+        */
+        
+        /*print '<iframe class="websiteiframenoborder centpercent" src="'.DOL_URL_ROOT.'/public/websites/index.php?website='.$website.'&pageid='.$pageid.'"/>';
+        print '</iframe>';*/
     }
     else
     {
-- 
GitLab