39 $r = @pg_connect($connect);
40 $this->connect = $connect;
42 if ($r) $this->r = $r;
47 $this->tout[
"main connection db"] = array(
48 "status" => $this->r ? self::OK : self::KO,
49 "msg" => $this->connect
51 return ($this->r != null);
56 $result = pg_query($this->r,
"SELECT * from groups where iduser not in (select id from users);");
58 while ($row = pg_fetch_array($result, NULL, PGSQL_ASSOC)) {
59 $pout[$row[
"iduser"]][] = $row[
"idgroup"];
61 if (count($pout) > 0) $msg = sprintf(
"%d unreferenced users<pre>%s</pre>", count($pout) , print_r($pout,
true));
63 $this->tout[
"unreferenced user in group"] = array(
64 "status" => (count($pout) == 0) ? self::OK : self::BOF,
75 simpleQuery(
'',
"SELECT current_database()", $dbname,
true,
true,
true);
76 simpleQuery(
'',
"SHOW DateStyle", $dateStyle,
true,
true,
true);
77 if ($dateStyle !==
'ISO, DMY') {
78 $ret[
'status'] = self::KO;
79 $ret[
'msg'] = sprintf(
"Database's \"DateStyle\" should be set to 'ISO, DMY' (actual value is '%s') <br/><pre>ALTER DATABASE %s SET DateStyle = 'ISO, DMY';</pre>", htmlspecialchars($dateStyle, ENT_QUOTES) , htmlspecialchars(pg_escape_identifier($dbname)));
81 $this->tout[
"dateStyle"] =
$ret;
90 simpleQuery(
'',
"SELECT current_database()", $dbname,
true,
true,
true);
93 $res[
'status'] = self::KO;
94 $res[
'msg'] = sprintf(
"Database's \"standard_conforming_strings\" should be set to 'off' (actual value is '%s') :<br/><pre>ALTER DATABASE %s SET standard_conforming_strings = off;</pre>", htmlspecialchars(
$value, ENT_QUOTES) , htmlspecialchars(pg_escape_identifier($dbname)));
96 $this->tout[
"standard_conforming_strings"] = $res;
101 $result = pg_query($this->r,
"SELECT distinct(idgroup) from groups where idgroup not in (select id from users where accounttype!='U');");
103 while ($row = pg_fetch_array($result, NULL, PGSQL_ASSOC)) {
104 $pout[] = $row[
"idgroup"];
106 if (count($pout) > 0) $msg = sprintf(
"%d users detected as group<br><kbd>%s</kbd>", count($pout) , implode(
", ", $pout));
108 $this->tout[
"user as group"] = array(
109 "status" => (count($pout) == 0) ? self::OK : self::KO,
116 $result = pg_query($this->r,
"SELECT * from action where id_application not in (select id from application);");
118 while ($row = pg_fetch_array($result, NULL, PGSQL_ASSOC)) {
119 $pout[] = $row[
"name"];
121 if (count($pout) > 0) $msg = sprintf(
"%d unreferenced actions<br><kbd>%s</kbd>", count($pout) , implode(
", ", $pout));
123 $this->tout[
"unreferenced actions"] = array(
124 "status" => (count($pout) == 0) ? self::OK : self::BOF,
131 $result = pg_query($this->r,
"SELECT * from paramdef where appid not in (select id from application);");
133 while ($row = pg_fetch_array($result, NULL, PGSQL_ASSOC)) {
134 $pout[] = $row[
"name"];
136 $result = pg_query($this->r,
"SELECT * from paramv where appid not in (select id from application);");
137 while ($row = pg_fetch_array($result, NULL, PGSQL_ASSOC)) {
138 $pout[] = $row[
"name"];
140 if (count($pout) > 0) $msg = sprintf(
"%d unreferenced parameters<br><kbd>%s</kbd>", count($pout) , implode(
", ", $pout));
142 $this->tout[
"unreferenced parameters"] = array(
143 "status" => (count($pout) == 0) ? self::OK : self::BOF,
150 $result = pg_query($this->r,
"SELECT * from acl where id_application not in (select id from application);");
152 while ($row = pg_fetch_array($result, NULL, PGSQL_ASSOC)) {
153 $pout[] = $row[
"name"];
155 if (count($pout) > 0) $msg = sprintf(
"%d unreferenced acl<br><kbd>%s</kbd>", count($pout) , implode(
", ", $pout));
157 $this->tout[
"unreferenced acl"] = array(
158 "status" => (count($pout) == 0) ? self::OK : self::BOF,
165 $result = pg_query($this->r,
"SELECT * from permission where id_acl not in (select id from acl);");
166 $nb = pg_num_rows($result);
167 $result = pg_query($this->r,
"SELECT * from permission where id_user not in (select id from users);");
168 $nb+= pg_num_rows($result);
169 $result = pg_query($this->r,
"SELECT * from permission where id_application not in (select id from application);");
170 $nb+= pg_num_rows($result);
172 if ($nb > 0) $msg = sprintf(
"%d unreferenced permissions", ($nb));
173 $this->tout[
"unreferenced permission"] = array(
174 "status" => ($nb == 0) ? self::OK : self::BOF,
181 $result = pg_query($this->r,
"SELECT * from (SELECT id, count(id) as c from doc group by id) as Z where Z.c > 1;");
183 while ($row = pg_fetch_array($result, NULL, PGSQL_ASSOC)) {
184 $pout[$row[
"id"]] = $row[
"c"];
186 if (count($pout) > 0) $msg = sprintf(
"%d double id detected<pre>%s</pre>", count($pout) , print_r($pout,
true));
188 $this->tout[
"double doc id"] = array(
189 "status" => (count($pout) == 0) ? self::OK : self::KO,
195 $result = pg_query($this->r,
"select * from (select name, count(name) as c from doc where name is not null and name != '' and locked != -1 group by name) as Z where Z.c >1");
197 while ($row = pg_fetch_array($result, NULL, PGSQL_ASSOC)) {
198 $pout[$row[
"name"]] = $row[
"c"];
200 if (count($pout) > 0) $msg = sprintf(
"%d double detected<pre>%s</pre>", count($pout) , print_r($pout,
true));
202 $this->tout[
"double doc name"] = array(
203 "status" => (count($pout) == 0) ? self::OK : self::KO,
210 $result = pg_query($this->r,
"select id, title from docread where id in (SELECT m AS id FROM (SELECT min(id) AS m, initid, count(initid) AS c FROM docread WHERE locked != -1 AND doctype != 'T' GROUP BY docread.initid) AS z where z.c > 1);");
212 while ($row = pg_fetch_array($result, NULL, PGSQL_ASSOC)) {
213 $pout[$row[
"id"]] = $row[
"title"];
215 if (count($pout) > 0) $msg = sprintf(
"%d multiple alive<pre>%s</pre>", count($pout) , print_r($pout,
true));
217 $this->tout[
"multiple alive"] = array(
218 "status" => (count($pout) == 0) ? self::OK : self::KO,
225 $result = pg_query($this->r,
"select * from docfam");
227 while ($row = pg_fetch_array($result, NULL, PGSQL_ASSOC)) {
228 $fromid = intval($row[
"fromid"]);
229 if ($fromid == 0) $fromid =
"";
230 $fid = intval($row[
"id"]);
231 $test = pg_query($this->r, sprintf(
"SELECT relname from pg_class where oid in (SELECT inhparent from pg_inherits where inhrelid =(SELECT oid FROM pg_class where relname='doc%d'));", $fid));
232 $dbfrom = pg_fetch_array(
$test, NULL, PGSQL_ASSOC);
233 if ($dbfrom[
"relname"] !=
"doc$fromid") {
234 $pout[] = sprintf(
"Family %s [%d]: fromid = %d, pg inherit=%s", $row[
"name"], $row[
"id"], $row[
"fromid"], $dbfrom[
"relname"]);
237 $this->tout[
"family inheritance"] = array(
238 "status" => (count($pout) == 0) ? self::OK : self::KO,
239 "msg" => implode(
"<br/>", $pout)
246 $appNameList = array();
247 $result = pg_query($this->r,
"SELECT name FROM application;");
248 while ($row = pg_fetch_array($result, NULL, PGSQL_ASSOC)) {
249 $appNameList[] = $row[
'name'];
251 $nuAppExists = (array_search(
'NU', $appNameList) ===
false) ?
false :
true;
252 $ldaphost = $this->getGlobalParam(
"NU_LDAP_HOST");
253 $ldapport = $this->getGlobalParam(
"NU_LDAP_PORT");
254 $ldapmode = $this->getGlobalParam(
"NU_LDAP_MODE");
255 if ($nuAppExists && $ldaphost) {
256 include_once (
'../../../NU/Lib.NU.php');
258 $ldapBindDn = $this->getGlobalParam(
'NU_LDAP_BINDDN');
259 $ldapPassword = $this->getGlobalParam(
'NU_LDAP_PASSWORD');
262 array_push($baseList, array(
263 'dn' => $this->getGlobalParam(
'NU_LDAP_USER_BASE_DN') ,
264 'filter' => $this->getGlobalParam(
'NU_LDAP_USER_FILTER')
266 array_push($baseList, array(
267 'dn' => $this->getGlobalParam(
'NU_LDAP_GROUP_BASE_DN') ,
268 'filter' => $this->getGlobalParam(
'NU_LDAP_GROUP_FILTER')
271 foreach ($baseList as $base) {
272 $testName = sprintf(
"connection to '%s'", $base[
'dn']);
273 $this->tout[$testName] = array();
275 $uri = getLDAPUri($ldapmode, $ldaphost, $ldapport);
276 $conn = ldap_connect($uri);
277 if (
$conn ===
false) {
278 $this->tout[$testName][
'status'] = self::KO;
279 $this->tout[$testName][
'msg'] = sprintf(
"Could not connect to LDAP server '%s': %s", $uri, $php_errormsg);
283 ldap_set_option(
$conn, LDAP_OPT_PROTOCOL_VERSION, 3);
284 ldap_set_option(
$conn, LDAP_OPT_REFERRALS, 0);
286 if ($ldapmode ==
'tls') {
288 if (
$ret ===
false) {
289 $this->tout[$testName][
'status'] = self::KO;
290 $this->tout[$testName][
'msg'] = sprintf(
"Could not negotiate TLS with server '%s': %s", $uri, ldap_error(
$conn));
295 $bind = ldap_bind(
$conn, $ldapBindDn, $ldapPassword);
296 if ($bind ===
false) {
297 $this->tout[$testName][
'status'] = self::KO;
298 $this->tout[$testName][
'msg'] = sprintf(
"Could not bind with bind DN '%s' on server '%s': %s", $ldapBindDn, $uri, ldap_error(
$conn));
303 $res = ldap_search(
$conn, $base[
'dn'], sprintf(
"(&(objectClass=*)%s)", $base[
'filter']));
304 if ($res ===
false) {
305 $this->tout[$testName][
'status'] = self::KO;
306 $this->tout[$testName][
'msg'] = sprintf(
"LDAP search on base '%s' with filter '%s' failed: %s", $base[
'dn'], $base[
'filter'], ldap_error(
$conn));
311 $count = ldap_count_entries(
$conn, $res);
312 if ($count ===
false) {
313 $this->tout[$testName][
'status'] = self::KO;
314 $this->tout[$testName][
'msg'] = sprintf(
"Error counting result entries: %s", ldap_error(
$conn));
319 $this->tout[$testName][
'status'] = self::BOF;
320 $this->tout[$testName][
'msg'] = sprintf(
"Search returned 0 entries...");
325 $this->tout[$testName][
'status'] = self::OK;
326 $this->tout[$testName][
'msg'] = sprintf(
"Search returned %s entries.", $count);
334 $testName =
"cleanContext cron job execution";
335 $sql =
"SELECT min(cdate) AS mincdate, count(id) AS count FROM doc WHERE doctype = 'T' AND cdate < now() - INTERVAL '24h'";
339 if ($res[0][
'count'] > 0) {
340 $err = sprintf(
"<p>Oldest temporary document is > 24 hours: <code>%s</code></p>", htmlspecialchars($res[0][
'mincdate']));
341 $err.=
"<p>Dynacase crontab might not be active or correctly registered.</p>";
343 $err.=
"<li>Check that the Dynacase crontab 'FREEDOM/freedom.cron' is correctly registered in the Apache's user crontab: <pre>./wsh.php --api=manageContextCrontab --cmd=list</pre></li>";
344 $err.=
"<li>If the crontab is not registered, try to register it: <pre>./wsh.php --api=manageContextCrontab --cmd=register --file=FREEDOM/freedom.cron</pre>";
345 $err.=
"<li>If the crontab is correctly registered but not executed, check that the system's cron daemon is correctly running.</li>";
347 throw new Exception(
$err);
350 catch(Exception $e) {
351 $this->tout[$testName] = array(
352 'status' => self::KO,
353 'msg' => $e->getMessage()
357 $this->tout[$testName] = array(
358 'status' => self::OK,
369 private static function verifyDbAttr(&$oa, $pgtype, &$rtype)
373 if (!$oa->inArray()) {
391 $rtype =
'timestamp';
400 if ($rtype != $pgtype) {
401 $err = sprintf(
"expected [%s], found [%s]", $rtype, $pgtype);
416 $fam = new_doc(
'',
$famid);
417 if ($fam->isAlive()) {
418 $sql = sprintf(
"select pg_attribute.attname,pg_type.typname FROM pg_attribute, pg_type where pg_type.oid=pg_attribute.atttypid and pg_attribute.attrelid=(SELECT oid from pg_class where relname='doc%d') order by pg_attribute.attname;", $fam->id);
421 foreach ($res as $pgattr) {
422 if ($pgattr[
"typname"] ==
"timestamptz") $pgattr[
"typname"] =
"timestamp";
423 $pgtype[$pgattr[
"attname"]] = $pgattr[
"typname"];
427 $oas = $fam->getNormalAttributes();
433 foreach ($oas as $oa) {
435 if (($oa->docid == $fam->id) && ($oa->type !=
"array") && ($oa->type !=
"frame") && ($oa->type !=
"tab") && ($oa->type !=
"") && ($oa->type !=
"menu")) {
436 $err = self::verifyDbAttr($oa, $pgtype[$aid], $rtype);
438 $cr[] = sprintf(
"family %s, %s (%s) : %s\n", $fam->getTitle() , $aid, $oa->type,
$err) . sprintf(
"\ttry : drop view family.%s; \n", strtolower($fam->name)) . sprintf(
"\tand : alter table doc%d alter column %s type %s using %s::%s; \n", $fam->id, $aid, $rtype, $aid, $rtype);
452 $fam = new_doc(
'',
$famid);
453 $sql = sprintf(
"select column_name from information_schema.columns where table_name = 'doc%d'", $fam->id);
456 $nAttributes = $fam->getNormalAttributes();
457 $oasIds = array_keys($nAttributes);
458 $oasIds = array_merge($oasIds,
$d->fields,
$d->sup_fields, array(
463 foreach ($nAttributes as $attrid => $oa) {
464 if ($oa->type ==
"file") {
465 $oasIds[] = $attrid .
'_txt';
466 $oasIds[] = $attrid .
'_vec';
471 foreach ($res as $dbAttr) {
472 if (!in_array($dbAttr, $oasIds)) {
473 if ($dbAttr !=
"forumid") {
486 $testName =
'attribute type';
487 include_once (
"../../../FDL/Class.Doc.php");
490 foreach ($families as
$famid) {
492 if (count(
$cr) > 0) {
497 $this->tout[$testName][
'status'] = (
$err) ? self::KO : self::OK;
498 $this->tout[$testName][
'msg'] =
'<pre>' .
$err .
'</pre>';
506 $testName =
'attribute orphan';
507 include_once (
"../../../FDL/Class.Doc.php");
509 $this->tout[$testName][
'status'] = self::BOF;
510 $this->tout[$testName][
'msg'] = sprintf(
"<pre>%s</pre>", htmlspecialchars(
$err, ENT_QUOTES));
516 if (count($cmds) > 0) {
517 $html.=
"BEGIN;<br/>";
519 $html.= implode(
"<br/>", array_map(
function ($v)
521 return htmlspecialchars($v, ENT_QUOTES);
528 $this->tout[$testName][
'status'] = ($html !==
'') ? self::BOF : self::OK;
529 $this->tout[$testName][
'msg'] =
'<pre>' . $html .
'</pre>';
544 if (isset($node[
'drop'][$column])) {
547 if (isset($node[
'parent'])) {
548 return self::isDroppedInNode($node[
'parent'], $column);
566 if (isset($node[
'drop']) && is_array($node[
'drop'])) {
567 if (count($node[
'drop']) > 0) {
568 $cmds[] = sprintf(
"-- Family '%s', table doc%d", $node[
'name'], $node[
'id']);
569 $alter = sprintf(
"ALTER TABLE doc%d", $node[
'id']);
571 foreach ($node[
'drop'] as $column) {
572 $drops[] = sprintf(
"DROP COLUMN IF EXISTS %s CASCADE", pg_escape_identifier($column));
575 $alter.=
"\n\t" . join(
",\n\t", $drops) .
";";
578 foreach ($drops as
$drop) {
579 $cmds[] = $alter .
" " . $drop .
";";
582 $cmds[] =
'SELECT refreshFamilySchemaViews();';
586 if (isset($node[
'childs'])) {
587 foreach ($node[
'childs'] as & $child) {
607 WITH RECURSIVE topfam(
id, fromid) AS (
608 SELECT
id, fromid FROM docfam WHERE fromid = %d
610 SELECT docfam.id, docfam.fromid FROM topfam, docfam WHERE docfam.fromid = topfam.id
612 SELECT * FROM topfam;
619 if ($node === null) {
626 foreach ($families as $fam) {
628 if (!is_object(
$doc) || !
$doc->isAlive()) {
631 if ($fam[
'fromid'] != $fromId) {
635 $orphans = self::getOrphanAttributes($fam[
'id']);
636 foreach ($orphans as $column) {
637 if (!self::isDroppedInNode($node, $column)) {
638 $drop[$column] = $column;
641 $node[
'childs'][$fam[
'id']] = array(
642 'name' =>
$doc->name,
644 'fromid' => $fam[
'fromid'],
650 foreach ($node[
'childs'] as & $child) {
688 private function initGlobalParam()
690 $result = pg_query($this->r,
"SELECT * FROM paramv where type='G'");
693 $this->tparam = array();
694 while ($row = pg_fetch_array($result, NULL, PGSQL_ASSOC)) {
695 $this->tparam[$row[
"name"]] = $row[
"val"];
698 private function getGlobalParam($key)
700 if (!$this->tparam) {
701 $this->initGlobalParam();
703 return isset($this->tparam[$key]) ? $this->tparam[$key] : null;
708 SELECT docfam.id AS id, docfam.name AS docfam_name, docname.name AS docname_name, docread.name AS docread_name
710 LEFT JOIN docname ON docfam.id = docname.id
711 LEFT JOIN docread ON docfam.id = docread.id
713 docfam.name IS NULL OR
714 docname.name IS NULL OR
716 ORDER BY docfam.id ASC
718 $result = pg_query($this->r,
$sql);
719 $unnamedDocfam = array();
720 $unnamedDocname = array();
721 $unnamedDocread = array();
722 while ($row = pg_fetch_array($result, NULL, PGSQL_ASSOC)) {
723 if ($row[
'docfam_name'] ==
'') {
724 $unnamedDocfam[] = $row[
'id'];
726 if ($row[
'docname_name'] ==
'') {
727 $unnamedDocname[] = $row[
'id'];
729 if ($row[
'docread_name'] ==
'') {
730 $unnamedDocread[] = $row[
'id'];
733 $unnamedDocfamCount = count($unnamedDocfam);
734 $unnamedDocreadCount = count($unnamedDocread);
735 $unnamedDocnameCount = count($unnamedDocname);
737 if ($unnamedDocfamCount > 0) {
738 $pout[] = sprintf(
"%s unnamed famil%s in docfam: <pre>{%s}</pre>", $unnamedDocfamCount, ($unnamedDocfamCount > 1 ?
'ies' :
'y') , join(
', ', $unnamedDocfam));
740 if ($unnamedDocreadCount > 0) {
741 $pout[] = sprintf(
"%s unnamed famil%s in docfam: <pre>{%s}</pre>", $unnamedDocreadCount, ($unnamedDocreadCount > 1 ?
'ies' :
'y') , join(
', ', $unnamedDocread));
743 if ($unnamedDocnameCount > 0) {
744 $pout[] = sprintf(
"%s unnamed famil%s in docfam: <pre>{%s}</pre>", $unnamedDocnameCount, ($unnamedDocnameCount > 1 ?
'ies' :
'y') , join(
', ', $unnamedDocname));
746 $this->tout[
"missing family name"] = array(
747 "status" => (count($pout) <= 0) ? self::OK : self::BOF,
748 "msg" => (count($pout) <= 0) ?
'' :
'<ul><li>' . join(
'</li><li>', $pout) .
'</li></ul>'
753 $result = pg_query($this->r,
"SELECT id FROM doc WHERE id < 1e9 AND NOT EXISTS (SELECT 1 FROM docread WHERE docread.id = doc.id)");
755 while ($row = pg_fetch_array($result, NULL, PGSQL_ASSOC)) {
756 $pout[] = $row[
'id'];
758 if (count($pout) > 0) {
759 if (count($pout) > 10) {
760 $pout = array_slice($pout, 0, 10);
763 $msg = sprintf(
"%d missing document%s in docread: <pre>{%s}</pre>", count($pout) , (count($pout) > 1 ?
's' :
'') , join(
', ', $pout));
765 $this->tout[
"missing documents in docread"] = array(
766 "status" => (count($pout) == 0) ? self::OK : self::BOF,
772 $result = pg_query($this->r,
"SELECT id FROM docread WHERE id < 1e9 AND NOT EXISTS (SELECT 1 FROM doc WHERE docread.id = doc.id)");
774 while ($row = pg_fetch_array($result, NULL, PGSQL_ASSOC)) {
775 $pout[] = $row[
'id'];
777 if (count($pout) > 0) {
778 if (count($pout) > 10) {
779 $pout = array_slice($pout, 0, 10);
782 $msg = sprintf(
"%d spurious document%s in docread: <pre>{%s}</pre>", count($pout) , (count($pout) > 1 ?
's' :
'') , join(
', ', $pout));
784 $this->tout[
"spurious documents in docread"] = array(
785 "status" => (count($pout) == 0) ? self::OK : self::BOF,
static verifyDbFamily($famid, NormalAttribute $aoa=null)
static getOrphanAttributes($famid)
getUnreferencedPermission()
Exception class use exceptionCode to identifiy correctly exception.
checkStandardConformingStrings()
static isDroppedInNode(&$node, $column)
getSQLDropColumns(&$node, &$cmds=array(), $combined=true)
computeDropColumns(&$node=null, $fromId=0)
checkMissingDocumentsInDocread()
checkUnreferencedAction()
checkUnreferencedParameters()
new_Doc($dbaccess, $id= '', $latest=false)
simpleQuery($dbaccess, $query, &$result=array(), $singlecolumn=false, $singleresult=false, $useStrict=null)
if($file) if($subject==""&&$file) if($subject=="") $err
checkSpuriousDocumentsInDocread()