diff --git a/htdocs/admin/system/filecheck.php b/htdocs/admin/system/filecheck.php
index 8aed7d193f9..60c20dfafe7 100644
--- a/htdocs/admin/system/filecheck.php
+++ b/htdocs/admin/system/filecheck.php
@@ -152,7 +152,7 @@ if (GETPOST('target') == 'remote')
}
-if ($xml)
+if (! $error && $xml)
{
$checksumconcat = array();
$file_list = array();
@@ -395,19 +395,34 @@ if ($xml)
var_dump($checksumget);
var_dump($checksumtoget);
var_dump($checksumget == $checksumtoget);*/
- print_fiche_titre($langs->trans("GlobalChecksum")).'
';
- print $langs->trans("ExpectedChecksum").' = '. ($checksumtoget ? $checksumtoget : $langs->trans("Unknown")) .'
';
- print $langs->trans("CurrentChecksum").' = ';
+
+ $outexpectedchecksum = ($checksumtoget ? $checksumtoget : $langs->trans("Unknown"));
if ($checksumget == $checksumtoget)
{
- if (count($file_list['added'])) print $checksumget.' - '.$langs->trans("FileIntegrityIsOkButFilesWereAdded").'';
- else print ''.$checksumget.'';
+ if (count($file_list['added']))
+ {
+ $resultcode = 'warning';
+ $resultcomment='FileIntegrityIsOkButFilesWereAdded';
+ $outcurrentchecksum = $checksumget.' - '.$langs->trans("FileIntegrityIsOkButFilesWereAdded").'';
+ }
+ else
+ {
+ $resultcode = 'ok';
+ $resultcomment='Success';
+ $outcurrentchecksum = ''.$checksumget.'';
+ }
}
else
{
- print ''.$checksumget.'';
+ $resultcode = 'error';
+ $resultcomment='Error';
+ $outcurrentchecksum = ''.$checksumget.'';
}
+ print_fiche_titre($langs->trans("GlobalChecksum")).'
';
+ print $langs->trans("ExpectedChecksum").' = '. $outexpectedchecksum .'
';
+ print $langs->trans("CurrentChecksum").' = '. $outcurrentchecksum;
+
print '
';
print '
';
@@ -424,43 +439,3 @@ $db->close();
exit($error);
-
-/**
- * Function to get list of updated or modified files.
- * $file_list is used as global variable
- *
- * @param array $file_list Array for response
- * @param SimpleXMLElement $dir SimpleXMLElement of files to test
- * @param string $path Path of files relative to $pathref. We start with ''. Used by recursive calls.
- * @param string $pathref Path ref (DOL_DOCUMENT_ROOT)
- * @param array $checksumconcat Array of checksum
- * @return array Array of filenames
- */
-function getFilesUpdated(&$file_list, SimpleXMLElement $dir, $path = '', $pathref = '', &$checksumconcat = array())
-{
- $exclude = 'install';
-
- foreach ($dir->md5file as $file) // $file is a simpleXMLElement
- {
- $filename = $path.$file['name'];
- $file_list['insignature'][] = $filename;
-
- //if (preg_match('#'.$exclude.'#', $filename)) continue;
-
- if (!file_exists($pathref.'/'.$filename))
- {
- $file_list['missing'][] = array('filename'=>$filename, 'expectedmd5'=>(string) $file);
- }
- else
- {
- $md5_local = md5_file($pathref.'/'.$filename);
- if ($md5_local != (string) $file) $file_list['updated'][] = array('filename'=>$filename, 'expectedmd5'=>(string) $file, 'md5'=>(string) $md5_local);
- $checksumconcat[] = $md5_local;
- }
- }
-
- foreach ($dir->dir as $subdir) getFilesUpdated($file_list, $subdir, $path.$subdir['name'].'/', $pathref, $checksumconcat);
-
- return $file_list;
-}
-
diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php
index 9a5b18ca95d..caba92f2947 100644
--- a/htdocs/api/class/api_setup.class.php
+++ b/htdocs/api/class/api_setup.class.php
@@ -329,7 +329,7 @@ class Setup extends DolibarrApi
*
* @throws RestException
*/
- function getListOfEvents($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $sqlfilters = '')
+ function getListOfEventTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $sqlfilters = '')
{
$list = array();
@@ -577,4 +577,345 @@ class Setup extends DolibarrApi
return $list;
}
+
+ /**
+ * Do a test of integrity for files and setup.
+ *
+ * @param string $target Can be 'local' or 'default' or Url of the signatures file to use for the test. Must be reachable by the tested Dolibarr.
+ * @return Result of file and setup integrity check
+ *
+ * @url GET checkintegrity
+ *
+ * @throws RestException
+ */
+ function getCheckIntegrity($target)
+ {
+ global $langs, $conf;
+
+ if (! DolibarrApiAccess::$user->admin
+ && (empty($conf->global->API_LOGIN_ALLOWED_FOR_INTEGRITY_CHECK) || DolibarrApiAccess::$user->login != $conf->global->API_LOGIN_ALLOWED_FOR_INTEGRITY_CHECK))
+ {
+ throw new RestException(503, 'Error API open to admin users only or to login user defined with constant API_LOGIN_ALLOWED_FOR_INTEGRITY_CHECK');
+ }
+
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
+
+ $langs->load("admin");
+
+ $outexpectedchecksum = '';
+ $outcurrentchecksum = '';
+
+ // Modified or missing files
+ $file_list = array('missing' => array(), 'updated' => array());
+
+ // Local file to compare to
+ $xmlshortfile = GETPOST('xmlshortfile')?GETPOST('xmlshortfile'):'/install/filelist-'.DOL_VERSION.'.xml';
+ $xmlfile = DOL_DOCUMENT_ROOT.$xmlshortfile;
+ // Remote file to compare to
+ $xmlremote = ($target == 'default' ? '' : $target);
+ if (empty($xmlremote) && ! empty($conf->global->MAIN_FILECHECK_URL)) $xmlremote = $conf->global->MAIN_FILECHECK_URL;
+ $param='MAIN_FILECHECK_URL_'.DOL_VERSION;
+ if (empty($xmlremote) && ! empty($conf->global->$param)) $xmlremote = $conf->global->$param;
+ if (empty($xmlremote)) $xmlremote = 'https://www.dolibarr.org/files/stable/signatures/filelist-'.DOL_VERSION.'.xml';
+
+ if ($target == 'local')
+ {
+ if (dol_is_file($xmlfile))
+ {
+ $xml = simplexml_load_file($xmlfile);
+ }
+ else
+ {
+ throw new RestException(500, $langs->trans('XmlNotFound') . ': ' . $xmlfile);
+ $error++;
+ }
+ }
+ else
+ {
+ $xmlarray = getURLContent($xmlremote);
+
+ // Return array('content'=>response,'curl_error_no'=>errno,'curl_error_msg'=>errmsg...)
+ if (! $xmlarray['curl_error_no'] && $xmlarray['http_code'] != '404')
+ {
+ $xmlfile = $xmlarray['content'];
+ //print "eee".$xmlfile."eee";
+ $xml = simplexml_load_string($xmlfile);
+ }
+ else
+ {
+ $errormsg=$langs->trans('XmlNotFound') . ': ' . $xmlremote.' - '.$xmlarray['http_code'].' '.$xmlarray['curl_error_no'].' '.$xmlarray['curl_error_msg'];
+ throw new RestException(500, $errormsg);
+ $error++;
+ }
+ }
+
+
+
+ if (! $error && $xml)
+ {
+ $checksumconcat = array();
+ $file_list = array();
+ $out = '';
+
+ // Forced constants
+ if (is_object($xml->dolibarr_constants[0]))
+ {
+ $out.=load_fiche_titre($langs->trans("ForcedConstants"));
+
+ $out.='
';
+ $out.='
';
+ $out.='';
+ $out.='| # | ';
+ $out.='' . $langs->trans("Constant") . ' | ';
+ $out.='' . $langs->trans("ExpectedValue") . ' | ';
+ $out.='' . $langs->trans("Value") . ' | ';
+ $out.='
'."\n";
+
+ $i = 0;
+ foreach ($xml->dolibarr_constants[0]->constant as $constant) // $constant is a simpleXMLElement
+ {
+ $constname=$constant['name'];
+ $constvalue=(string) $constant;
+ $constvalue = (empty($constvalue)?'0':$constvalue);
+ // Value found
+ $value='';
+ if ($constname && $conf->global->$constname != '') $value=$conf->global->$constname;
+ $valueforchecksum=(empty($value)?'0':$value);
+
+ $checksumconcat[]=$valueforchecksum;
+
+ $i++;
+ $out.='';
+ $out.='| '.$i.' | ' . "\n";
+ $out.=''.$constname.' | ' . "\n";
+ $out.=''.$constvalue.' | ' . "\n";
+ $out.=''.$valueforchecksum.' | ' . "\n";
+ $out.="
\n";
+ }
+
+ if ($i==0)
+ {
+ $out.='| '.$langs->trans("None").' |
';
+ }
+ $out.='
';
+ $out.='
';
+
+ $out.='
';
+ }
+
+ // Scan htdocs
+ if (is_object($xml->dolibarr_htdocs_dir[0]))
+ {
+ //var_dump($xml->dolibarr_htdocs_dir[0]['includecustom']);exit;
+ $includecustom=(empty($xml->dolibarr_htdocs_dir[0]['includecustom'])?0:$xml->dolibarr_htdocs_dir[0]['includecustom']);
+
+ // Defined qualified files (must be same than into generate_filelist_xml.php)
+ $regextoinclude='\.(php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$';
+ $regextoexclude='('.($includecustom?'':'custom|').'documents|conf|install|public\/test|Shared\/PCLZip|nusoap\/lib\/Mail|php\/example|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs
+ $scanfiles = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude);
+
+ // Fill file_list with files in signature, new files, modified files
+ $ret = getFilesUpdated($file_list, $xml->dolibarr_htdocs_dir[0], '', DOL_DOCUMENT_ROOT, $checksumconcat, $scanfiles); // Fill array $file_list
+ // Complete with list of new files
+ foreach ($scanfiles as $keyfile => $valfile)
+ {
+ $tmprelativefilename=preg_replace('/^'.preg_quote(DOL_DOCUMENT_ROOT,'/').'/','', $valfile['fullname']);
+ if (! in_array($tmprelativefilename, $file_list['insignature']))
+ {
+ $md5newfile=@md5_file($valfile['fullname']); // Can fails if we don't have permission to open/read file
+ $file_list['added'][]=array('filename'=>$tmprelativefilename, 'md5'=>$md5newfile);
+ }
+ }
+
+ // Files missings
+ $out.=load_fiche_titre($langs->trans("FilesMissing"));
+
+ $out.='';
+ $out.='
';
+ $out.='';
+ $out.='| # | ';
+ $out.='' . $langs->trans("Filename") . ' | ';
+ $out.='' . $langs->trans("ExpectedChecksum") . ' | ';
+ $out.='
'."\n";
+ $tmpfilelist = dol_sort_array($file_list['missing'], 'filename');
+ if (is_array($tmpfilelist) && count($tmpfilelist))
+ {
+ $i = 0;
+ foreach ($tmpfilelist as $file)
+ {
+ $i++;
+ $out.='';
+ $out.='| '.$i.' | ' . "\n";
+ $out.=''.$file['filename'].' | ' . "\n";
+ $out.=''.$file['expectedmd5'].' | ' . "\n";
+ $out.="
\n";
+ }
+ }
+ else
+ {
+ $out.='| '.$langs->trans("None").' |
';
+ }
+ $out.='
';
+ $out.='
';
+
+ $out.='
';
+
+ // Files modified
+ $out.=load_fiche_titre($langs->trans("FilesModified"));
+
+ $totalsize=0;
+ $out.='';
+ $out.='
';
+ $out.='';
+ $out.='| # | ';
+ $out.='' . $langs->trans("Filename") . ' | ';
+ $out.='' . $langs->trans("ExpectedChecksum") . ' | ';
+ $out.='' . $langs->trans("CurrentChecksum") . ' | ';
+ $out.='' . $langs->trans("Size") . ' | ';
+ $out.='' . $langs->trans("DateModification") . ' | ';
+ $out.='
'."\n";
+ $tmpfilelist2 = dol_sort_array($file_list['updated'], 'filename');
+ if (is_array($tmpfilelist2) && count($tmpfilelist2))
+ {
+ $i = 0;
+ foreach ($tmpfilelist2 as $file)
+ {
+ $i++;
+ $out.='';
+ $out.='| '.$i.' | ' . "\n";
+ $out.=''.$file['filename'].' | ' . "\n";
+ $out.=''.$file['expectedmd5'].' | ' . "\n";
+ $out.=''.$file['md5'].' | ' . "\n";
+ $size = dol_filesize(DOL_DOCUMENT_ROOT.'/'.$file['filename']);
+ $totalsize += $size;
+ $out.=''.dol_print_size($size).' | ' . "\n";
+ $out.=''.dol_print_date(dol_filemtime(DOL_DOCUMENT_ROOT.'/'.$file['filename']),'dayhour').' | ' . "\n";
+ $out.="
\n";
+ }
+ $out.='';
+ $out.=' | ' . "\n";
+ $out.=''.$langs->trans("Total").' | ' . "\n";
+ $out.=' | ' . "\n";
+ $out.=' | ' . "\n";
+ $out.=''.dol_print_size($totalsize).' | ' . "\n";
+ $out.=' | ' . "\n";
+ $out.="
\n";
+ }
+ else
+ {
+ $out.='| '.$langs->trans("None").' |
';
+ }
+ $out.='
';
+ $out.='
';
+
+ $out.='
';
+
+ // Files added
+ $out.=load_fiche_titre($langs->trans("FilesAdded"));
+
+ $totalsize = 0;
+ $out.='';
+ $out.='
';
+ $out.='';
+ $out.='| # | ';
+ $out.='' . $langs->trans("Filename") . ' | ';
+ $out.='' . $langs->trans("ExpectedChecksum") . ' | ';
+ $out.='' . $langs->trans("CurrentChecksum") . ' | ';
+ $out.='' . $langs->trans("Size") . ' | ';
+ $out.='' . $langs->trans("DateModification") . ' | ';
+ $out.='
'."\n";
+ $tmpfilelist3 = dol_sort_array($file_list['added'], 'filename');
+ if (is_array($tmpfilelist3) && count($tmpfilelist3))
+ {
+ $i = 0;
+ foreach ($tmpfilelist3 as $file)
+ {
+ $i++;
+ $out.='';
+ $out.='| '.$i.' | ' . "\n";
+ $out.=''.$file['filename'].' | ' . "\n";
+ $out.=''.$file['expectedmd5'].' | ' . "\n";
+ $out.=''.$file['md5'].' | ' . "\n";
+ $size = dol_filesize(DOL_DOCUMENT_ROOT.'/'.$file['filename']);
+ $totalsize += $size;
+ $out.=''.dol_print_size($size).' | ' . "\n";
+ $out.=''.dol_print_date(dol_filemtime(DOL_DOCUMENT_ROOT.'/'.$file['filename']),'dayhour').' | ' . "\n";
+ $out.="
\n";
+ }
+ $out.='';
+ $out.=' | ' . "\n";
+ $out.=''.$langs->trans("Total").' | ' . "\n";
+ $out.=' | ' . "\n";
+ $out.=' | ' . "\n";
+ $out.=''.dol_print_size($totalsize).' | ' . "\n";
+ $out.=' | ' . "\n";
+ $out.="
\n";
+ }
+ else
+ {
+ $out.='| '.$langs->trans("None").' |
';
+ }
+ $out.='
';
+ $out.='
';
+
+
+ // Show warning
+ if (empty($tmpfilelist) && empty($tmpfilelist2) && empty($tmpfilelist3))
+ {
+ //setEventMessage($langs->trans("FileIntegrityIsStrictlyConformedWithReference"));
+ }
+ else
+ {
+ //setEventMessage($langs->trans("FileIntegritySomeFilesWereRemovedOrModified"), 'warnings');
+ }
+ }
+ else
+ {
+ throw new RestException(500, 'Error: Failed to found dolibarr_htdocs_dir into XML file '.$xmlfile);
+ $error++;
+ }
+
+
+ // Scan scripts
+
+
+ asort($checksumconcat); // Sort list of checksum
+ //var_dump($checksumconcat);
+ $checksumget = md5(join(',',$checksumconcat));
+ $checksumtoget = trim((string) $xml->dolibarr_htdocs_dir_checksum);
+
+ $outexpectedchecksum = ($checksumtoget ? $checksumtoget : $langs->trans("Unknown"));
+ if ($checksumget == $checksumtoget)
+ {
+ if (count($file_list['added']))
+ {
+ $resultcode = 'warning';
+ $resultcomment='FileIntegrityIsOkButFilesWereAdded';
+ //$outcurrentchecksum = $checksumget.' - '.$langs->trans("FileIntegrityIsOkButFilesWereAdded").'';
+ $outcurrentchecksum = $checksumget;
+ }
+ else
+ {
+ $resultcode = 'ok';
+ $resultcomment='Success';
+ //$outcurrentchecksum = ''.$checksumget.'';
+ $outcurrentchecksum = $checksumget;
+ }
+ }
+ else
+ {
+ $resultcode = 'error';
+ $resultcomment='Error';
+ //$outcurrentchecksum = ''.$checksumget.'';
+ $outcurrentchecksum = $checksumget;
+ }
+ }
+ else {
+ throw new RestException(404, 'No signature file known');
+ }
+
+ return array('resultcode'=>$resultcode, 'resultcomment'=>$resultcomment, 'expectedchecksum'=> $outexpectedchecksum, 'currentchecksum'=> $outcurrentchecksum, 'out'=>$out);
+ }
+
}
diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php
index 220a390d577..daf4621ebcb 100644
--- a/htdocs/core/lib/files.lib.php
+++ b/htdocs/core/lib/files.lib.php
@@ -2723,3 +2723,44 @@ function dol_readcachefile($directory, $filename)
$object = unserialize(file_get_contents($cachefile));
return $object;
}
+
+
+/**
+ * Function to get list of updated or modified files.
+ * $file_list is used as global variable
+ *
+ * @param array $file_list Array for response
+ * @param SimpleXMLElement $dir SimpleXMLElement of files to test
+ * @param string $path Path of files relative to $pathref. We start with ''. Used by recursive calls.
+ * @param string $pathref Path ref (DOL_DOCUMENT_ROOT)
+ * @param array $checksumconcat Array of checksum
+ * @return array Array of filenames
+ */
+function getFilesUpdated(&$file_list, SimpleXMLElement $dir, $path = '', $pathref = '', &$checksumconcat = array())
+{
+ $exclude = 'install';
+
+ foreach ($dir->md5file as $file) // $file is a simpleXMLElement
+ {
+ $filename = $path.$file['name'];
+ $file_list['insignature'][] = $filename;
+
+ //if (preg_match('#'.$exclude.'#', $filename)) continue;
+
+ if (!file_exists($pathref.'/'.$filename))
+ {
+ $file_list['missing'][] = array('filename'=>$filename, 'expectedmd5'=>(string) $file);
+ }
+ else
+ {
+ $md5_local = md5_file($pathref.'/'.$filename);
+ if ($md5_local != (string) $file) $file_list['updated'][] = array('filename'=>$filename, 'expectedmd5'=>(string) $file, 'md5'=>(string) $md5_local);
+ $checksumconcat[] = $md5_local;
+ }
+ }
+
+ foreach ($dir->dir as $subdir) getFilesUpdated($file_list, $subdir, $path.$subdir['name'].'/', $pathref, $checksumconcat);
+
+ return $file_list;
+}
+