From b31c1e77fd1208b87329215c2d7fd3cbf22173a1 Mon Sep 17 00:00:00 2001 From: Lamrani Abdel Date: Mon, 11 Dec 2023 17:52:46 +0100 Subject: [PATCH 01/23] New functionality for ovewrite modification in template --- htdocs/website/class/website.class.php | 75 +++++++++++++++++++++++++- htdocs/website/index.php | 10 ++++ 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index f5a4ec292bd..edc5d9e9c95 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -140,6 +140,10 @@ class Website extends CommonObject */ public $lines; + /** + * @var string name of template + */ + public $name_template; const STATUS_DRAFT = 0; const STATUS_VALIDATED = 1; @@ -331,7 +335,8 @@ class Website extends CommonObject $sql .= " t.fk_user_creat,"; $sql .= " t.fk_user_modif,"; $sql .= " t.date_creation,"; - $sql .= " t.tms as date_modification"; + $sql .= " t.tms as date_modification,"; + $sql .= " t.name_template"; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t"; $sql .= " WHERE t.entity IN (".getEntity('website').")"; if (!empty($ref)) { @@ -362,6 +367,7 @@ class Website extends CommonObject $this->fk_user_modif = $obj->fk_user_modif; $this->date_creation = $this->db->jdate($obj->date_creation); $this->date_modification = $this->db->jdate($obj->date_modification); + $this->name_template = $obj->name_template; } $this->db->free($resql); @@ -955,7 +961,6 @@ class Website extends CommonObject } $destdir = $conf->website->dir_temp.'/'.$website->ref; - dol_syslog("Clear temp dir ".$destdir); $count = 0; $countreallydeleted = 0; @@ -1605,4 +1610,70 @@ class Website extends CommonObject return $out; } + + /** + * Overite template by copy and past all files + * @return int 1 if OK, -1 if KO + */ + public function overwriteTemplate() + { + global $conf; + + $website = $this; + if (empty($website->id) || empty($website->ref)) { + setEventMessages("Website id or ref is not defined", null, 'errors'); + return false; + } + + $pathToInstallDir = DOL_DOCUMENT_ROOT . '/install/doctemplates/websites/'.urlencode($website->name_template); + + //check if can write in + if (!is_writable($pathToInstallDir)) { + if (is_readable($pathToInstallDir)) { + $files = scandir($pathToInstallDir); + $x =''; + foreach ($files as $file) { + $x .= $file . "\n"; + } + } else { + setEventMessages("Install dir ".$pathToInstallDir." is not readable", null, 'errors'); + return false; + } + } + + $srcdir = $conf->website->dir_output.'/'.$website->ref; + $destdir = $conf->install->dir_templates; + + dol_syslog("Copy templates from ".$srcdir." into ".$destdir); + $result = dolCopyDir($srcdir, $destdir, 0, 1); + + if ($result < 0) { + setEventMessages("Failed to copy templates", null, 'errors'); + var_dump(2); + } + + setEventMessages("Templates successfully overwritten", null, 'messages'); + return true; + } + + /** + * update name_template in table after import template + * @param string $name_template name of template + * @return int 1 if OK, -1 if KO + */ + public function setTemplateName($name_template) + { + $sql = "UPDATE ".$this->db->prefix()."website SET"; + $sql .= " name_template = '".$this->db->escape($name_template)."'"; + $sql .= " WHERE rowid = ".(int) $this->id; + $result = $this->db->query($sql); + //print_r($sql);exit; + if ($result) { + $this->db->commit(); + return 1; + } else { + $this->db->rollback(); + return -1; + } + } } diff --git a/htdocs/website/index.php b/htdocs/website/index.php index aa7ea1f78e7..5a65a52f4c5 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -2417,6 +2417,11 @@ if ($action == 'exportsite' && $user->hasRight('website', 'export')) { } } +// Overite site +if ($action == 'overwitesite' && $user->hasRight('website', 'export')) { + $fileofzip = $object->overwriteTemplate(); + var_dump($fileofzip); +} // Regenerate site if ($action == 'regeneratesite' && $usercanedit) { // Check symlink to medias and restore it if ko. Recreate also dir of website if not found. @@ -2517,6 +2522,9 @@ if ($action == 'importsiteconfirm' && $usercanedit) { } if (!$error && GETPOSTISSET('templateuserfile')) { + $templatewithoutzip = preg_replace('/\.zip$/i', '', GETPOST('templateuserfile')); + $object->setTemplateName($templatewithoutzip); + $result = $object->importWebSite($fileofzip); if ($result < 0) { @@ -3054,6 +3062,8 @@ if (!GETPOST('hide_websitemenu')) { print ''; } + // overite template + print 'ref).'" class="button bordertransp"> '.dol_escape_htmltag($langs->trans("Overwrite")).''; } else { print ''; } From aaba4b823bb46424cccd43fb2a9f68022eb0d3e6 Mon Sep 17 00:00:00 2001 From: Lamrani Abdel Date: Fri, 15 Dec 2023 18:17:51 +0100 Subject: [PATCH 02/23] add function for copy file when detected changes --- htdocs/website/class/website.class.php | 163 +++++++++++++++++++++---- htdocs/website/index.php | 4 +- 2 files changed, 141 insertions(+), 26 deletions(-) diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index edc5d9e9c95..a4a839acade 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1182,7 +1182,6 @@ class Website extends CommonObject $error = 0; $pathtofile = dol_sanitizePathName($pathtofile); - $object = $this; if (empty($object->ref)) { $this->error = 'Function importWebSite called on object not loaded (object->ref is empty)'; @@ -1625,35 +1624,83 @@ class Website extends CommonObject return false; } - $pathToInstallDir = DOL_DOCUMENT_ROOT . '/install/doctemplates/websites/'.urlencode($website->name_template); + if (!is_writable($conf->website->dir_output)) { + setEventMessages("Temporary dir ".$conf->website->dir_output." is not writable", null, 'errors'); + return ''; + } - //check if can write in - if (!is_writable($pathToInstallDir)) { - if (is_readable($pathToInstallDir)) { - $files = scandir($pathToInstallDir); - $x =''; - foreach ($files as $file) { - $x .= $file . "\n"; + $sourcedir = $conf->website->dir_output."/".$website->ref; + + $destdir = DOL_DOCUMENT_ROOT . '/install/doctemplates/websites/'.$website->name_template; + + // Copier le fichier zip dans le dossier de destination + + if (is_dir($destdir) && is_dir($sourcedir)) { + $arraydestdir = dol_dir_list($destdir, "all", 0, '', '', 'name', SORT_ASC); + $arraysourcedir = dol_dir_list($sourcedir, "all", 1, '', '', 'name', SORT_ASC); + } + $destinationFileNames = array_column($arraydestdir, 'name'); + // var_dump($arraysourcedir);exit; + foreach ($arraysourcedir as $sourceFile) { + if ($this->extractNumberFromFilename($sourceFile['fullname']) > 1) { + if (!preg_match('/\.old$/', $sourceFile['name'])) { + $arraySource[] = $sourceFile['fullname']; + } + } + } + // for extract pages in destination folder + foreach ($arraydestdir as $destFile) { + if ($destFile['name'] == 'containers') { + $containersDir = dol_dir_list($destFile['fullname']); + + foreach ($containersDir as $file) { + $extractPageFromDestDir = $this->extractNumberFromFilename($file['fullname']); + if ($extractPageFromDestDir > 1) { + $arrayDest[] = $file['fullname']; + } } - } else { - setEventMessages("Install dir ".$pathToInstallDir." is not readable", null, 'errors'); - return false; } } - $srcdir = $conf->website->dir_output.'/'.$website->ref; - $destdir = $conf->install->dir_templates; + $minCount = min(count($arraySource), count($arrayDest)); + for ($i = 0; $i < $minCount; $i++) { + $sourceFilePath = $arraySource[$i]; + $destFilePath = $arrayDest[$i]; - dol_syslog("Copy templates from ".$srcdir." into ".$destdir); - $result = dolCopyDir($srcdir, $destdir, 0, 1); + $sourceContent = file_get_contents($sourceFilePath); + if ($sourceContent === false) { + echo "Erreur lors de la lecture du fichier source: " . basename($sourceFilePath) . "\n"; + } else { + $destContent = file_get_contents($destFilePath); + if ($destContent === false) { + echo "Erreur lors de la lecture du fichier de destination: " . basename($destFilePath) . "\n"; + } else { + if ($sourceContent !== $destContent) { + $numPage = $this->extractNumberFromFilename($sourceFilePath); - if ($result < 0) { - setEventMessages("Failed to copy templates", null, 'errors'); - var_dump(2); + $differences = $this->showDifferences($sourceContent, $destContent, $numPage); + + //var_dump($differences); + //var_dump($arrayreplacement); + // Les contenus sont différents, effectuer la copie + + if (file_put_contents($destFilePath, $sourceContent) === false) { + echo "Échec de la copie du fichier: " . basename($sourceFilePath) . "\n"; + } else { + if (count($differences) > 0) { + $result = dolReplaceInFile($destFilePath, $differences); + if ($result > 0) { + echo 'rename with correct number page'; + } + echo "Fichier copié avec succès: " . basename($sourceFilePath) . "\n"; + } + } + } else { + echo "Aucune modification détectée, copie non nécessaire pour: " . basename($sourceFilePath) . "\n"; + } + } + } } - - setEventMessages("Templates successfully overwritten", null, 'messages'); - return true; } /** @@ -1667,7 +1714,7 @@ class Website extends CommonObject $sql .= " name_template = '".$this->db->escape($name_template)."'"; $sql .= " WHERE rowid = ".(int) $this->id; $result = $this->db->query($sql); - //print_r($sql);exit; + if ($result) { $this->db->commit(); return 1; @@ -1676,4 +1723,74 @@ class Website extends CommonObject return -1; } } + + /** + * extract num of page + * @param string $filename name of file + * @return int 1 if OK, -1 if KO + */ + protected function extractNumberFromFilename($filename) + { + $matches = []; + if (preg_match('/page(\d+)\.tpl\.php/', $filename, $matches)) { + return (int) $matches[1]; + } + return -1; + } + + /** + * remove espace in string + * @param string $str string + * @return string + */ + protected function normalizeString($str) + { + + $str = str_replace("\r\n", "\n", $str); + $str = str_replace("\r", "\n", $str); + + $lines = explode("\n", $str); + $lines = array_map('trim', $lines); + + return implode("\n", $lines); + } + + /** + * show difference between to string + * @param string $str1 first string + * @param string $str2 seconde string + * @param string $exceptNumPge num of page file + * @return array|int -1 if KO, array if OK + */ + protected function showDifferences($str1, $str2, $exceptNumPge = '0') + { + $diff = []; + $str1 = $this->normalizeString($str1); + $str2 = $this->normalizeString($str2); + + $lines1 = explode("\n", $str1); + $lines2 = explode("\n", $str2); + + foreach ($lines1 as $lineNum => $lineContent) { + if (isset($lines2[$lineNum])) { + if ($lineContent !== $lines2[$lineNum]) { + $diff[$lines2[$lineNum]] = $lineContent; + } + } else { + $diff['new'] = "line " . ($lineNum + 1) . ": " . $lineContent; + } + } + foreach ($lines2 as $lineNum => $lineContent) { + if (!isset($lines1[$lineNum])) { + $diff[] = "Supplémentaire dans la destination à la ligne " . ($lineNum + 1) . ": " . $lineContent; + } + } + // search if except exist in array + foreach ($diff as $key => $line) { + if (str_contains($line, $exceptNumPge)) { + $lineNochange[$line] = $key; + } + } + return $lineNochange; + } } diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 5a65a52f4c5..0fb360f0755 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -2399,12 +2399,11 @@ if ($usercanedit && (($action == 'updatesource' || $action == 'updatecontent' || } // Export site -if ($action == 'exportsite' && $user->hasRight('website', 'export')) { +if ($action == 'exportsite') { $fileofzip = $object->exportWebSite(); if ($fileofzip) { $file_name = basename($fileofzip); - header("Content-Type: application/zip"); header("Content-Disposition: attachment; filename=".$file_name); header("Content-Length: ".filesize($fileofzip)); @@ -2420,7 +2419,6 @@ if ($action == 'exportsite' && $user->hasRight('website', 'export')) { // Overite site if ($action == 'overwitesite' && $user->hasRight('website', 'export')) { $fileofzip = $object->overwriteTemplate(); - var_dump($fileofzip); } // Regenerate site if ($action == 'regeneratesite' && $usercanedit) { From 0e564736203595b6ab3e18a37504b4617c01506a Mon Sep 17 00:00:00 2001 From: Lamrani Abdel Date: Mon, 18 Dec 2023 18:13:50 +0100 Subject: [PATCH 03/23] update function for overwrite folder --- htdocs/website/class/website.class.php | 157 ++++--------------------- 1 file changed, 20 insertions(+), 137 deletions(-) diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index a4a839acade..a8ac86c75d4 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1623,83 +1623,36 @@ class Website extends CommonObject setEventMessages("Website id or ref is not defined", null, 'errors'); return false; } - - if (!is_writable($conf->website->dir_output)) { - setEventMessages("Temporary dir ".$conf->website->dir_output." is not writable", null, 'errors'); + if (!is_writable($conf->website->dir_temp)) { + setEventMessages("Temporary dir ".$conf->website->dir_temp." is not writable", null, 'errors'); return ''; } - $sourcedir = $conf->website->dir_output."/".$website->ref; - $destdir = DOL_DOCUMENT_ROOT . '/install/doctemplates/websites/'.$website->name_template; + $filename = $this->exportWebSite(); + if (!is_writable($destdir)) { + setEventMessages("Error to write in folder".$destdir, null, 'errors'); + return ''; + } + $destfile = $destdir.'/'.basename($filename); + // Copier le fichier zip dans le dossier de destination - - if (is_dir($destdir) && is_dir($sourcedir)) { - $arraydestdir = dol_dir_list($destdir, "all", 0, '', '', 'name', SORT_ASC); - $arraysourcedir = dol_dir_list($sourcedir, "all", 1, '', '', 'name', SORT_ASC); - } - $destinationFileNames = array_column($arraydestdir, 'name'); - // var_dump($arraysourcedir);exit; - foreach ($arraysourcedir as $sourceFile) { - if ($this->extractNumberFromFilename($sourceFile['fullname']) > 1) { - if (!preg_match('/\.old$/', $sourceFile['name'])) { - $arraySource[] = $sourceFile['fullname']; - } - } - } - // for extract pages in destination folder - foreach ($arraydestdir as $destFile) { - if ($destFile['name'] == 'containers') { - $containersDir = dol_dir_list($destFile['fullname']); - - foreach ($containersDir as $file) { - $extractPageFromDestDir = $this->extractNumberFromFilename($file['fullname']); - if ($extractPageFromDestDir > 1) { - $arrayDest[] = $file['fullname']; - } - } + if (file_exists($filename)) { + if (!copy($filename, $destfile)) { + setEventMessages("Failed to copy zip file to destination directory", null, 'errors'); + return ''; } } - $minCount = min(count($arraySource), count($arrayDest)); - for ($i = 0; $i < $minCount; $i++) { - $sourceFilePath = $arraySource[$i]; - $destFilePath = $arrayDest[$i]; + $result = dol_uncompress($destfile, $destdir.'/'); - $sourceContent = file_get_contents($sourceFilePath); - if ($sourceContent === false) { - echo "Erreur lors de la lecture du fichier source: " . basename($sourceFilePath) . "\n"; - } else { - $destContent = file_get_contents($destFilePath); - if ($destContent === false) { - echo "Erreur lors de la lecture du fichier de destination: " . basename($destFilePath) . "\n"; - } else { - if ($sourceContent !== $destContent) { - $numPage = $this->extractNumberFromFilename($sourceFilePath); - - $differences = $this->showDifferences($sourceContent, $destContent, $numPage); - - //var_dump($differences); - //var_dump($arrayreplacement); - // Les contenus sont différents, effectuer la copie - - if (file_put_contents($destFilePath, $sourceContent) === false) { - echo "Échec de la copie du fichier: " . basename($sourceFilePath) . "\n"; - } else { - if (count($differences) > 0) { - $result = dolReplaceInFile($destFilePath, $differences); - if ($result > 0) { - echo 'rename with correct number page'; - } - echo "Fichier copié avec succès: " . basename($sourceFilePath) . "\n"; - } - } - } else { - echo "Aucune modification détectée, copie non nécessaire pour: " . basename($sourceFilePath) . "\n"; - } - } - } + if (!empty($result['error'])) { + setEventMessages('Failed to unzip file '.$destfile.'.', null, 'errors'); + return -1; + } else { + dol_delete_file($destfile); + return 1; } } @@ -1723,74 +1676,4 @@ class Website extends CommonObject return -1; } } - - /** - * extract num of page - * @param string $filename name of file - * @return int 1 if OK, -1 if KO - */ - protected function extractNumberFromFilename($filename) - { - $matches = []; - if (preg_match('/page(\d+)\.tpl\.php/', $filename, $matches)) { - return (int) $matches[1]; - } - return -1; - } - - /** - * remove espace in string - * @param string $str string - * @return string - */ - protected function normalizeString($str) - { - - $str = str_replace("\r\n", "\n", $str); - $str = str_replace("\r", "\n", $str); - - $lines = explode("\n", $str); - $lines = array_map('trim', $lines); - - return implode("\n", $lines); - } - - /** - * show difference between to string - * @param string $str1 first string - * @param string $str2 seconde string - * @param string $exceptNumPge num of page file - * @return array|int -1 if KO, array if OK - */ - protected function showDifferences($str1, $str2, $exceptNumPge = '0') - { - $diff = []; - $str1 = $this->normalizeString($str1); - $str2 = $this->normalizeString($str2); - - $lines1 = explode("\n", $str1); - $lines2 = explode("\n", $str2); - - foreach ($lines1 as $lineNum => $lineContent) { - if (isset($lines2[$lineNum])) { - if ($lineContent !== $lines2[$lineNum]) { - $diff[$lines2[$lineNum]] = $lineContent; - } - } else { - $diff['new'] = "line " . ($lineNum + 1) . ": " . $lineContent; - } - } - foreach ($lines2 as $lineNum => $lineContent) { - if (!isset($lines1[$lineNum])) { - $diff[] = "Supplémentaire dans la destination à la ligne " . ($lineNum + 1) . ": " . $lineContent; - } - } - // search if except exist in array - foreach ($diff as $key => $line) { - if (str_contains($line, $exceptNumPge)) { - $lineNochange[$line] = $key; - } - } - return $lineNochange; - } } From 8c8404f32ffca72418f21f4ba0d44dcc71f86158 Mon Sep 17 00:00:00 2001 From: Lamrani Abdel Date: Fri, 22 Dec 2023 17:47:19 +0100 Subject: [PATCH 04/23] update function --- htdocs/website/class/website.class.php | 305 +++++++++++++++++++++++-- 1 file changed, 285 insertions(+), 20 deletions(-) diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index a8ac86c75d4..e872e00ee1e 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1317,7 +1317,7 @@ class Website extends CommonObject // Regenerate index page to point to the new index page $pathofwebsite = $conf->website->dir_output.'/'.$object->ref; dolSaveIndexPage($pathofwebsite, $pathofwebsite.'/index.php', $pathofwebsite.'/page'.$object->fk_default_home.'.tpl.php', $pathofwebsite.'/wrapper.php', $object); - + $this->initFilesStatus($pathofwebsite); if ($error) { $this->db->rollback(); return -1; @@ -1612,7 +1612,7 @@ class Website extends CommonObject /** * Overite template by copy and past all files - * @return int 1 if OK, -1 if KO + * @return void */ public function overwriteTemplate() { @@ -1628,32 +1628,103 @@ class Website extends CommonObject return ''; } - $destdir = DOL_DOCUMENT_ROOT . '/install/doctemplates/websites/'.$website->name_template; + $sourcedir = $conf->website->dir_output."/".$website->ref; - $filename = $this->exportWebSite(); - if (!is_writable($destdir)) { - setEventMessages("Error to write in folder".$destdir, null, 'errors'); - return ''; - } - $destfile = $destdir.'/'.basename($filename); + $fichierEtat = $sourcedir . '/etat_fichiers.txt'; - // Copier le fichier zip dans le dossier de destination - if (file_exists($filename)) { - if (!copy($filename, $destfile)) { - setEventMessages("Failed to copy zip file to destination directory", null, 'errors'); - return ''; + $etatPrecedent = $this->checkPreviousState($fichierEtat); + + $arraySourcedir = dol_dir_list($sourcedir); + + $modifications = []; + foreach ($arraySourcedir as $file) { + if (substr($file['name'], -4) === '.old') { + continue; } + $hashActuel = hash_file('md5', $file['fullname']); + + // Check whether the file is new or has been modified + if (!isset($etatPrecedent[$file['name']]) || $etatPrecedent[$file['name']] !== $hashActuel) { + $modifications[] = $file; + } + + $etatPrecedent[$file['name']] = $hashActuel; } - $result = dol_uncompress($destfile, $destdir.'/'); + // listed modified files - if (!empty($result['error'])) { - setEventMessages('Failed to unzip file '.$destfile.'.', null, 'errors'); - return -1; + $destdir = DOL_DOCUMENT_ROOT . '/install/doctemplates/websites/'.$website->name_template; + $arraydestdir = dol_dir_list($destdir, "all", 1); + $differences = []; + + if (count($modifications) >1) { + foreach ($modifications as $fichierModifie) { + $nomFichierModifie = $fichierModifie['name']; + if ($nomFichierModifie == basename($fichierEtat)) { + continue; + } + + // Find the corresponding file in the destination folder + foreach ($arraydestdir as $destFile) { + if ($destFile['name'] == $nomFichierModifie) { + $sourceContent = file_get_contents($fichierModifie['fullname']); + $destContent = file_get_contents($destFile['fullname']); + + if ($sourceContent !== $destContent) { + $numPage = $this->extractNumberFromFilename($fichierModifie['fullname']); + $differences[$nomFichierModifie] = $this->showDifferences($destContent, $sourceContent, $numPage); + + if (count($differences[$nomFichierModifie]) > 0) { + $result = $this->replaceLignEUsingNum($destFile['fullname'], $differences[$nomFichierModifie]); + if ($result !== false) { + setEventMessages("file ".$nomFichierModifie." was modified", null, 'warnings'); + } else { + setEventMessages("file ".$nomFichierModifie." was not modified", null, 'errors'); + } + } + } + } else { + // TO DO when file has not same name + // $succes = 0; + // $differences[$nomFichierModifie] = $this->compareFichierModifie($sourcedir, $destdir, $fichierModifie); + + // if (count($differences[$nomFichierModifie]) > 0) { + // $result = $this->replaceLignEUsingNum($destFile['fullname'], $differences[$nomFichierModifie]); + // if ($result !== false) { + // $succes++; + // } else { + // setEventMessages("file ".$nomFichierModifie." was not modified", null, 'errors'); + // } + // } + } + } + // if ($succes) { + // setEventMessages("file ".$nomFichierModifie." was modified", null, 'warnings'); + // } + } } else { - dol_delete_file($destfile); - return 1; + setEventMessages("No files was modified", null, 'warnings'); } + + // save state file + $this->saveState($etatPrecedent, $fichierEtat); + + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); + exit(); + } + + /** + * extract num of page + * @param string $filename name of file + * @return int 1 if OK, -1 if KO + */ + protected function extractNumberFromFilename($filename) + { + $matches = []; + if (preg_match('/page(\d+)\.tpl\.php/', $filename, $matches)) { + return (int) $matches[1]; + } + return -1; } /** @@ -1676,4 +1747,198 @@ class Website extends CommonObject return -1; } } + + /** + * check previous state for file + * @param string $pathname path of file + * @return array|mixed + */ + public function checkPreviousState($pathname) + { + if (!file_exists($pathname)) { + if (touch($pathname)) { + dolChmod($pathname, '0664'); + } + return []; + } + return unserialize(file_get_contents($pathname)); + } + + + /** + * Save state for File + * @param mixed $etat state + * @param mixed $pathname path of file + * @return int|false + */ + public function saveState($etat, $pathname) + { + return file_put_contents($pathname, serialize($etat)); + } + + /** + * create file for save state of all files in folder + * @param string $sourcedir path of folder + * @return void + */ + public function initFilesStatus($sourcedir) + { + $fichierEtat = $sourcedir . '/etat_fichiers.txt'; + + $etatPrecedent = $this->checkPreviousState($fichierEtat); + + // for first save state when ceate file + if (empty($etatPrecedent)) { + $arraySourcedir = dol_dir_list($sourcedir, "files"); + $etatFichiers = []; + + foreach ($arraySourcedir as $file) { + // Ignore .old files and the status file itself + if (substr($file['name'], -4) === '.old' || $file['name'] === basename($fichierEtat)) { + continue; + } + + $hashActuel = hash_file('md5', $file['fullname']); + $etatFichiers[$file['name']] = $hashActuel; + } + $this->saveState($etatFichiers, $fichierEtat); + } + } + + // public function compareFichierModifie($dossierSource, $dossierDestination, $fichierModifie) + // { + + // // Initialiser les tableaux pour les fichiers filtrés + // $fichiersSource = []; + // $fichiersDestination = []; + + // // Parcourir et filtrer les fichiers source + // foreach (dol_dir_list($dossierSource, "files") as $file) { + // if (preg_match('/^page\d+/', $file['name']) && !str_contains($file['name'], '.old')) { + // $fichiersSource[] = $file; + // } + // } + + // // Parcourir et filtrer les fichiers destination + // foreach (dol_dir_list($dossierDestination, "all", 1) as $file) { + // if (preg_match('/^page\d+/', $file['name']) && !str_contains($file['name'], '.old')) { + // $fichiersDestination[] = $file; + // } + // } + + // // Trouver l'index du fichier modifié dans la liste triée + // $indexModifie = -1; + // foreach ($fichiersSource as $index => $file) { + // if ($file['name'] == basename($fichierModifie['fullname'])) { + // $indexModifie = $index; + // break; + // } + // } + + // if ($indexModifie != -1 && isset($fichiersDestination[$indexModifie])) { + // // Comparer le fichier modifié avec le fichier correspondant dans le dossier de destination + // $sameFichier= $fichiersDestination[$indexModifie]['fullname']; + // $sourceContent = file_get_contents($fichierModifie['fullname']); + // $destContent = file_get_contents($sameFichier); + // $differences = $this->showDifferences($destContent, $sourceContent); + // return $differences; + // } + // return array(); + // } + + /** + * remove espace in string + * @param string $str string + * @return string + */ + protected function normalizeString($str) + { + + $str = str_replace("\r\n", "\n", $str); + $str = str_replace("\r", "\n", $str); + + $lines = explode("\n", $str); + $lines = array_map('trim', $lines); + + return implode("\n", $lines); + } + + /** + * show difference between to string + * @param string $str1 first string + * @param string $str2 seconde string + * @param string $exceptNumPge num of page file + * @return array|int -1 if KO, array if OK + */ + protected function showDifferences($str1, $str2, $exceptNumPge = '0') + { + $diff = []; + $str1 = $this->normalizeString($str1); + $str2 = $this->normalizeString($str2); + + $lines1 = explode("\n", $str1); + $lines2 = explode("\n", $str2); + + $maxLines = max(count($lines1), count($lines2)); + + for ($lineNum = 0; $lineNum < $maxLines; $lineNum++) { + $lineContent1 = $lines1[$lineNum] ?? ''; + $lineContent2 = $lines2[$lineNum] ?? ''; + + if (str_contains($lineContent1, $exceptNumPge) || str_contains($lineContent2, $exceptNumPge)) { + continue; + } + + if ($lineContent1 !== $lineContent2) { + if (isset($lines1[$lineNum]) && !isset($lines2[$lineNum])) { + // Ligne deleted de la source + $diff["Supprimée à la ligne " . ($lineNum + 1)] = $lineContent1; + } elseif (!isset($lines1[$lineNum]) && isset($lines2[$lineNum])) { + // Nouvelle ligne added dans la destination + $diff["Ajoutée à la ligne " . ($lineNum + 1)] = $lineContent2; + } else { + // Différence found it + $diff["Modifiée à la ligne " . ($lineNum + 1)] = $lineContent2; + } + } + } + + return $diff; + } + + /** + * Replace ligne by ligne in file using num of ligne + * @param string $desfFile path of file dest + * @param array $differences array of differences between files + * @return false|int false if we cant replace + */ + public function replaceLignEUsingNum($desfFile, $differences) + { + // if (file_exists($desfFile)) { + // dolChmod($desfFile,'766'); + // } + $contentDest = file($desfFile, FILE_IGNORE_NEW_LINES); + + foreach ($differences as $key => $ligneSource) { + if (preg_match('/(Ajoutée|Modifiée) à la ligne (\d+)/', $key, $matches)) { + $typeModification = $matches[1]; + $numLigne = (int) $matches[2] - 1; + + if ($typeModification === 'Ajoutée') { + array_splice($contentDest, $numLigne, 0, $ligneSource); + } elseif ($typeModification === 'Modifiée') { + $contentDest[$numLigne] = $ligneSource; + } + } elseif (preg_match('/Supprimée à la ligne (\d+)/', $key, $matches)) { + $numLigne = (int) $matches[1] - 1; + unset($contentDest[$numLigne]); + } + } + //Reindex the table keys + + $contentDest = array_values($contentDest); + $stringreplacement = implode("\n", $contentDest); + + file_put_contents($desfFile, $stringreplacement); + } } From 91d09cc0b299d1df658500a8248d6f7164a14fee Mon Sep 17 00:00:00 2001 From: Lamrani Abdel Date: Tue, 26 Dec 2023 18:56:32 +0100 Subject: [PATCH 05/23] recupere lines dont want to change --- htdocs/website/class/website.class.php | 174 +++++++++++++++---------- 1 file changed, 102 insertions(+), 72 deletions(-) diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index e872e00ee1e..a9eb5d56f59 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1677,40 +1677,43 @@ class Website extends CommonObject if (count($differences[$nomFichierModifie]) > 0) { $result = $this->replaceLignEUsingNum($destFile['fullname'], $differences[$nomFichierModifie]); if ($result !== false) { - setEventMessages("file ".$nomFichierModifie." was modified", null, 'warnings'); + // save state file + $this->saveState($etatPrecedent, $fichierEtat); + setEventMessages("file ".$nomFichierModifie." was modified in template ".$website->name_template."", null, 'warnings'); + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); + exit(); } else { setEventMessages("file ".$nomFichierModifie." was not modified", null, 'errors'); } } } - } else { + } elseif (preg_match('/page(\d+)\.tpl\.php/', $nomFichierModifie)) { // TO DO when file has not same name - // $succes = 0; - // $differences[$nomFichierModifie] = $this->compareFichierModifie($sourcedir, $destdir, $fichierModifie); - - // if (count($differences[$nomFichierModifie]) > 0) { - // $result = $this->replaceLignEUsingNum($destFile['fullname'], $differences[$nomFichierModifie]); - // if ($result !== false) { - // $succes++; - // } else { - // setEventMessages("file ".$nomFichierModifie." was not modified", null, 'errors'); - // } - // } + $succes = 0; + $differences[$nomFichierModifie] = $this->compareFichierModifie($sourcedir, $destdir, $fichierModifie); + if (count($differences[$nomFichierModifie]) > 0) { + $result = $this->replaceLignEUsingNum($differences[$nomFichierModifie]['file_destination']['fullname'], $differences[$nomFichierModifie]); + if ($result !== false) { + $succes++; + } else { + setEventMessages("file ".$nomFichierModifie." was not modified", null, 'errors'); + } + } } } - // if ($succes) { - // setEventMessages("file ".$nomFichierModifie." was modified", null, 'warnings'); - // } + if ($succes) { + // save state file + $this->saveState($etatPrecedent, $fichierEtat); + setEventMessages("file ".$differences[$nomFichierModifie]['file_destination']['name']." was modified in template ".$website->name_template."", null, 'warnings'); + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); + exit(); + } } } else { - setEventMessages("No files was modified", null, 'warnings'); + setEventMessages("No file has been modified", null, 'warnings'); + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); + exit(); } - - // save state file - $this->saveState($etatPrecedent, $fichierEtat); - - header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); - exit(); } /** @@ -1805,53 +1808,65 @@ class Website extends CommonObject } } - // public function compareFichierModifie($dossierSource, $dossierDestination, $fichierModifie) - // { + /** + * Compare two files has not same name but same content + * @param string $dossierSource filepath of folder source + * @param string $dossierDestination filepath of folder dest + * @param mixed $fichierModifie files modified + * @return array empty if KO, array if OK + */ + public function compareFichierModifie($dossierSource, $dossierDestination, $fichierModifie) + { - // // Initialiser les tableaux pour les fichiers filtrés - // $fichiersSource = []; - // $fichiersDestination = []; + $fichiersSource = []; + $fichiersDestination = []; - // // Parcourir et filtrer les fichiers source - // foreach (dol_dir_list($dossierSource, "files") as $file) { - // if (preg_match('/^page\d+/', $file['name']) && !str_contains($file['name'], '.old')) { - // $fichiersSource[] = $file; - // } - // } + // filter files source + foreach (dol_dir_list($dossierSource, "files") as $file) { + if (preg_match('/^page\d+/', $file['name']) && !str_contains($file['name'], '.old')) { + $fichiersSource[] = $file; + } + } - // // Parcourir et filtrer les fichiers destination - // foreach (dol_dir_list($dossierDestination, "all", 1) as $file) { - // if (preg_match('/^page\d+/', $file['name']) && !str_contains($file['name'], '.old')) { - // $fichiersDestination[] = $file; - // } - // } + // filter files destination + foreach (dol_dir_list($dossierDestination, "all", 1) as $file) { + if (preg_match('/^page\d+/', $file['name']) && !str_contains($file['name'], '.old')) { + $fichiersDestination[] = $file; + } + } - // // Trouver l'index du fichier modifié dans la liste triée - // $indexModifie = -1; - // foreach ($fichiersSource as $index => $file) { - // if ($file['name'] == basename($fichierModifie['fullname'])) { - // $indexModifie = $index; - // break; - // } - // } + // find index source and search it in folder destination + $numOfPageSource = 0; + $indexModifie = -1; + foreach ($fichiersSource as $index => $file) { + if ($file['name'] == basename($fichierModifie['fullname'])) { + $numOfPageSource = $this->extractNumberFromFilename($file['name']); + $indexModifie = $index; + break; + } + } - // if ($indexModifie != -1 && isset($fichiersDestination[$indexModifie])) { - // // Comparer le fichier modifié avec le fichier correspondant dans le dossier de destination - // $sameFichier= $fichiersDestination[$indexModifie]['fullname']; - // $sourceContent = file_get_contents($fichierModifie['fullname']); - // $destContent = file_get_contents($sameFichier); - // $differences = $this->showDifferences($destContent, $sourceContent); - // return $differences; - // } - // return array(); - // } + if ($indexModifie != -1 && isset($fichiersDestination[$indexModifie])) { + $sameFichier= $fichiersDestination[$indexModifie]['fullname']; + $sourceContent = file_get_contents($fichierModifie['fullname']); + $destContent = file_get_contents($sameFichier); + + $numOfPageDest = $this->extractNumberFromFilename($sameFichier); + + $differences = $this->showDifferences($destContent, $sourceContent, array($numOfPageDest,$numOfPageSource)); + $differences['file_destination'] = $fichiersDestination[$indexModifie]; + + return $differences; + } + return array(); + } /** * remove espace in string * @param string $str string * @return string */ - protected function normalizeString($str) + private function normalizeString($str) { $str = str_replace("\r\n", "\n", $str); @@ -1867,26 +1882,30 @@ class Website extends CommonObject * show difference between to string * @param string $str1 first string * @param string $str2 seconde string - * @param string $exceptNumPge num of page file + * @param array $exceptNumPge num of page files we dont want to change * @return array|int -1 if KO, array if OK */ - protected function showDifferences($str1, $str2, $exceptNumPge = '0') + protected function showDifferences($str1, $str2, $exceptNumPge = array()) { - $diff = []; + $diff = array(); $str1 = $this->normalizeString($str1); $str2 = $this->normalizeString($str2); $lines1 = explode("\n", $str1); $lines2 = explode("\n", $str2); + $linesShouldnChange = array(); + $linesShouldnNotChange = array(); $maxLines = max(count($lines1), count($lines2)); - for ($lineNum = 0; $lineNum < $maxLines; $lineNum++) { $lineContent1 = $lines1[$lineNum] ?? ''; $lineContent2 = $lines2[$lineNum] ?? ''; - if (str_contains($lineContent1, $exceptNumPge) || str_contains($lineContent2, $exceptNumPge)) { - continue; + if (str_contains($lineContent1, $exceptNumPge[0])) { + $linesShouldnChange[] = $lineContent1; + } + if (str_contains($lineContent2, $exceptNumPge[1])) { + $linesShouldnNotChange[] = $lineContent2; } if ($lineContent1 !== $lineContent2) { @@ -1902,6 +1921,13 @@ class Website extends CommonObject } } } + $pairesRemplacement = array(); + foreach ($linesShouldnNotChange as $numLigne => $ligneRemplacement) { + if (isset($linesShouldnChange[$numLigne])) { + $pairesRemplacement[$ligneRemplacement] = $linesShouldnChange[$numLigne]; + } + } + $diff['lignes_dont_change'] = $pairesRemplacement; return $diff; } @@ -1912,12 +1938,13 @@ class Website extends CommonObject * @param array $differences array of differences between files * @return false|int false if we cant replace */ - public function replaceLignEUsingNum($desfFile, $differences) + protected function replaceLignEUsingNum($desfFile, $differences) { - // if (file_exists($desfFile)) { - // dolChmod($desfFile,'766'); - // } - $contentDest = file($desfFile, FILE_IGNORE_NEW_LINES); + if (file_exists($desfFile)) { + dolChmod($desfFile, '0664'); + unset($differences['file_destination']); + } + $contentDest = file($desfFile); foreach ($differences as $key => $ligneSource) { if (preg_match('/(Ajoutée|Modifiée) à la ligne (\d+)/', $key, $matches)) { @@ -1935,10 +1962,13 @@ class Website extends CommonObject } } //Reindex the table keys - $contentDest = array_values($contentDest); $stringreplacement = implode("\n", $contentDest); - file_put_contents($desfFile, $stringreplacement); + foreach ($differences['lignes_dont_change'] as $linechanged => $line) { + if (in_array($linechanged, $contentDest)) { + dolReplaceInFile($desfFile, array($linechanged => $line)); + } + } } } From 52cb80879fd67c38fea766a7028b68bd56791934 Mon Sep 17 00:00:00 2001 From: Lamrani Abdel Date: Wed, 27 Dec 2023 19:24:29 +0100 Subject: [PATCH 06/23] verify permission for files --- htdocs/website/class/website.class.php | 73 ++++++++++++++++---------- 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index a9eb5d56f59..2bdff5673c9 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1656,14 +1656,13 @@ class Website extends CommonObject $destdir = DOL_DOCUMENT_ROOT . '/install/doctemplates/websites/'.$website->name_template; $arraydestdir = dol_dir_list($destdir, "all", 1); $differences = []; - if (count($modifications) >1) { foreach ($modifications as $fichierModifie) { $nomFichierModifie = $fichierModifie['name']; if ($nomFichierModifie == basename($fichierEtat)) { continue; } - + $succes = 0; // Find the corresponding file in the destination folder foreach ($arraydestdir as $destFile) { if ($destFile['name'] == $nomFichierModifie) { @@ -1671,49 +1670,52 @@ class Website extends CommonObject $destContent = file_get_contents($destFile['fullname']); if ($sourceContent !== $destContent) { - $numPage = $this->extractNumberFromFilename($fichierModifie['fullname']); - $differences[$nomFichierModifie] = $this->showDifferences($destContent, $sourceContent, $numPage); - + $differences[$nomFichierModifie] = $this->showDifferences($destContent, $sourceContent); if (count($differences[$nomFichierModifie]) > 0) { $result = $this->replaceLignEUsingNum($destFile['fullname'], $differences[$nomFichierModifie]); if ($result !== false) { - // save state file - $this->saveState($etatPrecedent, $fichierEtat); + if ($result == -2) { + setEventMessages("No permissions to write in file ".$nomFichierModifie." from template ".$website->name_template."", null, 'errors'); + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); + exit(); + } setEventMessages("file ".$nomFichierModifie." was modified in template ".$website->name_template."", null, 'warnings'); - header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); - exit(); } else { setEventMessages("file ".$nomFichierModifie." was not modified", null, 'errors'); } } } - } elseif (preg_match('/page(\d+)\.tpl\.php/', $nomFichierModifie)) { - // TO DO when file has not same name - $succes = 0; + } + if (preg_match('/page(\d+)\.tpl\.php/', $nomFichierModifie)) { $differences[$nomFichierModifie] = $this->compareFichierModifie($sourcedir, $destdir, $fichierModifie); if (count($differences[$nomFichierModifie]) > 0) { $result = $this->replaceLignEUsingNum($differences[$nomFichierModifie]['file_destination']['fullname'], $differences[$nomFichierModifie]); if ($result !== false) { + if ($result == -2) { + setEventMessages("No permissions to write in file ".$nomFichierModifie." from template ".$website->name_template."", null, 'errors'); + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); + exit(); + } $succes++; - } else { - setEventMessages("file ".$nomFichierModifie." was not modified", null, 'errors'); } } } } - if ($succes) { - // save state file - $this->saveState($etatPrecedent, $fichierEtat); - setEventMessages("file ".$differences[$nomFichierModifie]['file_destination']['name']." was modified in template ".$website->name_template."", null, 'warnings'); - header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); - exit(); - } + } + if ($succes>0) { + // save state file + $this->saveState($etatPrecedent, $fichierEtat); + setEventMessages("file ".$differences[$nomFichierModifie]['file_destination']['name']." was modified in template ".$website->name_template."", null, 'warnings'); + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); + exit(); } } else { - setEventMessages("No file has been modified", null, 'warnings'); - header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); - exit(); + setEventMessages("No file has been modified", null, 'errors'); } + // save state file + $this->saveState($etatPrecedent, $fichierEtat); + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); + exit(); } /** @@ -1901,10 +1903,10 @@ class Website extends CommonObject $lineContent1 = $lines1[$lineNum] ?? ''; $lineContent2 = $lines2[$lineNum] ?? ''; - if (str_contains($lineContent1, $exceptNumPge[0])) { + if (strpos($lineContent1, $exceptNumPge[0])) { $linesShouldnChange[] = $lineContent1; } - if (str_contains($lineContent2, $exceptNumPge[1])) { + if (strpos($lineContent2, $exceptNumPge[1])) { $linesShouldnNotChange[] = $lineContent2; } @@ -1940,12 +1942,25 @@ class Website extends CommonObject */ protected function replaceLignEUsingNum($desfFile, $differences) { + $userId = fileowner($desfFile); + if ($userId !== false) { + // Obtain user information from the ID + if (function_exists('posix_getpwuid')&& function_exists('posix_getpwuid')) { + $uid = posix_geteuid(); + $userInfoM = posix_getpwuid($uid); + + $userInfo = posix_getpwuid($userId); + if ($userInfo['uid'] !== $userInfoM['uid']) { + return -2; + } + } + } if (file_exists($desfFile)) { dolChmod($desfFile, '0664'); - unset($differences['file_destination']); } - $contentDest = file($desfFile); - + unset($differences['file_destination']); + $contentDest = file($desfFile, FILE_IGNORE_NEW_LINES); + //var_dump($desfFile);exit; foreach ($differences as $key => $ligneSource) { if (preg_match('/(Ajoutée|Modifiée) à la ligne (\d+)/', $key, $matches)) { $typeModification = $matches[1]; From c08edf237dbcf4958b26df5754101af79c6b90eb Mon Sep 17 00:00:00 2001 From: Lamrani Abdel Date: Fri, 29 Dec 2023 18:35:24 +0100 Subject: [PATCH 07/23] extract num of page and found the correct page in destination --- htdocs/website/class/website.class.php | 61 +++++++++++++++++++------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index 2bdff5673c9..68d8dff6e8f 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1656,6 +1656,7 @@ class Website extends CommonObject $destdir = DOL_DOCUMENT_ROOT . '/install/doctemplates/websites/'.$website->name_template; $arraydestdir = dol_dir_list($destdir, "all", 1); $differences = []; + var_dump($modifications); if (count($modifications) >1) { foreach ($modifications as $fichierModifie) { $nomFichierModifie = $fichierModifie['name']; @@ -1689,10 +1690,11 @@ class Website extends CommonObject if (preg_match('/page(\d+)\.tpl\.php/', $nomFichierModifie)) { $differences[$nomFichierModifie] = $this->compareFichierModifie($sourcedir, $destdir, $fichierModifie); if (count($differences[$nomFichierModifie]) > 0) { + //var_dump($differences[$nomFichierModifie]); $result = $this->replaceLignEUsingNum($differences[$nomFichierModifie]['file_destination']['fullname'], $differences[$nomFichierModifie]); if ($result !== false) { if ($result == -2) { - setEventMessages("No permissions to write in file ".$nomFichierModifie." from template ".$website->name_template."", null, 'errors'); + setEventMessages("No permissions to write in file ".$differences[$nomFichierModifie]['file_destination']['name']." from template ".$website->name_template."", null, 'errors'); header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); exit(); } @@ -1823,10 +1825,15 @@ class Website extends CommonObject $fichiersSource = []; $fichiersDestination = []; + $fichierWithNoPage = []; + $fichierWithNoPageInDest = []; + // filter files source foreach (dol_dir_list($dossierSource, "files") as $file) { if (preg_match('/^page\d+/', $file['name']) && !str_contains($file['name'], '.old')) { $fichiersSource[] = $file; + } else { + $fichierWithNoPage[] = $file; } } @@ -1834,30 +1841,56 @@ class Website extends CommonObject foreach (dol_dir_list($dossierDestination, "all", 1) as $file) { if (preg_match('/^page\d+/', $file['name']) && !str_contains($file['name'], '.old')) { $fichiersDestination[] = $file; + } else { + $fichierWithNoPageInDest[] = $file; } } // find index source and search it in folder destination $numOfPageSource = 0; - $indexModifie = -1; foreach ($fichiersSource as $index => $file) { if ($file['name'] == basename($fichierModifie['fullname'])) { $numOfPageSource = $this->extractNumberFromFilename($file['name']); - $indexModifie = $index; break; } } - if ($indexModifie != -1 && isset($fichiersDestination[$indexModifie])) { - $sameFichier= $fichiersDestination[$indexModifie]['fullname']; + //search numPage where was declared + $fileFounded = array(); + foreach ($fichierWithNoPage as $filesource) { + $fileContent = file_get_contents($filesource['fullname']); + if (strpos($fileContent, "require './page".$numOfPageSource.".tpl.php'") !== false) { + $fileFounded = $filesource; + break; + } + } + // find file with same name and extract num page in destination folder + $numPageFounded = ''; + foreach ($fichierWithNoPageInDest as $filedest) { + if ($filedest['name'] === $fileFounded['name']) { + $fileContent = file_get_contents($filedest['fullname']); + if (preg_match("/page\d+\.tpl\.php/", $fileContent, $matches)) { + $numPageFounded = $matches[0]; + break; + } + } + } + //search file with the number of page founded + $fileNeeded = array(); + foreach ($fichiersDestination as $index => $file) { + if ($file['name'] == $numPageFounded) { + $fileNeeded = $file; + break; + } + } + + if (isset($fileNeeded)) { $sourceContent = file_get_contents($fichierModifie['fullname']); - $destContent = file_get_contents($sameFichier); - - $numOfPageDest = $this->extractNumberFromFilename($sameFichier); + $destContent = file_get_contents($fileNeeded['fullname']); + $numOfPageDest = $this->extractNumberFromFilename($fileNeeded['name']); $differences = $this->showDifferences($destContent, $sourceContent, array($numOfPageDest,$numOfPageSource)); - $differences['file_destination'] = $fichiersDestination[$indexModifie]; - + $differences['file_destination'] = $fileNeeded; return $differences; } return array(); @@ -1870,14 +1903,9 @@ class Website extends CommonObject */ private function normalizeString($str) { - $str = str_replace("\r\n", "\n", $str); $str = str_replace("\r", "\n", $str); - - $lines = explode("\n", $str); - $lines = array_map('trim', $lines); - - return implode("\n", $lines); + return $str; } /** @@ -1960,7 +1988,6 @@ class Website extends CommonObject } unset($differences['file_destination']); $contentDest = file($desfFile, FILE_IGNORE_NEW_LINES); - //var_dump($desfFile);exit; foreach ($differences as $key => $ligneSource) { if (preg_match('/(Ajoutée|Modifiée) à la ligne (\d+)/', $key, $matches)) { $typeModification = $matches[1]; From a5a4d6d0aff6fdb40c40fb9ccc6cf50dbd146038 Mon Sep 17 00:00:00 2001 From: Lamrani Abdel Date: Fri, 29 Dec 2023 18:37:06 +0100 Subject: [PATCH 08/23] remove var_dump --- htdocs/website/class/website.class.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index 68d8dff6e8f..8cd5bd412ee 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1656,7 +1656,7 @@ class Website extends CommonObject $destdir = DOL_DOCUMENT_ROOT . '/install/doctemplates/websites/'.$website->name_template; $arraydestdir = dol_dir_list($destdir, "all", 1); $differences = []; - var_dump($modifications); + if (count($modifications) >1) { foreach ($modifications as $fichierModifie) { $nomFichierModifie = $fichierModifie['name']; @@ -1690,7 +1690,6 @@ class Website extends CommonObject if (preg_match('/page(\d+)\.tpl\.php/', $nomFichierModifie)) { $differences[$nomFichierModifie] = $this->compareFichierModifie($sourcedir, $destdir, $fichierModifie); if (count($differences[$nomFichierModifie]) > 0) { - //var_dump($differences[$nomFichierModifie]); $result = $this->replaceLignEUsingNum($differences[$nomFichierModifie]['file_destination']['fullname'], $differences[$nomFichierModifie]); if ($result !== false) { if ($result == -2) { From a60bc67c515a9c758467afaeb4b21dd99e9a0e30 Mon Sep 17 00:00:00 2001 From: Lamrani Abdel Date: Tue, 2 Jan 2024 17:51:18 +0100 Subject: [PATCH 09/23] correct path image --- htdocs/website/class/website.class.php | 38 ++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index 8cd5bd412ee..2ef78d4a6e7 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1656,7 +1656,7 @@ class Website extends CommonObject $destdir = DOL_DOCUMENT_ROOT . '/install/doctemplates/websites/'.$website->name_template; $arraydestdir = dol_dir_list($destdir, "all", 1); $differences = []; - + //var_dump($modifications);exit; if (count($modifications) >1) { foreach ($modifications as $fichierModifie) { $nomFichierModifie = $fichierModifie['name']; @@ -1925,18 +1925,30 @@ class Website extends CommonObject $linesShouldnChange = array(); $linesShouldnNotChange = array(); + $linefound = array(); + $countNumPage = count($exceptNumPge); + + for ($i = 0;$i< $countNumPage; $i++) { + $linefound[$i]['meta'] = '/content="' . preg_quote($exceptNumPge[$i], '/') . '" \/>/'; + $linefound[$i]['output'] = '/dolWebsiteOutput\(\$tmp, "html", ' . preg_quote($exceptNumPge[$i], '/') . '\);/'; + } + $maxLines = max(count($lines1), count($lines2)); for ($lineNum = 0; $lineNum < $maxLines; $lineNum++) { $lineContent1 = $lines1[$lineNum] ?? ''; $lineContent2 = $lines2[$lineNum] ?? ''; - - if (strpos($lineContent1, $exceptNumPge[0])) { + if (preg_match($linefound[0]['output'], $lineContent1)) { $linesShouldnChange[] = $lineContent1; } - if (strpos($lineContent2, $exceptNumPge[1])) { + if (preg_match($linefound[1]['output'], $lineContent2)) { + $linesShouldnNotChange[] = $lineContent2; + } + if (preg_match($linefound[0]['meta'], $lineContent1)) { + $linesShouldnChange[] = $lineContent1; + } + if (preg_match($linefound[1]['meta'], $lineContent2)) { $linesShouldnNotChange[] = $lineContent2; } - if ($lineContent1 !== $lineContent2) { if (isset($lines1[$lineNum]) && !isset($lines2[$lineNum])) { // Ligne deleted de la source @@ -1950,6 +1962,8 @@ class Website extends CommonObject } } } + + $pairesRemplacement = array(); foreach ($linesShouldnNotChange as $numLigne => $ligneRemplacement) { if (isset($linesShouldnChange[$numLigne])) { @@ -1958,6 +1972,20 @@ class Website extends CommonObject } $diff['lignes_dont_change'] = $pairesRemplacement; + // search path of image and replace it with the correcte path + $pattern = '/medias\/image\/'.$this->ref.'\/([^\'"\s]+)/'; + + foreach ($diff as $key => $value) { + // Assurez-vous que la valeur est une chaîne + if (is_string($value)) { + if (preg_match($pattern, $value)) { + //var_dump( "Trouvé dans".$this->name_template." / ". $key." : ".$value."\n"); + $newValue = preg_replace($pattern, 'medias/image/'.$this->name_template.'/$1', $value); + + $diff[$key] = $newValue; + } + } + } return $diff; } From 64a854bb1d4cb7fbb183c2700be2ca25831ffa34 Mon Sep 17 00:00:00 2001 From: Lamrani Abdel Date: Fri, 5 Jan 2024 19:26:22 +0100 Subject: [PATCH 10/23] fix problem when create new page --- htdocs/website/class/website.class.php | 164 ++++++++++++++++++------- 1 file changed, 119 insertions(+), 45 deletions(-) diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index 2ef78d4a6e7..7b02d600cb2 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1656,50 +1656,114 @@ class Website extends CommonObject $destdir = DOL_DOCUMENT_ROOT . '/install/doctemplates/websites/'.$website->name_template; $arraydestdir = dol_dir_list($destdir, "all", 1); $differences = []; - //var_dump($modifications);exit; - if (count($modifications) >1) { + $names = array_column($arraydestdir, 'name'); + $namesSource = array_column($arraySourcedir, 'name'); + + if (count($modifications) > 1) { foreach ($modifications as $fichierModifie) { $nomFichierModifie = $fichierModifie['name']; if ($nomFichierModifie == basename($fichierEtat)) { continue; } $succes = 0; + + //check if it is a new file + if ((!preg_match('/^page\d+\.tpl\.php$/', $nomFichierModifie)) && (!in_array($nomFichierModifie, $names))) { + if (file_exists($fichierModifie['fullname']) && dol_is_dir($destdir.'/containers')) { + $cp = dol_copy($fichierModifie['fullname'], $destdir.'/containers/'.$nomFichierModifie,'0664'); + if ($cp > 0) { + if (file_exists($destdir.'/containers/'.$nomFichierModifie)){ + $tabnumpage = array(); + foreach ($arraydestdir as $fileDest) { + if ($this->extractNumberFromFilename($fileDest['name']) !== -1) { + $tabnumpage[] = $this->extractNumberFromFilename($fileDest['name']); + } + } + $getContentSource = file_get_contents($destdir.'/containers/'.$nomFichierModifie); + $nextpage = max($tabnumpage) + 1; + $chaineModifiee = preg_replace('/page\d+\.tpl\.php/', 'page' . $nextpage . '.tpl.php', $getContentSource); + $write = file_put_contents($destdir.'/containers/'.$nomFichierModifie, $chaineModifiee); + if ($write !== false) { + if(!touch($destdir.'/containers/'."page" . $nextpage . ".tpl.php")) { + setEventMessages("Please check permission to create page" . $nextpage . ".tpl.php in template ".$website->name_template."", null, 'errors'); + } + $fileFounded = ''; + foreach ($arraySourcedir as $file) { + if ($file['name'] == $nomFichierModifie) { + $fileContent = file_get_contents($file['fullname']); + if (preg_match("/page\d+\.tpl\.php/", $fileContent, $matches)) { + $fileFounded = $matches[0]; + break; + } + } + } + foreach ($arraySourcedir as $file) { + if($file['name'] == $fileFounded) { + if (!is_writable($file['fullname'])){ + dolChmod($file['fullname'],'0664'); + } + $diff = $this->showDifferences(file_get_contents($destdir.'/containers/'."page" . $nextpage . ".tpl.php"),file_get_contents($file['fullname']),array($nextpage,$this->extractNumberFromFilename($file['name']))); + if ($diff != -1) { + $replace = $this->replaceLignEUsingNum($destdir.'/containers/'."page" . $nextpage . ".tpl.php", $diff); + if ($replace !== false) { + setEventMessages("Copy file page".$nextpage.".tpl.php in template ".$this->name_template." with succes", null,'warnings'); + } + } + + } + } + } + + } + $this->saveState($etatPrecedent, $fichierEtat); + setEventMessages("file ".$nomFichierModifie." was created in template ".$website->name_template."", null, 'warnings'); + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); + exit(); + } + } + + + } // Find the corresponding file in the destination folder - foreach ($arraydestdir as $destFile) { - if ($destFile['name'] == $nomFichierModifie) { - $sourceContent = file_get_contents($fichierModifie['fullname']); - $destContent = file_get_contents($destFile['fullname']); - - if ($sourceContent !== $destContent) { - $differences[$nomFichierModifie] = $this->showDifferences($destContent, $sourceContent); + if (in_array($nomFichierModifie, $namesSource)){ + foreach ($arraydestdir as $destFile) { + if ($destFile['name'] == $nomFichierModifie) { + $sourceContent = file_get_contents($fichierModifie['fullname']); + $destContent = file_get_contents($destFile['fullname']); + + if ($sourceContent !== $destContent) { + $differences[$nomFichierModifie] = $this->showDifferences($destContent, $sourceContent); + if (count($differences[$nomFichierModifie]) > 0) { + $result = $this->replaceLignEUsingNum($destFile['fullname'], $differences[$nomFichierModifie]); + if ($result !== false) { + if ($result == -2) { + setEventMessages("No permissions to write in file ".$nomFichierModifie." from template ".$website->name_template."", null, 'errors'); + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); + exit(); + } + setEventMessages("file ".$nomFichierModifie." was modified in template ".$website->name_template."", null, 'warnings'); + } else { + setEventMessages("file ".$nomFichierModifie." was not modified", null, 'errors'); + } + } + } + } + if (preg_match('/page(\d+)\.tpl\.php/', $nomFichierModifie)) { + $differences[$nomFichierModifie] = $this->compareFichierModifie($sourcedir, $destdir, $fichierModifie); if (count($differences[$nomFichierModifie]) > 0) { - $result = $this->replaceLignEUsingNum($destFile['fullname'], $differences[$nomFichierModifie]); + $result = $this->replaceLignEUsingNum($differences[$nomFichierModifie]['file_destination']['fullname'], $differences[$nomFichierModifie]); if ($result !== false) { if ($result == -2) { - setEventMessages("No permissions to write in file ".$nomFichierModifie." from template ".$website->name_template."", null, 'errors'); + setEventMessages("No permissions to write in file ".$differences[$nomFichierModifie]['file_destination']['name']." from template ".$website->name_template."", null, 'errors'); header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); exit(); } - setEventMessages("file ".$nomFichierModifie." was modified in template ".$website->name_template."", null, 'warnings'); - } else { - setEventMessages("file ".$nomFichierModifie." was not modified", null, 'errors'); + $succes++; } } } - } - if (preg_match('/page(\d+)\.tpl\.php/', $nomFichierModifie)) { - $differences[$nomFichierModifie] = $this->compareFichierModifie($sourcedir, $destdir, $fichierModifie); - if (count($differences[$nomFichierModifie]) > 0) { - $result = $this->replaceLignEUsingNum($differences[$nomFichierModifie]['file_destination']['fullname'], $differences[$nomFichierModifie]); - if ($result !== false) { - if ($result == -2) { - setEventMessages("No permissions to write in file ".$differences[$nomFichierModifie]['file_destination']['name']." from template ".$website->name_template."", null, 'errors'); - header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); - exit(); - } - $succes++; - } - } + + } } } @@ -1885,11 +1949,13 @@ class Website extends CommonObject if (isset($fileNeeded)) { $sourceContent = file_get_contents($fichierModifie['fullname']); - $destContent = file_get_contents($fileNeeded['fullname']); - - $numOfPageDest = $this->extractNumberFromFilename($fileNeeded['name']); - $differences = $this->showDifferences($destContent, $sourceContent, array($numOfPageDest,$numOfPageSource)); - $differences['file_destination'] = $fileNeeded; + if (file_exists($fileNeeded['fullname'])) { + $destContent = file_get_contents($fileNeeded['fullname']); + + $numOfPageDest = $this->extractNumberFromFilename($fileNeeded['name']); + $differences = $this->showDifferences($destContent, $sourceContent, array($numOfPageDest,$numOfPageSource)); + $differences['file_destination'] = $fileNeeded; + } return $differences; } return array(); @@ -1940,12 +2006,12 @@ class Website extends CommonObject if (preg_match($linefound[0]['output'], $lineContent1)) { $linesShouldnChange[] = $lineContent1; } - if (preg_match($linefound[1]['output'], $lineContent2)) { - $linesShouldnNotChange[] = $lineContent2; - } if (preg_match($linefound[0]['meta'], $lineContent1)) { $linesShouldnChange[] = $lineContent1; } + if (preg_match($linefound[1]['output'], $lineContent2)) { + $linesShouldnNotChange[] = $lineContent2; + } if (preg_match($linefound[1]['meta'], $lineContent2)) { $linesShouldnNotChange[] = $lineContent2; } @@ -1964,14 +2030,24 @@ class Website extends CommonObject } - $pairesRemplacement = array(); - foreach ($linesShouldnNotChange as $numLigne => $ligneRemplacement) { - if (isset($linesShouldnChange[$numLigne])) { - $pairesRemplacement[$ligneRemplacement] = $linesShouldnChange[$numLigne]; - } + if (empty($linesShouldnChange)) { + $linesShouldnChange[0] = ''; + $linesShouldnChange[1] = '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp, "html", '.$exceptNumPge[0].');'; } - $diff['lignes_dont_change'] = $pairesRemplacement; + $pairesRemplacement = array(); + if (!empty($linesShouldnNotChange)) { + $i =0; + foreach ($linesShouldnNotChange as $numLigne => $ligneRemplacement) { + if (isset($linesShouldnChange[$numLigne])) { + $pairesRemplacement[$ligneRemplacement] = $linesShouldnChange[$numLigne]; + }else { + $pairesRemplacement[$ligneRemplacement] = $linesShouldnChange[$i]; + } + $i++; + } + $diff['lignes_dont_change'] = $pairesRemplacement; + } // search path of image and replace it with the correcte path $pattern = '/medias\/image\/'.$this->ref.'\/([^\'"\s]+)/'; @@ -1979,9 +2055,7 @@ class Website extends CommonObject // Assurez-vous que la valeur est une chaîne if (is_string($value)) { if (preg_match($pattern, $value)) { - //var_dump( "Trouvé dans".$this->name_template." / ". $key." : ".$value."\n"); - $newValue = preg_replace($pattern, 'medias/image/'.$this->name_template.'/$1', $value); - + $newValue = preg_replace($pattern, 'medias/image/'.$this->name_template.'/$1', $value); $diff[$key] = $newValue; } } From 5f4e5844253cbe3b588137e52ae3bbe6823b30e5 Mon Sep 17 00:00:00 2001 From: Lamrani Abdel Date: Fri, 5 Jan 2024 19:26:27 +0100 Subject: [PATCH 11/23] fix problem when create new page --- htdocs/website/class/website.class.php | 40 +++++++++++--------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index 7b02d600cb2..1825d66322a 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1666,13 +1666,13 @@ class Website extends CommonObject continue; } $succes = 0; - - //check if it is a new file + + //check if it is a new file if ((!preg_match('/^page\d+\.tpl\.php$/', $nomFichierModifie)) && (!in_array($nomFichierModifie, $names))) { if (file_exists($fichierModifie['fullname']) && dol_is_dir($destdir.'/containers')) { - $cp = dol_copy($fichierModifie['fullname'], $destdir.'/containers/'.$nomFichierModifie,'0664'); + $cp = dol_copy($fichierModifie['fullname'], $destdir.'/containers/'.$nomFichierModifie, '0664'); if ($cp > 0) { - if (file_exists($destdir.'/containers/'.$nomFichierModifie)){ + if (file_exists($destdir.'/containers/'.$nomFichierModifie)) { $tabnumpage = array(); foreach ($arraydestdir as $fileDest) { if ($this->extractNumberFromFilename($fileDest['name']) !== -1) { @@ -1684,7 +1684,7 @@ class Website extends CommonObject $chaineModifiee = preg_replace('/page\d+\.tpl\.php/', 'page' . $nextpage . '.tpl.php', $getContentSource); $write = file_put_contents($destdir.'/containers/'.$nomFichierModifie, $chaineModifiee); if ($write !== false) { - if(!touch($destdir.'/containers/'."page" . $nextpage . ".tpl.php")) { + if (!touch($destdir.'/containers/'."page" . $nextpage . ".tpl.php")) { setEventMessages("Please check permission to create page" . $nextpage . ".tpl.php in template ".$website->name_template."", null, 'errors'); } $fileFounded = ''; @@ -1698,22 +1698,20 @@ class Website extends CommonObject } } foreach ($arraySourcedir as $file) { - if($file['name'] == $fileFounded) { - if (!is_writable($file['fullname'])){ - dolChmod($file['fullname'],'0664'); + if ($file['name'] == $fileFounded) { + if (!is_writable($file['fullname'])) { + dolChmod($file['fullname'], '0664'); } - $diff = $this->showDifferences(file_get_contents($destdir.'/containers/'."page" . $nextpage . ".tpl.php"),file_get_contents($file['fullname']),array($nextpage,$this->extractNumberFromFilename($file['name']))); + $diff = $this->showDifferences(file_get_contents($destdir.'/containers/'."page" . $nextpage . ".tpl.php"), file_get_contents($file['fullname']), array($nextpage,$this->extractNumberFromFilename($file['name']))); if ($diff != -1) { $replace = $this->replaceLignEUsingNum($destdir.'/containers/'."page" . $nextpage . ".tpl.php", $diff); if ($replace !== false) { - setEventMessages("Copy file page".$nextpage.".tpl.php in template ".$this->name_template." with succes", null,'warnings'); + setEventMessages("Copy file page".$nextpage.".tpl.php in template ".$this->name_template." with succes", null, 'warnings'); } } - } } } - } $this->saveState($etatPrecedent, $fichierEtat); setEventMessages("file ".$nomFichierModifie." was created in template ".$website->name_template."", null, 'warnings'); @@ -1721,16 +1719,14 @@ class Website extends CommonObject exit(); } } - - } // Find the corresponding file in the destination folder - if (in_array($nomFichierModifie, $namesSource)){ + if (in_array($nomFichierModifie, $namesSource)) { foreach ($arraydestdir as $destFile) { if ($destFile['name'] == $nomFichierModifie) { $sourceContent = file_get_contents($fichierModifie['fullname']); $destContent = file_get_contents($destFile['fullname']); - + if ($sourceContent !== $destContent) { $differences[$nomFichierModifie] = $this->showDifferences($destContent, $sourceContent); if (count($differences[$nomFichierModifie]) > 0) { @@ -1762,8 +1758,6 @@ class Website extends CommonObject } } } - - } } } @@ -1951,11 +1945,11 @@ class Website extends CommonObject $sourceContent = file_get_contents($fichierModifie['fullname']); if (file_exists($fileNeeded['fullname'])) { $destContent = file_get_contents($fileNeeded['fullname']); - + $numOfPageDest = $this->extractNumberFromFilename($fileNeeded['name']); $differences = $this->showDifferences($destContent, $sourceContent, array($numOfPageDest,$numOfPageSource)); $differences['file_destination'] = $fileNeeded; - } + } return $differences; } return array(); @@ -2041,13 +2035,13 @@ class Website extends CommonObject foreach ($linesShouldnNotChange as $numLigne => $ligneRemplacement) { if (isset($linesShouldnChange[$numLigne])) { $pairesRemplacement[$ligneRemplacement] = $linesShouldnChange[$numLigne]; - }else { + } else { $pairesRemplacement[$ligneRemplacement] = $linesShouldnChange[$i]; } $i++; } $diff['lignes_dont_change'] = $pairesRemplacement; - } + } // search path of image and replace it with the correcte path $pattern = '/medias\/image\/'.$this->ref.'\/([^\'"\s]+)/'; @@ -2055,7 +2049,7 @@ class Website extends CommonObject // Assurez-vous que la valeur est une chaîne if (is_string($value)) { if (preg_match($pattern, $value)) { - $newValue = preg_replace($pattern, 'medias/image/'.$this->name_template.'/$1', $value); + $newValue = preg_replace($pattern, 'medias/image/'.$this->name_template.'/$1', $value); $diff[$key] = $newValue; } } From bfae93b3b34afac43723fba00254aec6232bd4cf Mon Sep 17 00:00:00 2001 From: Lamrani Abdel Date: Sat, 6 Jan 2024 19:48:11 +0100 Subject: [PATCH 12/23] fix rights for exportwebsite --- htdocs/website/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 1e33b30f470..fa3c34860bb 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -2399,7 +2399,7 @@ if ($usercanedit && (($action == 'updatesource' || $action == 'updatecontent' || } // Export site -if ($action == 'exportsite') { +if ($action == 'exportsite' && $user->hasRight('website', 'export')) { $fileofzip = $object->exportWebSite(); if ($fileofzip) { From 69289f5005072c4b1bb439beb6831ef1f5c71ed0 Mon Sep 17 00:00:00 2001 From: Hystepik Date: Fri, 26 Jan 2024 15:41:13 +0100 Subject: [PATCH 13/23] New hook to allow module show onlinepaymenturl --- htdocs/adherents/card.php | 8 ++++++++ htdocs/adherents/subscription.php | 8 ++++++++ htdocs/commande/card.php | 9 +++++++++ htdocs/compta/facture/card.php | 8 ++++++++ htdocs/core/modules/facture/doc/pdf_crabe.modules.php | 9 ++++++++- htdocs/core/modules/facture/doc/pdf_sponge.modules.php | 9 ++++++++- htdocs/don/card.php | 8 ++++++++ 7 files changed, 57 insertions(+), 2 deletions(-) diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index 1af279d33d4..7f41b76e564 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -2069,6 +2069,14 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { // Show online payment link $useonlinepayment = (isModEnabled('paypal') || isModEnabled('stripe') || isModEnabled('paybox')); + $parameters = array(); + $reshook = $hookmanager->executeHooks('doShowOnlinePaymentUrl', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } else { + $useonlinepayment = $reshook; + } + if ($useonlinepayment) { print '
'; if (empty($amount)) { // Take the maximum amount among what the member is supposed to pay / has paid in the past diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index 7c6647835d8..3d479cd23c6 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -825,6 +825,14 @@ if (($action != 'addsubscription' && $action != 'create_thirdparty')) { // Shon online payment link $useonlinepayment = (isModEnabled('paypal') || isModEnabled('stripe') || isModEnabled('paybox')); + $parameters = array(); + $reshook = $hookmanager->executeHooks('doShowOnlinePaymentUrl', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + if (isset($hookmanager->resArray['showonlinepaymenturl'])) { + $useonlinepayment = $hookmanager->resArray['showonlinepaymenturl']; + } + } + if ($useonlinepayment) { print '
'; diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index fc72d6a7f8a..cae96460a93 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -3090,6 +3090,15 @@ if ($action == 'create' && $usercancreate) { // Show online payment link $useonlinepayment = (isModEnabled('paypal') || isModEnabled('stripe') || isModEnabled('paybox')); + + $parameters = array(); + $reshook = $hookmanager->executeHooks('doShowOnlinePaymentUrl', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + if (isset($hookmanager->resArray['showonlinepaymenturl'])) { + $useonlinepayment = $hookmanager->resArray['showonlinepaymenturl']; + } + } + if (getDolGlobalString('ORDER_HIDE_ONLINE_PAYMENT_ON_ORDER')) { $useonlinepayment = 0; } diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 64d2f2637ae..55f4876fee2 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -5993,6 +5993,14 @@ if ($action == 'create') { // Show online payment link $useonlinepayment = (isModEnabled('paypal') || isModEnabled('stripe') || isModEnabled('paybox')); + $parameters = array(); + $reshook = $hookmanager->executeHooks('doShowOnlinePaymentUrl', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + if (isset($hookmanager->resArray['showonlinepaymenturl'])) { + $useonlinepayment = $hookmanager->resArray['showonlinepaymenturl']; + } + } + if ($object->status != Facture::STATUS_DRAFT && $useonlinepayment) { print '
'."\n"; require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index 6c58f02900a..13df1c7b90c 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -1111,7 +1111,7 @@ class pdf_crabe extends ModelePDFFactures protected function _tableau_info(&$pdf, $object, $posy, $outputlangs, $outputlangsbis) { // phpcs:enable - global $conf, $mysoc; + global $conf, $mysoc, $hookmanager; $default_font_size = pdf_getPDFFontSize($outputlangs); @@ -1238,6 +1238,13 @@ class pdf_crabe extends ModelePDFFactures if (isModEnabled('paybox')) { $useonlinepayment++; } + $parameters = array(); + $reshook = $hookmanager->executeHooks('doShowOnlinePaymentUrl', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + if (isset($hookmanager->resArray['showonlinepaymenturl'])) { + $useonlinepayment += $hookmanager->resArray['showonlinepaymenturl']; + } + } } if ($object->statut != Facture::STATUS_DRAFT && $useonlinepayment) { diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php index 1d6b8104d87..1a3db19bab3 100644 --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -1204,7 +1204,7 @@ class pdf_sponge extends ModelePDFFactures */ protected function drawInfoTable(&$pdf, $object, $posy, $outputlangs, $outputlangsbis) { - global $conf, $mysoc; + global $conf, $mysoc, $hookmanager; $default_font_size = pdf_getPDFFontSize($outputlangs); @@ -1333,6 +1333,13 @@ class pdf_sponge extends ModelePDFFactures if (isModEnabled('paybox')) { $useonlinepayment++; } + $parameters = array(); + $reshook = $hookmanager->executeHooks('doShowOnlinePaymentUrl', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + if (isset($hookmanager->resArray['showonlinepaymenturl'])) { + $useonlinepayment += $hookmanager->resArray['showonlinepaymenturl']; + } + } } diff --git a/htdocs/don/card.php b/htdocs/don/card.php index 44e5b207156..a9ffd884b5e 100644 --- a/htdocs/don/card.php +++ b/htdocs/don/card.php @@ -974,6 +974,14 @@ if (!empty($id) && $action != 'edit') { // Show online payment link $useonlinepayment = (isModEnabled('paypal') || isModEnabled('stripe') || isModEnabled('paybox')); + $parameters = array(); + $reshook = $hookmanager->executeHooks('doShowOnlinePaymentUrl', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + if (isset($hookmanager->resArray['showonlinepaymenturl'])) { + $useonlinepayment += $hookmanager->resArray['showonlinepaymenturl']; + } + } + if ($useonlinepayment) { //$object->statut != Facture::STATUS_DRAFT && print '
'."\n"; require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; From 47c98623f4a986923f93c1f00f781abcc3195e66 Mon Sep 17 00:00:00 2001 From: Hystepik Date: Fri, 26 Jan 2024 15:58:22 +0100 Subject: [PATCH 14/23] fix php errors --- htdocs/core/modules/facture/doc/pdf_crabe.modules.php | 1 + htdocs/core/modules/facture/doc/pdf_sponge.modules.php | 1 + 2 files changed, 2 insertions(+) diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index 13df1c7b90c..6ac14a96489 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -1239,6 +1239,7 @@ class pdf_crabe extends ModelePDFFactures $useonlinepayment++; } $parameters = array(); + $action = ''; $reshook = $hookmanager->executeHooks('doShowOnlinePaymentUrl', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { if (isset($hookmanager->resArray['showonlinepaymenturl'])) { diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php index 1a3db19bab3..7f54da1fd99 100644 --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -1334,6 +1334,7 @@ class pdf_sponge extends ModelePDFFactures $useonlinepayment++; } $parameters = array(); + $action = ''; $reshook = $hookmanager->executeHooks('doShowOnlinePaymentUrl', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { if (isset($hookmanager->resArray['showonlinepaymenturl'])) { From 1d0a6411bc67314d0a2ffca1a5a544c61df43460 Mon Sep 17 00:00:00 2001 From: thibdrev Date: Sat, 27 Jan 2024 14:09:04 +0100 Subject: [PATCH 15/23] qual: add phpunit tests for profid.lib.php --- test/phpunit/AllTests.php | 2 + test/phpunit/ProfidLibTest.php | 283 +++++++++++++++++++++++++++++++++ 2 files changed, 285 insertions(+) create mode 100644 test/phpunit/ProfidLibTest.php diff --git a/test/phpunit/AllTests.php b/test/phpunit/AllTests.php index 5a5c2f48b02..965ea8a2ce7 100644 --- a/test/phpunit/AllTests.php +++ b/test/phpunit/AllTests.php @@ -99,6 +99,8 @@ class AllTests $suite->addTestSuite('FunctionsLibTest'); require_once dirname(__FILE__).'/Functions2LibTest.php'; $suite->addTestSuite('Functions2LibTest'); + require_once dirname(__FILE__).'/ProfidLibTest.php.php'; + $suite->addTestSuite('ProfidLibTest'); require_once dirname(__FILE__).'/XCalLibTest.php'; $suite->addTestSuite('XCalLibTest'); diff --git a/test/phpunit/ProfidLibTest.php b/test/phpunit/ProfidLibTest.php new file mode 100644 index 00000000000..c0735e7c71b --- /dev/null +++ b/test/phpunit/ProfidLibTest.php @@ -0,0 +1,283 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file test/phpunit/ProfidLibTest.php + * \ingroup test + * \brief PHPUnit test + * \remarks To run this script as CLI: phpunit filename.php + */ + +global $conf,$user,$langs,$db,$mysoc; +//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver +//require_once 'PHPUnit/Autoload.php'; +require_once dirname(__FILE__).'/../../htdocs/master.inc.php'; +require_once dirname(__FILE__).'/../../htdocs/core/lib/profid.lib.php'; + +if (! defined('NOREQUIREUSER')) { + define('NOREQUIREUSER', '1'); +} +if (! defined('NOREQUIREDB')) { + define('NOREQUIREDB', '1'); +} +if (! defined('NOREQUIRESOC')) { + define('NOREQUIRESOC', '1'); +} +if (! defined('NOREQUIRETRAN')) { + define('NOREQUIRETRAN', '1'); +} +if (! defined('NOCSRFCHECK')) { + define('NOCSRFCHECK', '1'); +} +if (! defined('NOTOKENRENEWAL')) { + define('NOTOKENRENEWAL', '1'); +} +if (! defined('NOREQUIREMENU')) { + define('NOREQUIREMENU', '1'); // If there is no menu to show +} +if (! defined('NOREQUIREHTML')) { + define('NOREQUIREHTML', '1'); // If we don't need to load the html.form.class.php +} +if (! defined('NOREQUIREAJAX')) { + define('NOREQUIREAJAX', '1'); +} +if (! defined("NOLOGIN")) { + define("NOLOGIN", '1'); // If this page is public (can be called outside logged session) +} + + + +/** + * Class for PHPUnit tests + * + * @backupGlobals disabled + * @backupStaticAttributes enabled + * @remarks backupGlobals must be disabled to have db,conf,user and lang not erased. + */ +class ProfidLibTest extends PHPUnit\Framework\TestCase +{ + protected $savconf; + protected $savuser; + protected $savlangs; + protected $savdb; + + /** + * Constructor + * We save global variables into local variables + * + * @param string $name Name + * @return CoreTest + */ + public function __construct($name = '') + { + parent::__construct($name); + + //$this->sharedFixture + global $conf,$user,$langs,$db; + $this->savconf=$conf; + $this->savuser=$user; + $this->savlangs=$langs; + $this->savdb=$db; + + print __METHOD__." db->type=".$db->type." user->id=".$user->id; + //print " - db ".$db->db; + print "\n"; + } + + /** + * setUpBeforeClass + * + * @return void + */ + public static function setUpBeforeClass(): void + { + global $conf,$user,$langs,$db; + //$db->begin(); // This is to have all actions inside a transaction even if test launched without suite. + + print __METHOD__."\n"; + } + + /** + * tearDownAfterClass + * + * @return void + */ + public static function tearDownAfterClass(): void + { + global $conf,$user,$langs,$db; + //$db->rollback(); + + print __METHOD__."\n"; + } + + /** + * Init phpunit tests. Restore variables before each test. + * + * @return void + */ + protected function setUp(): void + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + //$db=$this->savdb; + + print __METHOD__."\n"; + } + + /** + * End phpunit tests + * + * @return void + */ + protected function tearDown(): void + { + print __METHOD__."\n"; + } + + + + /** + * testIsValidLuhn + * + * @return void + */ + public function testIsValidLuhn() + { + // Tests OK + $this->assertTrue(isValidLuhn(972487086)); // int + $this->assertTrue(isValidLuhn("972487086")); // string + // Tests KO + $this->assertFalse(isValidLuhn(123456789)); // int + $this->assertFalse(isValidLuhn("123456789")); // string + } + + + + /** + * testIsValidSiren + * + * @return void + */ + public function testIsValidSiren() + { + // Tests OK + $this->assertTrue(isValidSiren("732829320")); + $this->assertTrue(isValidSiren(" 732 829 320 ")); // formatted with spaces + // Tests NOK + $this->assertFalse(isValidSiren("123456ABC")); // not numeric + $this->assertFalse(isValidSiren("43336767")); // Luhn test OK but length != 9 + $this->assertFalse(isValidSiren("123456789")); // 9 digits but Luhn test KO + } + + + + /** + * testIsValidSiret + * + * @return void + */ + public function testIsValidSiret() + { + // Tests OK + $this->assertTrue(isValidSiret("73282932000074")); + $this->assertTrue(isValidSiret(" 732 829 320 00074 ")); // formatted with spaces + $this->assertTrue(isValidSiret("35600000049837")); // Specific cases of "La Poste" companies + // Tests NOK + $this->assertFalse(isValidSiret("123456ABC12345")); // not numeric + $this->assertFalse(isValidSiret("3624679471379")); // Luhn test OK but length != 14 + $this->assertFalse(isValidSiret("12345678912345")); // 14 digits but Luhn test KO + } + + + + /** + * testIsValidTinForPT + * + * @return void + */ + public function testIsValidTinForPT() + { + // Tests OK + $this->assertTrue(isValidTinForPT("123456789")); + $this->assertTrue(isValidTinForPT(" 123 456 789 ")); // formatted with spaces + // Tests NOK + $this->assertFalse(isValidTinForPT("123456ABC")); // not numeric + $this->assertFalse(isValidTinForPT("12345678")); // length != 9 + } + + + + /** + * testIsValidTinForDZ + * + * @return void + */ + public function testIsValidTinForDZ() + { + // Tests OK + $this->assertTrue(isValidTinForDZ("123456789123456")); + $this->assertTrue(isValidTinForDZ(" 12345 67891 23456 ")); // formatted with spaces + // Tests NOK + $this->assertFalse(isValidTinForDZ("123456789123ABC")); // not numeric + $this->assertFalse(isValidTinForDZ("123456789123")); // length != 15 + } + + + + /** + * testIsValidTinForBE + * + * @return void + */ + public function testIsValidTinForBE() + { + // Tests OK + $this->assertTrue(isValidTinForBE("0123.123.123")); + $this->assertTrue(isValidTinForBE("1234.123.123")); + // Tests NOK + //$this->assertFalse(isValidTinForBE("2345.123.123")); // First digit shall be 0 or 1 + $this->assertFalse(isValidTinForBE("1234 123 123")); // formatted with spaces instead of dots + $this->assertFalse(isValidTinForBE("1234123123")); // without dots formatting + $this->assertFalse(isValidTinForBE("ABCD.123.123")); // not digits only + } + + // TODO + /** + * testIsValidTinForES + * + * @return void + */ + /* + public function testIsValidTinForES() + { + // Tests for NIF + $this->assertEquals(1, isValidTinForES("")); // valid NIF + $this->assertEquals(-1, isValidTinForES("")); // valid regex, but invalid control key + // Tests for CIF + $this->assertEquals(2, isValidTinForES("")); // valid CIF + $this->assertEquals(-2, isValidTinForES("")); // valid regex, but invalid control key + // Tests for NIE + $this->assertEquals(3, isValidTinForES("")); // valid NIE + $this->assertEquals(-3, isValidTinForES("")); // valid regex, but invalid control key + // Tests for unknown error + $this->assertEquals(-4, isValidTinForES("")); // invalid regex for both NIF, CIF and NIE + } + */ +} From 49461846484497422846a229820154ea7c4d0ff3 Mon Sep 17 00:00:00 2001 From: thibdrev Date: Sat, 27 Jan 2024 14:15:16 +0100 Subject: [PATCH 16/23] phpcs --- test/phpunit/ProfidLibTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/phpunit/ProfidLibTest.php b/test/phpunit/ProfidLibTest.php index c0735e7c71b..fdaacbb13eb 100644 --- a/test/phpunit/ProfidLibTest.php +++ b/test/phpunit/ProfidLibTest.php @@ -269,13 +269,13 @@ class ProfidLibTest extends PHPUnit\Framework\TestCase { // Tests for NIF $this->assertEquals(1, isValidTinForES("")); // valid NIF - $this->assertEquals(-1, isValidTinForES("")); // valid regex, but invalid control key + $this->assertEquals(-1, isValidTinForES("")); // valid regex, but invalid control key // Tests for CIF $this->assertEquals(2, isValidTinForES("")); // valid CIF - $this->assertEquals(-2, isValidTinForES("")); // valid regex, but invalid control key + $this->assertEquals(-2, isValidTinForES("")); // valid regex, but invalid control key // Tests for NIE $this->assertEquals(3, isValidTinForES("")); // valid NIE - $this->assertEquals(-3, isValidTinForES("")); // valid regex, but invalid control key + $this->assertEquals(-3, isValidTinForES("")); // valid regex, but invalid control key // Tests for unknown error $this->assertEquals(-4, isValidTinForES("")); // invalid regex for both NIF, CIF and NIE } From e0b35d2f6bff50d802739cdc9b400fb448ca57ec Mon Sep 17 00:00:00 2001 From: thibdrev Date: Sat, 27 Jan 2024 23:24:01 +0100 Subject: [PATCH 17/23] typo --- test/phpunit/AllTests.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/phpunit/AllTests.php b/test/phpunit/AllTests.php index 965ea8a2ce7..7dd60f8431e 100644 --- a/test/phpunit/AllTests.php +++ b/test/phpunit/AllTests.php @@ -99,7 +99,7 @@ class AllTests $suite->addTestSuite('FunctionsLibTest'); require_once dirname(__FILE__).'/Functions2LibTest.php'; $suite->addTestSuite('Functions2LibTest'); - require_once dirname(__FILE__).'/ProfidLibTest.php.php'; + require_once dirname(__FILE__).'/ProfidLibTest.php'; $suite->addTestSuite('ProfidLibTest'); require_once dirname(__FILE__).'/XCalLibTest.php'; $suite->addTestSuite('XCalLibTest'); From 05422868dc10dec88675257086065607076b763e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 28 Jan 2024 14:52:35 +0100 Subject: [PATCH 18/23] Fix codespell --- ChangeLog | 7 ------- htdocs/webportal/README.md | 8 +++----- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9b9664a1cf6..b19c131511e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -187,15 +187,8 @@ NEW: updating for display Help title when try to delete Don (issue #25314) NEW: Upgrade in module builder in menu section NEW: use account address in sepa mandate (#23642) NEW: VAT rate - Add entity -<<<<<<< HEAD -NEW: webportal site account NEW: When an user unset the batch management of products, transformation of each batch stock movement in global stock movement - -FIX: #25828 wrong odt style naming -======= -NEW: When an user unset the batch management of products, transformation of each batch stock mouvement in global stock mouvement NEW: PDF Generation for each Human Resource Evaluations. ->>>>>>> branch '19.0' of git@github.com:Dolibarr/dolibarr.git SEC: #25512 applicative anti bruteforce - security on too many login attempts (#25520) SEC: Add action confirm_... as sensitive to need a CSRF token diff --git a/htdocs/webportal/README.md b/htdocs/webportal/README.md index 0dddedea0eb..3d7e82ccbc2 100644 --- a/htdocs/webportal/README.md +++ b/htdocs/webportal/README.md @@ -3,7 +3,7 @@ Module Web Portal This is a module to provide a ready to use Web Portal for your customers, suppliers, partners or members of the mebership module. -Accounts (login and pass) to acces this portal can be created for any thirdparty (from the tab "Web site accounts"). +Accounts (login and pass) to access this portal can be created for any thirdparty (from the tab "Web site accounts"). It is better to have a standalone web server with its own virtual host and domain name to use this module, so using the web portal does not reaveal the domain and url of your backoffice installation. @@ -15,8 +15,8 @@ If the Thirdparty module is enabled: * Read/modify Name, phone, email, addresses of thirdparty If the Patnership module is enabled: -* Read properties (status, stard date, end date) of its partnership. - +* Read properties (status, start date, end date) of its partnership. + If the Proposal module is enabled: * Read its orders @@ -41,5 +41,3 @@ Documentation ------------- [Module Web Portal](https://wiki.dolibarr.org/index.php/Module_Web_Portal) - - \ No newline at end of file From 92cf4f2fd1ae52ea63376b237761a80cea1464d9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 28 Jan 2024 16:36:01 +0100 Subject: [PATCH 19/23] Mutualize code --- htdocs/admin/ticket_public.php | 6 +++--- htdocs/core/modules/modWebPortal.class.php | 2 ++ htdocs/langs/en_US/admin.lang | 2 ++ htdocs/langs/en_US/ticket.lang | 2 -- htdocs/langs/en_US/website.lang | 2 -- htdocs/langs/fr_FR/admin.lang | 1 + htdocs/langs/fr_FR/ticket.lang | 1 - htdocs/webportal/admin/configcss.php | 2 +- htdocs/webportal/admin/setup.php | 8 ++++---- htdocs/webportal/admin/setup_theme.php | 2 +- htdocs/website/index.php | 14 +++++++++----- 11 files changed, 23 insertions(+), 19 deletions(-) diff --git a/htdocs/admin/ticket_public.php b/htdocs/admin/ticket_public.php index e083c87d205..e58b0599b76 100644 --- a/htdocs/admin/ticket_public.php +++ b/htdocs/admin/ticket_public.php @@ -476,12 +476,12 @@ if (getDolGlobalInt('TICKET_ENABLE_PUBLIC_INTERFACE')) { // Url public interface $url_interface = getDolGlobalString("TICKET_URL_PUBLIC_INTERFACE"); - print ''.$langs->trans("TicketUrlPublicInterfaceLabelAdmin").''; + print ''.$langs->trans("UrlPublicInterfaceLabelAdmin").''; print ''; - print ''; + print ''; print ''; print ''; - print $form->textwithpicto('', $langs->trans("TicketUrlPublicInterfaceHelpAdmin"), 1, 'help'); + print $form->textwithpicto('', $langs->trans("UrlPublicInterfaceHelpAdmin"), 1, 'help'); print ''; print ''; diff --git a/htdocs/core/modules/modWebPortal.class.php b/htdocs/core/modules/modWebPortal.class.php index 6bd2885f31a..99f31d1907f 100644 --- a/htdocs/core/modules/modWebPortal.class.php +++ b/htdocs/core/modules/modWebPortal.class.php @@ -280,6 +280,7 @@ class modWebPortal extends DolibarrModules $this->menu = array(); $r = 0; // Add here entries to declare new menus + /* $this->menu[$r++] = array( 'fk_menu' => '', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'type' => 'top', // This is a Top menu entry @@ -295,6 +296,7 @@ class modWebPortal extends DolibarrModules 'target' => '', 'user' => 2, // 0=Menu for internal users, 1=external users, 2=both ); + */ /*$this->menu[$r++]=array( 'fk_menu'=>'fk_mainmenu=webportal', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'type'=>'left', // This is a Left menu entry diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index fac5f950a30..1a8c9492605 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2437,3 +2437,5 @@ ParametersForTestEnvironment=Parameters for test environment TryToKeepOnly=Try to keep only %s RecommendedForProduction=Recommended for Production RecommendedForDebug=Recommended for Debug +UrlPublicInterfaceLabelAdmin=Alternative URL for public interface +UrlPublicInterfaceHelpAdmin=It is possible to define an alias to the web server and thus make available the public interface with another URL (the virtual host server must act as a proxy on the standard URL) diff --git a/htdocs/langs/en_US/ticket.lang b/htdocs/langs/en_US/ticket.lang index 460e73e1cf1..e1493e9c14b 100644 --- a/htdocs/langs/en_US/ticket.lang +++ b/htdocs/langs/en_US/ticket.lang @@ -107,8 +107,6 @@ TicketsShowProgressionHelp=Enable this option to hide the progress of the ticket TicketCreateThirdPartyWithContactIfNotExist=Ask name and company name for unknown emails. TicketCreateThirdPartyWithContactIfNotExistHelp=Check if a third party or a contact exists for the email entered. If not, ask a name and a company name to create a third party with contact. PublicInterface=Public interface -TicketUrlPublicInterfaceLabelAdmin=Alternative URL for public interface -TicketUrlPublicInterfaceHelpAdmin=It is possible to define an alias to the web server and thus make available the public interface with another URL (the server must act as a proxy on this new URL) TicketPublicInterfaceTextHomeLabelAdmin=Welcome text of the public interface TicketPublicInterfaceTextHome=You can create a support ticket or view existing from its identifier tracking ticket. TicketPublicInterfaceTextHomeHelpAdmin=The text defined here will appear on the home page of the public interface. diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang index 1b076f689b4..6d457dfb33b 100644 --- a/htdocs/langs/en_US/website.lang +++ b/htdocs/langs/en_US/website.lang @@ -174,8 +174,6 @@ WebPortalSetup = WebPortal setup WebPortalCSS=Web portal CSS Settings = Settings WebPortalSetupPage = WebPortal setup page -WEBPORTAL_ROOT_URL = Alternative virtual host URL -WebPortalRootUrlHelp = Public access url (http or https) if you have a virtual host or keep empty WEBPORTAL_TITLE = Brand name on header of public page UserAccountForWebPortalAreInThirdPartyTabHelp = Users accounts for WebPortal can be set on each third party card in Website accounts tab WebPortalAccessHidden = Hidden diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index b9876492cdd..9864434ff14 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -2440,3 +2440,4 @@ ParametersForTestEnvironment=Paramètres pour l'environnement de test TryToKeepOnly=Essayez de ne conserver que %s RecommendedForProduction=Recommandé pour la production RecommendedForDebug=Recommandé pour le débogage +UrlPublicInterfaceHelpAdmin=Il est possible de définir un alias vers le serveur et de rendre ainsi l'interface publique accessible avec une autre URL (le serveur doit agir comme un proxy sur cette nouvelle URL) diff --git a/htdocs/langs/fr_FR/ticket.lang b/htdocs/langs/fr_FR/ticket.lang index e8c90035e07..d910042f8ca 100644 --- a/htdocs/langs/fr_FR/ticket.lang +++ b/htdocs/langs/fr_FR/ticket.lang @@ -108,7 +108,6 @@ TicketCreateThirdPartyWithContactIfNotExist=Demandez le nom et le nom de l'entre TicketCreateThirdPartyWithContactIfNotExistHelp=Vérifiez s'il existe un tiers ou un contact pour l'e-mail saisi. Sinon, demandez un nom et un nom société pour créer un tiers avec contact. PublicInterface=Interface publique TicketUrlPublicInterfaceLabelAdmin=URL alternative pour l'interface publique -TicketUrlPublicInterfaceHelpAdmin=Il est possible de définir un alias vers le serveur et de rendre ainsi l'interface publique accessible avec une autre URL (le serveur doit agir comme un proxy sur cette nouvelle URL) TicketPublicInterfaceTextHomeLabelAdmin=Texte de bienvenue dans l'interface publique TicketPublicInterfaceTextHome=Vous pouvez créer un ticket ou consulter à partir d'un ID de ticket existant. TicketPublicInterfaceTextHomeHelpAdmin=Le texte défini ici apparaîtra sur la page d'accueil de l'interface publique. diff --git a/htdocs/webportal/admin/configcss.php b/htdocs/webportal/admin/configcss.php index 56842f4cf74..8f68e8e81c8 100644 --- a/htdocs/webportal/admin/configcss.php +++ b/htdocs/webportal/admin/configcss.php @@ -29,7 +29,7 @@ require_once DOL_DOCUMENT_ROOT . "/core/lib/admin.lib.php"; require_once DOL_DOCUMENT_ROOT . "/webportal/lib/webportal.lib.php"; // Translations -$langs->loadLangs(array("admin", "hrm", "other")); +$langs->loadLangs(array("admin", "hrm", "other", "website")); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('webportalsetup', 'globalsetup')); diff --git a/htdocs/webportal/admin/setup.php b/htdocs/webportal/admin/setup.php index 334a97336cd..78e183d2a95 100644 --- a/htdocs/webportal/admin/setup.php +++ b/htdocs/webportal/admin/setup.php @@ -57,15 +57,15 @@ $useFormSetup = 1; if (!class_exists('FormSetup')) { require_once DOL_DOCUMENT_ROOT . '/core/class/html.formsetup.class.php'; } - $formSetup = new FormSetup($db); // root url $item = $formSetup->newItem('WEBPORTAL_ROOT_URL')->setAsString(); +$item->nameText = $langs->transnoentities('UrlPublicInterfaceLabelAdmin'); $item->fieldAttr = array('placeholder' => 'https://'); -$item->helpText = $langs->transnoentities('WebPortalRootUrlHelp'); +$item->helpText = $langs->transnoentities('UrlPublicInterfaceHelpAdmin'); require_once __DIR__ . '/../class/context.class.php'; -$context = Context::getInstance(); +//$context = Context::getInstance(); //$item->fieldOutputOverride = ''.img_picto('', 'globe', 'class="pictofixedwidth"').Context::getRootConfigUrl().''; @@ -270,7 +270,7 @@ print ajax_autoselect('publicurlmember'); // Setup page goes here print info_admin($langs->trans("UserAccountForWebPortalAreInThirdPartyTabHelp")); -print '
'; +print '

'; if ($action == 'edit') { print $formSetup->generateOutput(true); diff --git a/htdocs/webportal/admin/setup_theme.php b/htdocs/webportal/admin/setup_theme.php index 1e751389fea..9900f89d201 100644 --- a/htdocs/webportal/admin/setup_theme.php +++ b/htdocs/webportal/admin/setup_theme.php @@ -28,7 +28,7 @@ require_once DOL_DOCUMENT_ROOT . "/core/lib/admin.lib.php"; require_once DOL_DOCUMENT_ROOT . "/webportal/lib/webportal.lib.php"; // Translations -$langs->loadLangs(array("admin", "webportal")); +$langs->loadLangs(array("admin", "webportal", "website")); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('webportalthemesetup', 'globalsetup')); diff --git a/htdocs/website/index.php b/htdocs/website/index.php index cd9859e447f..7e0e6183b72 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -2417,9 +2417,11 @@ if ($action == 'exportsite' && $user->hasRight('website', 'export')) { } } -// Overite site -if ($action == 'overwitesite' && $user->hasRight('website', 'export')) { - $fileofzip = $object->overwriteTemplate(); +// Overwrite site +if ($action == 'overwritesite' && $user->hasRight('website', 'export')) { + if (getDolGlobalString('WEBSITE_ALLOW_OVERWRITE_GIT_SOURCE')) { + $fileofzip = $object->overwriteTemplate(); + } } // Regenerate site if ($action == 'regeneratesite' && $usercanedit) { @@ -3065,8 +3067,10 @@ if (!GETPOST('hide_websitemenu')) { print ''; } - // overite template - print 'ref).'" class="button bordertransp"> '.dol_escape_htmltag($langs->trans("Overwrite")).''; + if (getDolGlobalString('WEBSITE_ALLOW_OVERWRITE_GIT_SOURCE')) { + // overite template + print 'ref).'" class="button bordertransp"> '.dol_escape_htmltag($langs->trans("Overwrite")).''; + } } else { print ''; } From 64233c312e1c317ebe4b9b639cebadc524216c91 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 28 Jan 2024 17:05:15 +0100 Subject: [PATCH 20/23] Debug v20 --- htdocs/website/class/website.class.php | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index 642447afc23..7b6f2a00f3f 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1608,8 +1608,9 @@ class Website extends CommonObject } /** - * Overite template by copy and past all files - * @return void + * Overite template by copying all files + * + * @return int <0 if KO, >0 if OK */ public function overwriteTemplate() { @@ -1618,11 +1619,15 @@ class Website extends CommonObject $website = $this; if (empty($website->id) || empty($website->ref)) { setEventMessages("Website id or ref is not defined", null, 'errors'); - return false; + return -1; + } + if (empty($website->name_template)) { + setEventMessages("To export the website template into the GIT sources directory, the name of the directory/template must be know. For this website, the variable 'name_template' is unknown, so export in GIT sources is not possible.", null, 'errors'); + return -1; } if (!is_writable($conf->website->dir_temp)) { setEventMessages("Temporary dir ".$conf->website->dir_temp." is not writable", null, 'errors'); - return ''; + return -1; } $sourcedir = $conf->website->dir_output."/".$website->ref; @@ -1717,6 +1722,7 @@ class Website extends CommonObject } } } + // Find the corresponding file in the destination folder if (in_array($nomFichierModifie, $namesSource)) { foreach ($arraydestdir as $destFile) { @@ -1730,7 +1736,7 @@ class Website extends CommonObject $result = $this->replaceLignEUsingNum($destFile['fullname'], $differences[$nomFichierModifie]); if ($result !== false) { if ($result == -2) { - setEventMessages("No permissions to write in file ".$nomFichierModifie." from template ".$website->name_template."", null, 'errors'); + setEventMessages("No permissions to write in file ".$nomFichierModifie." from the template ".$website->name_template."", null, 'errors'); header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); exit(); } @@ -1747,7 +1753,7 @@ class Website extends CommonObject $result = $this->replaceLignEUsingNum($differences[$nomFichierModifie]['file_destination']['fullname'], $differences[$nomFichierModifie]); if ($result !== false) { if ($result == -2) { - setEventMessages("No permissions to write in file ".$differences[$nomFichierModifie]['file_destination']['name']." from template ".$website->name_template."", null, 'errors'); + setEventMessages("No permissions to write in file ".$differences[$nomFichierModifie]['file_destination']['name']." from the template ".$website->name_template."", null, 'errors'); header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); exit(); } @@ -1768,8 +1774,10 @@ class Website extends CommonObject } else { setEventMessages("No file has been modified", null, 'errors'); } + // save state file $this->saveState($etatPrecedent, $fichierEtat); + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); exit(); } From 83154b2809b73cbb6346d904f80b18e7585bdbfb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 28 Jan 2024 17:41:47 +0100 Subject: [PATCH 21/23] Better messages --- htdocs/website/class/website.class.php | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index 7b6f2a00f3f..45c047b94bd 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1632,12 +1632,15 @@ class Website extends CommonObject $sourcedir = $conf->website->dir_output."/".$website->ref; - $fichierEtat = $sourcedir . '/etat_fichiers.txt'; + $fichierEtat = $sourcedir . '/filelist-lastwrite-doctemplates.txt'; + // Get array with hash of files $etatPrecedent = $this->checkPreviousState($fichierEtat); + // Get list of all source files of the website $arraySourcedir = dol_dir_list($sourcedir); + // Get list of modified files $modifications = []; foreach ($arraySourcedir as $file) { if (substr($file['name'], -4) === '.old') { @@ -1650,12 +1653,12 @@ class Website extends CommonObject $modifications[] = $file; } - $etatPrecedent[$file['name']] = $hashActuel; + $etatPrecedent[$file['name']] = $hashActuel; // we store he new hash to record it later on disk. } - // listed modified files - - $destdir = DOL_DOCUMENT_ROOT . '/install/doctemplates/websites/'.$website->name_template; + // Replace modified files into the doctemplates directory. + $destdirrel = 'install/doctemplates/websites/'.$website->name_template; + $destdir = DOL_DOCUMENT_ROOT.'/'.$destdirrel; $arraydestdir = dol_dir_list($destdir, "all", 1); $differences = []; $names = array_column($arraydestdir, 'name'); @@ -1736,7 +1739,7 @@ class Website extends CommonObject $result = $this->replaceLignEUsingNum($destFile['fullname'], $differences[$nomFichierModifie]); if ($result !== false) { if ($result == -2) { - setEventMessages("No permissions to write in file ".$nomFichierModifie." from the template ".$website->name_template."", null, 'errors'); + setEventMessages("No permissions to write into file ".$destdirrel.'/'.$nomFichierModifie." from the current website ".$website->name_template."", null, 'errors'); header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); exit(); } @@ -1753,7 +1756,7 @@ class Website extends CommonObject $result = $this->replaceLignEUsingNum($differences[$nomFichierModifie]['file_destination']['fullname'], $differences[$nomFichierModifie]); if ($result !== false) { if ($result == -2) { - setEventMessages("No permissions to write in file ".$differences[$nomFichierModifie]['file_destination']['name']." from the template ".$website->name_template."", null, 'errors'); + setEventMessages("No permissions to write into file ".$destdirrel.'/'.$differences[$nomFichierModifie]['file_destination']['name']." from the current website ".$website->name_template."", null, 'errors'); header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); exit(); } @@ -1765,7 +1768,7 @@ class Website extends CommonObject } } if ($succes>0) { - // save state file + // Save the state file filelist.txt $this->saveState($etatPrecedent, $fichierEtat); setEventMessages("file ".$differences[$nomFichierModifie]['file_destination']['name']." was modified in template ".$website->name_template."", null, 'warnings'); header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref); @@ -1852,7 +1855,7 @@ class Website extends CommonObject */ public function initFilesStatus($sourcedir) { - $fichierEtat = $sourcedir . '/etat_fichiers.txt'; + $fichierEtat = $sourcedir . '/filelist-lastwrite-doctemplates.txt'; $etatPrecedent = $this->checkPreviousState($fichierEtat); From 38f897609d24bfb2214c6fa5c20478b896c3b227 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 28 Jan 2024 17:47:50 +0100 Subject: [PATCH 22/23] Trans --- htdocs/langs/en_US/website.lang | 1 + htdocs/website/index.php | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang index 6d457dfb33b..d97f4ff23ac 100644 --- a/htdocs/langs/en_US/website.lang +++ b/htdocs/langs/en_US/website.lang @@ -232,3 +232,4 @@ WebPortalErrorFetchLoggedUser = Error when loading user (Id : %s) WebPortalErrorFetchLoggedThirdParty = Error when loading third-party (Id : %s) WebPortalErrorFetchLoggedMember = Error when loading member (Id : %s) WebPortalErrorFetchLoggedPartnership = Error when loading partnership (Third-party Id : %s, Member Id : %s) +ExportIntoGIT=Export into sources \ No newline at end of file diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 7e0e6183b72..872431c1bb9 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -3022,6 +3022,11 @@ if (!GETPOST('hide_websitemenu')) { // Export web site print ''; + if (getDolGlobalString('WEBSITE_ALLOW_OVERWRITE_GIT_SOURCE')) { + // Overwrite template in sources + print 'ref).'" class="button bordertransp">'.dol_escape_htmltag($langs->trans("ExportIntoGIT")).''; + } + // Clone web site print ''; @@ -3067,10 +3072,6 @@ if (!GETPOST('hide_websitemenu')) { print ''; } - if (getDolGlobalString('WEBSITE_ALLOW_OVERWRITE_GIT_SOURCE')) { - // overite template - print 'ref).'" class="button bordertransp"> '.dol_escape_htmltag($langs->trans("Overwrite")).''; - } } else { print ''; } From 7baa02bda5c14d94231e551fe4ff76a14be6ca38 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 28 Jan 2024 18:22:21 +0100 Subject: [PATCH 23/23] Debug export website --- htdocs/core/lib/files.lib.php | 8 +++----- htdocs/website/class/website.class.php | 3 ++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index c842276835d..f5d930f26b6 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -2194,9 +2194,8 @@ function dol_convert_file($fileinput, $ext = 'png', $fileoutput = '', $page = '' */ function dol_compress_file($inputfile, $outputfile, $mode = "gz", &$errorstring = null) { - global $conf; - $foundhandler = 0; + //var_dump(basename($inputfile)); exit; try { dol_syslog("dol_compress_file mode=".$mode." inputfile=".$inputfile." outputfile=".$outputfile); @@ -2265,6 +2264,7 @@ function dol_compress_file($inputfile, $outputfile, $mode = "gz", &$errorstring include_once ODTPHP_PATHTOPCLZIP.'/pclzip.lib.php'; $archive = new PclZip($outputfile); + $result = $archive->add($inputfile, PCLZIP_OPT_REMOVE_PATH, dirname($inputfile)); if ($result === 0) { @@ -2439,7 +2439,7 @@ function dol_uncompress($inputfile, $outputdir) * @param string $inputdir Source dir name * @param string $outputfile Target file name (output directory must exists and be writable) * @param string $mode 'zip' - * @param string $excludefiles A regex pattern. For example: '/\.log$|\/temp\//' + * @param string $excludefiles A regex pattern to exclude files. For example: '/\.log$|\/temp\//' * @param string $rootdirinzip Add a root dir level in zip file * @param string $newmask Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666' * @return int Return integer <0 if KO, >0 if OK @@ -2447,8 +2447,6 @@ function dol_uncompress($inputfile, $outputdir) */ function dol_compress_dir($inputdir, $outputfile, $mode = "zip", $excludefiles = '', $rootdirinzip = '', $newmask = 0) { - global $conf; - $foundhandler = 0; dol_syslog("Try to zip dir ".$inputdir." into ".$outputfile." mode=".$mode); diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index 45c047b94bd..c6821322778 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1154,7 +1154,8 @@ class Website extends CommonObject $filename = $conf->website->dir_temp.'/'.$website->ref.'/website_'.$website->ref.'-'.dol_print_date(dol_now(), 'dayhourlog').'-V'.((float) DOL_VERSION).'.zip'; dol_delete_file($fileglob, 0); - $result = dol_compress_file($filedir, $filename, 'zip'); + + $result = dol_compress_dir($filedir, $filename, 'zip'); if ($result > 0) { return $filename;