69        "trac",
"taxf",
"auth",
"rolf",
"assf",
"svyf",
"extt",
"adve",
"fold");
 
   81                        "restore_trash" => 
false,               
 
   82                        "purge_trash" => 
false           
  155        $this->obj_definition = 
$DIC[
"objDefinition"];
 
  156        $this->db = 
$DIC->database();
 
  157        $this->lng = 
$DIC->language();
 
  158        $this->log = 
$DIC[
"ilLog"];
 
  159        $this->rbacadmin = 
$DIC->rbac()->admin();
 
  160        $this->tree = 
$DIC->repositoryTree();
 
  161        $this->
user = $DIC->user();
 
  162        $objDefinition = 
$DIC[
"objDefinition"];
 
  166        $this->rbac_object_types = 
"'" . implode(
"','", $objDefinition->getAllRBACObjects()) . 
"'";
 
  167        $this->rbac_object_types = $objDefinition->getAllRBACObjects();
 
  169        if ($a_log === 
true) {
 
  170            $this->logging = 
true;
 
  174            include_once 
"./Services/Logging/classes/class.ilLog.php";
 
  180            include_once 
'./Services/Logging/classes/class.ilLog.php';
 
  182            $this->scan_log->setLogFormat(
"");
 
  195        return array_keys($this->mode);
 
  211        if ((!in_array($a_mode, array_keys($this->mode)) and $a_mode != 
"all") or !is_bool($a_value)) {
 
  212            $this->throwError(INVALID_PARAM, FATAL, DEBUG);
 
  216        if ($a_mode == 
"all") {
 
  217            foreach ($this->mode as 
$mode => $value) {
 
  218                $this->mode[
$mode] = $a_value;
 
  221            $this->mode[$a_mode] = $a_value;
 
  240        if (!in_array($a_mode, array_keys($this->mode))) {
 
  241            $this->throwError(VALIDATER_UNKNOWN_MODE, WARNING, DEBUG);
 
  245        return $this->mode[$a_mode];
 
  265        if ($this->mode[
"restore"] === 
true) {
 
  266            $this->mode[
"scan"] = 
true;
 
  267            $this->mode[
"purge"] = 
false;
 
  270        if ($this->mode[
"purge"] === 
true) {
 
  271            $this->mode[
"scan"] = 
true;
 
  272            $this->mode[
"restore"] = 
false;
 
  275        if ($this->mode[
"restore_trash"] === 
true) {
 
  276            $this->mode[
"scan"] = 
true;
 
  277            $this->mode[
"purge_trash"] = 
false;
 
  280        if ($this->mode[
"purge_trash"] === 
true) {
 
  281            $this->mode[
"scan"] = 
true;
 
  282            $this->mode[
"restore_trash"] = 
false;
 
  285        if ($this->mode[
"clean"] === 
true) {
 
  286            $this->mode[
"scan"] = 
true;
 
  308        $summary .= 
$lng->txt(
"scanning_system");
 
  310            $summary .= 
$lng->txt(
"disabled");
 
  312            $summary .= 
"<br/>" . 
$lng->txt(
"searching_invalid_refs");
 
  316                $summary .= 
$lng->txt(
"found_none");
 
  319            $summary .= 
"<br/>" . 
$lng->txt(
"searching_invalid_childs");
 
  323                $summary .= 
$lng->txt(
"found_none");
 
  326            $summary .= 
"<br/>" . 
$lng->txt(
"searching_missing_objs");
 
  330                $summary .= 
$lng->txt(
"found_none");
 
  333            $summary .= 
"<br/>" . 
$lng->txt(
"searching_unbound_objs");
 
  337                $summary .= 
$lng->txt(
"found_none");
 
  340            $summary .= 
"<br/>" . 
$lng->txt(
"searching_deleted_objs");
 
  344                $summary .= 
$lng->txt(
"found_none");
 
  347            $summary .= 
"<br/>" . 
$lng->txt(
"searching_invalid_rolfs");
 
  351                $summary .= 
$lng->txt(
"found_none");
 
  354            $summary .= 
"<br/><br/>" . 
$lng->txt(
"analyzing_tree_structure");
 
  356                $summary .= 
$lng->txt(
"tree_corrupt");
 
  358                $summary .= 
$lng->txt(
"done");
 
  364        $summary .= 
"<br /><br />" . 
$lng->txt(
"dumping_tree");
 
  366            $summary .= 
$lng->txt(
"disabled");
 
  369            if ($error_count > 0) {
 
  370                $summary .= 
$lng->txt(
"tree_corrupt");
 
  372                $summary .= 
$lng->txt(
"done");
 
  378        $summary .= 
"<br /><br />" . 
$lng->txt(
"cleaning");
 
  380            $summary .= 
$lng->txt(
"disabled");
 
  382            $summary .= 
"<br />" . 
$lng->txt(
"removing_invalid_refs");
 
  384                $summary .= strtolower(
$lng->txt(
"done"));
 
  386                $summary .= 
$lng->txt(
"nothing_to_remove") . 
$lng->txt(
"skipped");
 
  389            $summary .= 
"<br />" . 
$lng->txt(
"removing_invalid_childs");
 
  391                $summary .= strtolower(
$lng->txt(
"done"));
 
  393                $summary .= 
$lng->txt(
"nothing_to_remove") . 
$lng->txt(
"skipped");
 
  396            $summary .= 
"<br />" . 
$lng->txt(
"removing_invalid_rolfs");
 
  398                $summary .= strtolower(
$lng->txt(
"done"));
 
  400                $summary .= 
$lng->txt(
"nothing_to_remove") . 
$lng->txt(
"skipped");
 
  410        $summary .= 
"<br /><br />" . 
$lng->txt(
"restoring");
 
  413            $summary .= 
$lng->txt(
"disabled");
 
  415            $summary .= 
"<br />" . 
$lng->txt(
"restoring_missing_objs");
 
  417                $summary .= strtolower(
$lng->txt(
"done"));
 
  419                $summary .= 
$lng->txt(
"nothing_to_restore") . 
$lng->txt(
"skipped");
 
  422            $summary .= 
"<br />" . 
$lng->txt(
"restoring_unbound_objs");
 
  424                $summary .= strtolower(
$lng->txt(
"done"));
 
  426                $summary .= 
$lng->txt(
"nothing_to_restore") . 
$lng->txt(
"skipped");
 
  431        $summary .= 
"<br /><br />" . 
$lng->txt(
"restoring_trash");
 
  434            $summary .= 
$lng->txt(
"disabled");
 
  437                $summary .= strtolower(
$lng->txt(
"done"));
 
  439                $summary .= 
$lng->txt(
"nothing_to_restore") . 
$lng->txt(
"skipped");
 
  444        $summary .= 
"<br /><br />" . 
$lng->txt(
"purging");
 
  447            $summary .= 
$lng->txt(
"disabled");
 
  449            $summary .= 
"<br />" . 
$lng->txt(
"purging_missing_objs");
 
  451                $summary .= strtolower(
$lng->txt(
"done"));
 
  453                $summary .= 
$lng->txt(
"nothing_to_purge") . 
$lng->txt(
"skipped");
 
  456            $summary .= 
"<br />" . 
$lng->txt(
"purging_unbound_objs");
 
  458                $summary .= strtolower(
$lng->txt(
"done"));
 
  460                $summary .= 
$lng->txt(
"nothing_to_purge") . 
$lng->txt(
"skipped");
 
  465        $summary .= 
"<br /><br />" . 
$lng->txt(
"purging_trash");
 
  468            $summary .= 
$lng->txt(
"disabled");
 
  471                $summary .= strtolower(
$lng->txt(
"done"));
 
  473                $summary .= 
$lng->txt(
"nothing_to_purge") . 
$lng->txt(
"skipped");
 
  479            $summary .= 
"<br /><br />" . 
$lng->txt(
"cleaning_final");
 
  481                $summary .= 
"<br />" . 
$lng->txt(
"initializing_gaps") . 
" " . strtolower(
$lng->txt(
"done"));
 
  489        foreach ($this->mode as 
$mode => $value) {
 
  490            $arr[] = 
$mode . 
"[" . (int) $value . 
"]";
 
  511        if ($this->mode[
"scan"] !== 
true) {
 
  516        $this->missing_objects = array();
 
  525        $q = 
"SELECT object_data.*, ref_id FROM object_data " .
 
  526             "LEFT JOIN object_reference ON object_data.obj_id = object_reference.obj_id " .
 
  527             "LEFT JOIN tree ON object_reference.ref_id = tree.child " .
 
  528             "WHERE tree.child IS NULL " .
 
  529             "AND (object_reference.obj_id IS NOT NULL " .
 
  530             "    OR object_data.type <> 'file' AND " .
 
  531             $ilDB->in(
'object_data.type', $this->rbac_object_types, 
false, 
'text') .
 
  533        $r = $this->db->query($q);
 
  536            #if (!in_array($row->type,$this->object_types_exclude)) 
  538                $this->missing_objects[] = array(
 
  539                                                    "obj_id" => $row->obj_id,
 
  540                                                    "type" => $row->type,
 
  541                                                    "ref_id" => $row->ref_id,
 
  542                                                    "child" => $row->child,
 
  543                                                    "title" => $row->title,
 
  544                                                    "desc" => $row->description,
 
  545                                                    "owner" => $row->owner,
 
  546                                                    "create_date" => $row->create_date,
 
  547                                                    "last_update" => $row->last_update
 
  553        if (count($this->missing_objects) > 0) {
 
  554            $this->
writeScanLogLine(
"obj_id\ttype\tref_id\tchild\ttitle\tdesc\towner\tcreate_date\tlast_update");
 
  579        if ($this->mode[
"scan"] !== 
true) {
 
  584        $this->invalid_rolefolders = array();
 
  589        $q = 
"SELECT object_data.*, ref_id FROM object_data " .
 
  590             "LEFT JOIN object_reference ON object_data.obj_id = object_reference.obj_id " .
 
  591             "LEFT JOIN tree ON object_reference.ref_id = tree.child " .
 
  592             "WHERE (object_reference.obj_id IS NULL OR tree.child IS NULL) " .
 
  593             "AND object_data.type='rolf'";
 
  594        $r = $this->db->query($q);
 
  597            $this->invalid_rolefolders[] = array(
 
  598                                                "obj_id" => $row->obj_id,
 
  599                                                "type" => $row->type,
 
  600                                                "ref_id" => $row->ref_id,
 
  601                                                "child" => $row->child,
 
  602                                                "title" => $row->title,
 
  603                                                "desc" => $row->description,
 
  604                                                "owner" => $row->owner,
 
  605                                                "create_date" => $row->create_date,
 
  606                                                "last_update" => $row->last_update
 
  611        $q = 
"SELECT object_data.*, ref_id FROM object_data " .
 
  612             "LEFT JOIN object_reference ON object_data.obj_id = object_reference.obj_id " .
 
  613             "LEFT JOIN tree ON object_reference.ref_id = tree.child " .
 
  615             "AND object_data.type='rolf'";
 
  616        $r = $this->db->query($q);
 
  619            $this->invalid_rolefolders[] = array(
 
  620                                                "obj_id" => $row->obj_id,
 
  621                                                "type" => $row->type,
 
  622                                                "ref_id" => $row->ref_id,
 
  623                                                "child" => $row->child,
 
  624                                                "title" => $row->title,
 
  625                                                "desc" => $row->description,
 
  626                                                "owner" => $row->owner,
 
  627                                                "create_date" => $row->create_date,
 
  628                                                "last_update" => $row->last_update
 
  633        if (count($this->invalid_rolefolders) > 0) {
 
  634            $this->
writeScanLogLine(
"obj_id\ttype\tref_id\tchild\ttitle\tdesc\towner\tcreate_date\tlast_update");
 
  657        if ($this->mode[
"scan"] !== 
true) {
 
  662        $this->invalid_rbac_entries = array();
 
  666        $q = 
"SELECT object_data.*, ref_id FROM object_data " .
 
  667             "LEFT JOIN object_reference ON object_data.obj_id = object_reference.obj_id " .
 
  668             "LEFT JOIN tree ON object_reference.ref_id = tree.child " .
 
  669             "WHERE (object_reference.obj_id IS NULL OR tree.child IS NULL) " .
 
  670             "AND object_data.type='rolf'";
 
  671        $r = $this->db->query($q);
 
  674            $this->invalid_rolefolders[] = array(
 
  675                                                "obj_id" => $row->obj_id,
 
  676                                                "type" => $row->type,
 
  677                                                "ref_id" => $row->ref_id,
 
  678                                                "child" => $row->child,
 
  679                                                "title" => $row->title,
 
  680                                                "desc" => $row->description,
 
  681                                                "owner" => $row->owner,
 
  682                                                "create_date" => $row->create_date,
 
  683                                                "last_update" => $row->last_update
 
  688        $q = 
"SELECT object_data.*, ref_id FROM object_data " .
 
  689             "LEFT JOIN object_reference ON object_data.obj_id = object_reference.obj_id " .
 
  690             "LEFT JOIN tree ON object_reference.ref_id = tree.child " .
 
  692             "AND object_data.type='rolf'";
 
  693        $r = $this->db->query($q);
 
  696            $this->invalid_rolefolders[] = array(
 
  697                                                "obj_id" => $row->obj_id,
 
  698                                                "type" => $row->type,
 
  699                                                "ref_id" => $row->ref_id,
 
  700                                                "child" => $row->child,
 
  701                                                "title" => $row->title,
 
  702                                                "desc" => $row->description,
 
  703                                                "owner" => $row->owner,
 
  704                                                "create_date" => $row->create_date,
 
  705                                                "last_update" => $row->last_update
 
  710        if (count($this->invalid_rolefolders) > 0) {
 
  711            $this->
writeScanLogLine(
"obj_id\ttype\tref_id\tchild\ttitle\tdesc\towner\tcreate_date\tlast_update");
 
  752        if ($this->mode[
"scan"] !== 
true) {
 
  757        $this->invalid_references = array();
 
  760        $q = 
"SELECT object_reference.* FROM object_reference " .
 
  761             "LEFT JOIN object_data ON object_data.obj_id = object_reference.obj_id " .
 
  762             "WHERE object_data.obj_id IS NULL " .
 
  763             "OR " . 
$ilDB->in(
'object_data.type', $this->rbac_object_types, 
true, 
'text');
 
  764        $r = $this->db->query($q);
 
  767            $this->invalid_references[] = array(
 
  768                                            "ref_id" => $row->ref_id,
 
  769                                            "obj_id" => $row->obj_id,
 
  770                                            "msg" => 
"Object does not exist." 
  775        if (count($this->invalid_references) > 0) {
 
  812        if ($this->mode[
"scan"] !== 
true) {
 
  817        $this->invalid_childs = array();
 
  821        $q = 
"SELECT tree.*,object_reference.ref_id FROM tree " .
 
  822             "LEFT JOIN object_reference ON tree.child = object_reference.ref_id " .
 
  823             "LEFT JOIN object_data ON object_reference.obj_id = object_data.obj_id " .
 
  824             "WHERE object_reference.ref_id IS NULL or object_data.obj_id IS NULL";
 
  825        $r = $this->db->query($q);
 
  827            $this->invalid_childs[] = array(
 
  828                                            "child" => $row->child,
 
  829                                            "ref_id" => $row->ref_id,
 
  830                                            "msg" => 
"No object found" 
  834        if (count($this->invalid_childs) > 0) {
 
  871        if ($this->mode[
"scan"] !== 
true) {
 
  876        $this->unbound_objects = array();
 
  880        $q = 
"SELECT T1.tree,T1.child,T1.parent," .
 
  881                "T2.tree deleted,T2.parent grandparent " .
 
  883             "LEFT JOIN tree T2 ON T2.child=T1.parent " .
 
  884             "WHERE (T2.tree!=1 OR T2.tree IS NULL) AND T1.parent!=0";
 
  885        $r = $this->db->query($q);
 
  889            if ($row->deleted === 
null) {
 
  890                $this->unbound_objects[] = array(
 
  891                                                "child" => $row->child,
 
  892                                                "parent" => $row->parent,
 
  893                                                "tree" => $row->tree,
 
  894                                                "msg" => 
"No valid parent node found" 
  899        if (count($this->unbound_objects) > 0) {
 
  923        if ($this->mode[
"scan"] !== 
true) {
 
  928        $this->deleted_objects = array();
 
  933        $query = 
"SELECT object_data.*,tree.tree,tree.child,tree.parent,deleted " .
 
  934             "FROM object_data " .
 
  935             "LEFT JOIN object_reference ON object_data.obj_id=object_reference.obj_id " .
 
  936             "LEFT JOIN tree ON tree.child=object_reference.ref_id " .
 
  937             " WHERE tree != 1 " .
 
  939        $r = $this->db->query(
$query);
 
  941        include_once 
'./Services/Calendar/classes/class.ilDateTime.php';
 
  945            $this->deleted_objects[] = array(
 
  946                                            "child" => $row->child,
 
  947                                            "parent" => $row->parent,
 
  948                                            "tree" => $row->tree,
 
  949                                            "type" => $row->type,
 
  950                                            "title" => $row->title,
 
  951                                            "desc" => $row->description,
 
  952                                            "owner" => $row->owner,
 
  953                                            "deleted" => $row->deleted,
 
  954                                            "deleted_timestamp" => $tmp_date->get(
IL_CAL_UNIX),
 
  955                                            "create_date" => $row->create_date,
 
  956                                            "last_update" => $row->last_update
 
  960        if (count($this->deleted_objects) > 0) {
 
 1027        if ($this->mode[
"clean"] !== 
true) {
 
 1033        if ($a_invalid_refs === 
null and isset($this->invalid_references)) {
 
 1038        if (!is_array($a_invalid_refs)) {
 
 1039            $this->throwError(INVALID_PARAM, WARNING, DEBUG);
 
 1043        if (count($a_invalid_refs) == 0) {
 
 1053            '%s::removeInvalidReferences(): Started...',
 
 1056        $ilLog->write(
$message, $ilLog->WARNING);
 
 1061        foreach ($a_invalid_refs as $entry) {
 
 1062            $query = 
"DELETE FROM object_reference WHERE ref_id= " . $this->db->quote($entry[
"ref_id"], 
'integer') .
 
 1063                " AND obj_id = " . $this->db->quote($entry[
"obj_id"], 
'integer') . 
" ";
 
 1067                '%s::removeInvalidReferences(): Reference %s removed',
 
 1071            $ilLog->write(
$message, $ilLog->WARNING);
 
 1093        if ($this->mode[
"clean"] !== 
true) {
 
 1099        if ($a_invalid_childs === 
null and isset($this->invalid_childs)) {
 
 1104        if (!is_array($a_invalid_childs)) {
 
 1105            $this->throwError(INVALID_PARAM, WARNING, DEBUG);
 
 1110        if (count($a_invalid_childs) == 0) {
 
 1120            '%s::removeInvalidChilds(): Started...',
 
 1123        $ilLog->write(
$message, $ilLog->WARNING);
 
 1125        foreach ($a_invalid_childs as $entry) {
 
 1126            $q = 
"DELETE FROM tree WHERE child='" . $entry[
"child"] . 
"'";
 
 1127            $this->db->query($q);
 
 1130                '%s::removeInvalidChilds(): Entry child=%s removed',
 
 1134            $ilLog->write(
$message, $ilLog->WARNING);
 
 1157        if ($this->mode[
"clean"] !== 
true) {
 
 1163        if ($a_invalid_rolefolders === 
null and isset($this->invalid_rolefolders)) {
 
 1168        if (!is_array($a_invalid_rolefolders)) {
 
 1169            $this->throwError(INVALID_PARAM, WARNING, DEBUG);
 
 1174        if (count($a_invalid_rolefolders) == 0) {
 
 1186            '%s::removeInvalidRolefolders(): Started...',
 
 1189        $ilLog->write(
$message, $ilLog->WARNING);
 
 1194        foreach ($a_invalid_rolefolders as $rolf) {
 
 1196            if ($rolf[
"ref_id"] === 
null) {
 
 1199                $this->
writeScanLogLine(
"Created missing reference '" . $rolf[
"ref_id"] . 
"' for rolefolder object '" . $rolf[
"obj_id"] . 
"'");
 
 1204            $obj_data->delete();
 
 1207            $this->
writeScanLogLine(
"Removed invalid rolefolder '" . $rolf[
"title"] . 
"' (id=" . $rolf[
"obj_id"] . 
",ref=" . $rolf[
"ref_id"] . 
") from system");
 
 1229        if ($this->mode[
"restore"] !== 
true) {
 
 1235        if ($a_missing_objects === 
null and isset($this->missing_objects)) {
 
 1240        if (!is_array($a_missing_objects)) {
 
 1241            $this->throwError(INVALID_PARAM, WARNING, DEBUG);
 
 1246        if (count($a_missing_objects) == 0) {
 
 1258            '%s::restoreMissingObjects(): Started...',
 
 1261        $ilLog->write(
$message, $ilLog->WARNING);
 
 1266        foreach ($a_missing_objects as $missing_obj) {
 
 1268            if ($missing_obj[
"ref_id"] === 
null) {
 
 1271                $this->
writeScanLogLine(
"Created missing reference '" . $missing_obj[
"ref_id"] . 
"' for object '" . $missing_obj[
"obj_id"] . 
"'");
 
 1275            #if (!in_array($missing_obj["type"],$this->object_types_exclude))
 
 1277                $rbacadmin->revokePermission($missing_obj[
"ref_id"]);
 
 1284                $this->
writeScanLogLine(
"Restored object '" . $missing_obj[
"title"] . 
"' (id=" . $missing_obj[
"obj_id"] . 
",ref=" . $missing_obj[
"ref_id"] . 
") in 'Restored objects folder'");
 
 1307        if (empty($a_obj_id)) {
 
 1308            $this->throwError(INVALID_PARAM, WARNING, DEBUG);
 
 1312        $query = 
"INSERT INTO object_reference (ref_id,obj_id) " .
 
 1313            "VALUES (" . $next_id = 
$ilDB->nextId(
'object_reference') . 
"," . $this->db->quote($a_obj_id, 
'integer') . 
" )";
 
 1317            '%s::restoreReference(): new reference %s for obj_id %s created',
 
 1322        $ilLog->write(
$message, $ilLog->WARNING);
 
 1342        if ($this->mode[
"restore"] !== 
true) {
 
 1348        if ($a_unbound_objects === 
null and isset($this->unbound_objects)) {
 
 1353        if (!is_array($a_unbound_objects)) {
 
 1354            $this->throwError(INVALID_PARAM, WARNING, DEBUG);
 
 1359            '%s::restoreUnboundObjects(): Started...',
 
 1362        $ilLog->write(
$message, $ilLog->WARNING);
 
 1382        if ($this->mode[
"restore_trash"] !== 
true) {
 
 1388        if ($a_deleted_objects === 
null and isset($this->deleted_objects)) {
 
 1393        if (!is_array($a_deleted_objects)) {
 
 1394            $this->throwError(INVALID_PARAM, WARNING, DEBUG);
 
 1399            '%s::restoreTrash(): Started...',
 
 1402        $ilLog->write(
$message, $ilLog->WARNING);
 
 1408            $q = 
"DELETE FROM tree WHERE tree!=1";
 
 1409            $this->db->query($q);
 
 1412                '%s::restoreTrash(): Removed all trees with tree id <> 1',
 
 1415            $ilLog->write(
$message, $ilLog->WARNING);
 
 1438        if (!is_array($a_nodes)) {
 
 1439            $this->throwError(INVALID_PARAM, WARNING, DEBUG);
 
 1444        if (count($a_nodes) == 0) {
 
 1450            '%s::restoreDeletedObjects()): Started...',
 
 1453        $ilLog->write(
$message, $ilLog->WARNING);
 
 1458        foreach ($a_nodes as $key => $node) {
 
 1459            if ($node[
"type"] == 
"rolf") {
 
 1461                $tree->deleteTree($node);
 
 1464                $obj_data->delete();
 
 1465                unset($a_nodes[$key]);
 
 1470        foreach ($a_nodes as $node) {
 
 1472            $tree->deleteTree($node);
 
 1474            $rbacadmin->revokePermission($node[
"child"]);
 
 1498        if (!is_array($a_nodes)) {
 
 1499            $this->throwError(INVALID_PARAM, WARNING, DEBUG);
 
 1504        if (count($a_nodes) == 0) {
 
 1513        $subnodes = array();
 
 1517            '%s::restoreSubTrees(): Started...',
 
 1520        $ilLog->write(
$message, $ilLog->WARNING);
 
 1523        foreach ($a_nodes as $node) {
 
 1525            $topnode = 
$tree->getNodeData($node[
"child"], $node[
'tree']);
 
 1529            if ($topnode[
"type"] == 
"rolf") {
 
 1538            $subnodes[$node[
"child"]] = 
$tree->getSubtree($topnode);
 
 1541            $tree->deleteTree($topnode);
 
 1546        foreach ($subnodes as $key => $subnode) {
 
 1557            array_shift($subnode);
 
 1560            if (count($subnode) > 0) {
 
 1561                foreach ($subnode as $node) {
 
 1562                    $rbacadmin->revokePermission($node[
"child"]);
 
 1564                    $obj_data->putInTree($node[
"parent"]);
 
 1565                    $obj_data->setPermissions($node[
"parent"]);
 
 1593        if ($this->mode[
"purge_trash"] !== 
true) {
 
 1599        if ($a_nodes === 
null and isset($this->deleted_objects)) {
 
 1603            '%s::purgeTrash(): Started...',
 
 1606        $ilLog->write(
$message, $ilLog->WARNING);
 
 1626        if ($this->mode[
"purge"] !== 
true) {
 
 1632        if ($a_nodes === 
null and isset($this->unbound_objects)) {
 
 1637            '%s::purgeUnboundObjects(): Started...',
 
 1640        $ilLog->write(
$message, $ilLog->WARNING);
 
 1660        if ($this->mode[
"purge"] !== 
true) {
 
 1666        if ($a_nodes === 
null and isset($this->missing_objects)) {
 
 1671            '%s::purgeMissingObjects(): Started...',
 
 1674        $ilLog->write(
$message, $ilLog->WARNING);
 
 1693        $count_limit = 
$ilUser->getPref(
"systemcheck_count_limit");
 
 1694        if (!is_numeric($count_limit) || $count_limit < 0) {
 
 1695            $count_limit = count($a_nodes);
 
 1697        $timestamp_limit = time();
 
 1698        $age_limit = 
$ilUser->getPref(
"systemcheck_age_limit");
 
 1699        if (is_numeric($age_limit) && $age_limit > 0) {
 
 1700            $timestamp_limit -= $age_limit * 60 * 60 * 24;
 
 1702        $type_limit = 
$ilUser->getPref(
"systemcheck_type_limit");
 
 1704            $type_limit = trim($type_limit);
 
 1705            if (strlen($type_limit) == 0) {
 
 1711        if (!is_array($a_nodes)) {
 
 1712            $this->throwError(INVALID_PARAM, WARNING, DEBUG);
 
 1719        foreach ($a_nodes as $node) {
 
 1720            if ($type_limit && $node[
'type'] != $type_limit) {
 
 1723                        $node[
'child'] . 
"\t\t" . $node[
'type'] . 
"\t\t" . $node[
'title']
 
 1730            if ($count > $count_limit) {
 
 1731                $this->
writeScanLogLine(
"Stopped purging after " . ($count - 1) . 
" objects, because count limit was reached: " . $count_limit);
 
 1734            if ($node[
"deleted_timestamp"] > $timestamp_limit) {
 
 1735                $this->
writeScanLogLine(
"Stopped purging after " . ($count - 1) . 
" objects, because timestamp limit was reached: " . date(
"c", $timestamp_limit));
 
 1739            $ref_id = ($node[
"child"]) ? $node[
"child"] : $node[
"ref_id"];
 
 1742            if ($node_obj === 
false) {
 
 1743                $this->invalid_objects[] = $node;
 
 1748                '%s::purgeObjects(): Removing object (id:%s ref:%s)',
 
 1753            $ilLog->write(
$message, $ilLog->WARNING);
 
 1755            $startTime = microtime(
true);
 
 1756            $node_obj->delete();
 
 1758            $endTime = microtime(
true);
 
 1761                "\t" . $node[
'type'] . 
"\t" . round($endTime - $startTime, 1) . 
"\t" . $node[
'title']);
 
 1789            '%s::initGapsInTree(): Started...',
 
 1792        $ilLog->write(
$message, $ilLog->WARNING);
 
 1795        if ($this->mode[
"clean"] !== 
true) {
 
 1818        $call_loc = $error->backtrace[count($error->backtrace) - 1];
 
 1819        $num_args = count($call_loc[
"args"]);
 
 1821        if ($num_args > 0) {
 
 1822            foreach ($call_loc[
"args"] as $arg) {
 
 1823                $type = gettype($arg);
 
 1827                        $value = strlen($arg);
 
 1831                        $value = count($arg);
 
 1835                        $value = get_class($arg);
 
 1839                        $value = ($arg) ? 
"true" : 
"false";
 
 1847                $arg_list[] = array(
 
 1849                                    "value" => 
"(" . $value . 
")" 
 1853            foreach ($arg_list as $arg) {
 
 1854                $arg_str .= implode(
"", $arg) . 
" ";
 
 1858        $err_msg = 
"<br/><b>" . $error->getCode() . 
":</b> " . $error->getMessage() . 
" in " . $call_loc[
"class"] . $call_loc[
"type"] . $call_loc[
"function"] . 
"()" .
 
 1859                   "<br/>Called from: " . basename($call_loc[
"file"]) . 
" , line " . $call_loc[
"line"] .
 
 1860                   "<br/>Passed parameters: [" . $num_args . 
"] " . $arg_str . 
"<br/>";
 
 1863        if ($error->getUserInfo()) {
 
 1864            printf(
"<br/>Parameter details:");
 
 1866            var_dump($call_loc[
"args"]);
 
 1870        if ($error->getCode() == FATAL) {
 
 1881        foreach ($a_arr as $entry) {
 
 1882            $this->scan_log->write(implode(
"\t", $entry));
 
 1892        $this->scan_log->write($a_msg);
 
 1931        $logs = array_keys($a_scan_log, $this->scan_log_separator . 
"\n");
 
 1933        if (count($logs) > 0) {
 
 1934            return array_slice($a_scan_log, array_pop($logs) + 2);
 
 1964        $q = 
'SELECT child FROM tree GROUP BY child HAVING COUNT(*) > 1';
 
 1965        $r = $this->db->query($q);
 
 1966        $duplicateNodes = array();
 
 1968            $duplicateNodes[] = $row->child;
 
 1972        $q = 
"SELECT tree.*,ref.ref_id,dat.obj_id objobj_id,ref.obj_id refobj_id,ref.deleted,dat.* " 
 1974            . 
"RIGHT JOIN object_reference ref ON tree.child = ref.ref_id " 
 1975            . 
"RIGHT JOIN object_data dat ON ref.obj_id = dat.obj_id " 
 1977            . 
"ORDER BY tree, lft, type, dat.title";
 
 1978        $r = $this->db->query($q);
 
 1982            . 
'<td>tree, child, parent, lft, rgt, depth</td>' 
 1983            . 
'<td>ref_id, ref.obj_id, deleted</td>' 
 1984            . 
'<td>obj_id, type, owner, title</td>' 
 1993        $repository_tree_count = 0;
 
 1994        $trash_trees_count = 0;
 
 1995        $other_trees_count = 0;
 
 1996        $not_in_tree_count = 0;
 
 1999        $previousNumber = 0;
 
 2005            if ($this->workspace_object_ids &&
 
 2006                in_array($row->objobj_id, $this->workspace_object_ids)) {
 
 2011            if (is_null($row->child)) {
 
 2012                switch ($row->type) {
 
 2026                        if (is_null($row->ref_id)) {
 
 2036                            $isParentOkay = 
false;
 
 2039                            $isDepthOkay = 
false;
 
 2053                        $isParentOkay = 
false;
 
 2056                        $isDepthOkay = 
false;
 
 2061                $not_in_tree_count++;
 
 2066                    . (($isRowOkay) ? 
'' : 
'<font color=#ff0000>')
 
 2068                    . $row->child . 
', ' 
 2069                    . (($isParentOkay) ? 
'' : 
'parent:<b>')
 
 2071                    . (($isParentOkay) ? 
'' : 
'</b>')
 
 2073                    . (($isLftOkay) ? 
'' : 
'lft:<b>')
 
 2075                    . (($isLftOkay) ? 
'' : 
'</b>')
 
 2077                    . (($isRgtOkay) ? 
'' : 
'rgt:<b>')
 
 2079                    . (($isRgtOkay) ? 
'' : 
'</b>')
 
 2081                    . (($isDepthOkay) ? 
'' : 
'depth:<b>')
 
 2083                    . (($isDepthOkay) ? 
'' : 
'</b>')
 
 2084                    . (($isRowOkay) ? 
'' : 
'</font>')
 
 2086                    . (($isRowOkay) ? 
'' : 
'<font color=#ff0000>')
 
 2087                    . (($isRefRefOkay && $isChildOkay) ? 
'' : 
'ref.ref_id:<b>')
 
 2089                    . (($isRefRefOkay && $isChildOkay) ? 
'' : 
'</b>')
 
 2091                    . (($isRefObjOkay) ? 
'' : 
'ref.obj_id:<b>')
 
 2093                    . (($isRefObjOkay) ? 
'' : 
'</b>')
 
 2094                    . (($isRowOkay) ? 
'' : 
'<font color=#ff0000>')
 
 2095                    . (($row->deleted != 
null) ? 
', ' . $row->deleted : 
'')
 
 2097                    . (($isRowOkay) ? 
'' : 
'<font color=#ff0000>')
 
 2099                    . $row->obj_id . 
', ' 
 2101                    . $row->login . 
', ' 
 2103                    . (($isRowOkay) ? 
'' : 
' <b>*ERROR*</b><font color=#ff0000>')
 
 2113            for (
$i = 1; 
$i < $row->depth; 
$i++) {
 
 2118            if (count($stack) == 0 || $stack[0]->tree != $row->tree) {
 
 2120                $previousNumber = $row->lft - 1;
 
 2126            while (count($stack) > 0 && $stack[count($stack) - 1]->rgt < $row->lft) {
 
 2127                $popped = array_pop($stack);
 
 2130                $gap = $popped->rgt - $previousNumber - 1;
 
 2133                    for (
$i = 1; 
$i < $popped->depth; 
$i++) {
 
 2134                        $poppedIndent .= 
". ";
 
 2138                        . 
'<td colspan=2><div align="right">' 
 2139                        . 
'<font color=#00cc00>*gap* for ' . ($gap / 2) . 
' nodes at end of </font>' 
 2142                        . 
'<font color=#00cc00>' 
 2144                        . $popped->obj_id . 
', ' 
 2145                        . $popped->type . 
', ' 
 2146                        . $popped->login . 
', ' 
 2153                $previousNumber = $popped->rgt;
 
 2162            $isChildOkay = 
true;
 
 2163            $isParentOkay = 
true;
 
 2166            $isDepthOkay = 
true;
 
 2169            if (count($stack) > 0) {
 
 2170                $parent = $stack[count($stack) - 1];
 
 2171                if ($parent->depth + 1 != $row->depth) {
 
 2172                    $isDepthOkay = 
false;
 
 2175                if ($parent->child != $row->parent) {
 
 2176                    $isParentOkay = 
false;
 
 2179                if (
$GLOBALS[
'ilSetting']->
get(
'main_tree_impl', 
'ns') == 
'ns') {
 
 2180                    if ($parent->lft >= $row->lft) {
 
 2184                    if ($parent->rgt <= $row->rgt) {
 
 2192            if (
$GLOBALS[
'ilSetting']->
get(
'main_tree_impl', 
'ns') == 
'ns') {
 
 2193                if ($row->lft >= $row->rgt) {
 
 2199            if (in_array($row->child, $duplicateNodes)) {
 
 2200                $isChildOkay = 
false;
 
 2205            $isRefRefOkay = 
true;
 
 2206            $isRefObjOkay = 
true;
 
 2207            if ($row->ref_id == 
null) {
 
 2208                $isRefRefOkay = 
false;
 
 2211            if ($row->obj_id == 
null) {
 
 2212                $isRefObjOkay = 
false;
 
 2222            if (
$GLOBALS[
'ilSetting']->
get(
'main_tree_impl', 
'ns') == 
'ns') {
 
 2223                $gap = $row->lft - $previousNumber - 1;
 
 2224                $previousNumber = $row->lft;
 
 2228                        . 
'<td colspan=2><div align="right">' 
 2229                        . 
'<font color=#00cc00>*gap* for ' . ($gap / 2) . 
' nodes between </font>' 
 2232                        . 
'<font color=#00cc00>siblings</font>' 
 2244                    . (($isRowOkay) ? 
'' : 
'<font color=#ff0000>')
 
 2246                    . $row->child . 
', ' 
 2247                    . (($isParentOkay) ? 
'' : 
'parent:<b>')
 
 2249                    . (($isParentOkay) ? 
'' : 
'</b>')
 
 2251                    . (($isLftOkay) ? 
'' : 
'lft:<b>')
 
 2253                    . (($isLftOkay) ? 
'' : 
'</b>')
 
 2255                    . (($isRgtOkay) ? 
'' : 
'rgt:<b>')
 
 2257                    . (($isRgtOkay) ? 
'' : 
'</b>')
 
 2259                    . (($isDepthOkay) ? 
'' : 
'depth:<b>')
 
 2261                    . (($isDepthOkay) ? 
'' : 
'</b>')
 
 2262                    . (($isRowOkay) ? 
'' : 
'</font>')
 
 2264                    . (($isRowOkay) ? 
'' : 
'<font color=#ff0000>')
 
 2265                    . (($isRefRefOkay && $isChildOkay) ? 
'' : 
'ref.ref_id:<b>')
 
 2267                    . (($isRefRefOkay && $isChildOkay) ? 
'' : 
'</b>')
 
 2269                    . (($isRefObjOkay) ? 
'' : 
'ref.obj_id:<b>')
 
 2271                    . (($isRefObjOkay) ? 
'' : 
'</b>')
 
 2272                    . (($isRowOkay) ? 
'' : 
'<font color=#ff0000>')
 
 2273                    . (($row->tree < 0) ? 
', ' . $row->deleted : 
'')
 
 2275                    . (($isRowOkay) ? 
'' : 
'<font color=#ff0000>')
 
 2277                    . $row->obj_id . 
', ' 
 2279                    . $row->login . 
', ' 
 2281                    . (($isRowOkay) ? 
'' : 
' <b>*ERROR*</b><font color=#ff0000>')
 
 2293            if ($row->tree == 1) {
 
 2294                $repository_tree_count++;
 
 2295            } elseif ($row->tree < 0) {
 
 2296                $trash_trees_count++;
 
 2298                $other_trees_count++;
 
 2304        while (count($stack) > 0) {
 
 2305            $popped = array_pop($stack);
 
 2308            $gap = $popped->rgt - $previousNumber - 1;
 
 2311                for (
$i = 1; 
$i < $popped->depth; 
$i++) {
 
 2312                    $poppedIndent .= 
". ";
 
 2316                    . 
'<td colspan=2><div align="right">' 
 2317                    . 
'<font color=#00cc00>*gap* for ' . ($gap / 2) . 
' nodes at end of </font>' 
 2320                    . 
'<font color=#00cc00>' 
 2322                    . $popped->obj_id . 
', ' 
 2323                    . $popped->type . 
', ' 
 2324                    . $popped->login . 
', ' 
 2331            $previousNumber = $popped->rgt;
 
 2338        if ($error_count > 0) {
 
 2339            $this->
writeScanLogLine(
'<font color=#ff0000>' . $error_count . 
' errors found while dumping tree.</font>');
 
 2343        $this->
writeScanLogLine(
"$repository_tree_count nodes in repository tree");
 
 2349        return $error_count;
 
 2356        if (!is_array($this->media_pool_ids)) {
 
 2357            $this->media_pool_ids = array();
 
 2358            $query = 
"SELECT child FROM mep_tree ";
 
 2360            while ($row = 
$ilDB->fetchObject(
$res)) {
 
 2361                $this->media_pool_ids[] = $row->child;
 
 2365        return in_array($a_obj_id, $this->media_pool_ids) ? 
true : 
false;
 
 2382        return in_array($a_type, $this->object_types_exclude);
 
 2389        if ($this->workspace_object_ids === 
null) {
 
 2390            $this->workspace_object_ids = array();
 
 2393            $set = 
$ilDB->query(
"SELECT DISTINCT(obj_id) FROM object_reference_ws");
 
 2394            while ($row = 
$ilDB->fetchAssoc($set)) {
 
 2395                $this->workspace_object_ids[] = $row[
"obj_id"];
 
 2399            $set = 
$ilDB->query(
"SELECT id FROM usr_portfolio");
 
 2400            while ($row = 
$ilDB->fetchAssoc($set)) {
 
 2401                $this->workspace_object_ids[] = $row[
"id"];
 
 2408        if (
sizeof($a_data)) {
 
 2412            if (is_array($this->workspace_object_ids)) {
 
 2413                foreach ($a_data as $idx => $item) {
 
 2414                    if (in_array($item[$a_index], $this->workspace_object_ids)) {
 
 2415                        unset($a_data[$idx]);
 
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
An exception for terminatinating execution or to throw for unit testing.
return true
Flag indicating whether or not HTTP headers will be sent when outputting captcha image/audio.
@classDescription Date and time handling
static getInstanceByRefId($a_ref_id, $stop_on_error=true)
get an instance of an Ilias object by reference id
static _removeEntry($a_tree, $a_child, $a_db_table="tree")
STATIC METHOD Removes a single entry from a tree.
ILIAS Data Validator & Recovery Tool.
restoreUnboundObjects($a_unbound_objects=null)
Restore objects (and their subobjects) to RecoveryFolder that are valid but not linked correctly in t...
removeInvalidRolefolders($a_invalid_rolefolders=null)
Removes invalid rolefolders.
removeInvalidChilds($a_invalid_childs=null)
Removes all tree entries without any link to a valid object.
deleteScanLog()
Delete scan log.
findUnboundObjects()
Search database for all tree entries having no valid parent (=> no valid path to root node) and store...
__construct($a_log=false)
Constructor.
handleErr($error)
Callback function handles PEAR_error and outputs detailed infos about error TODO: implement that in g...
isExcludedFromRecovery($a_type, $a_obj_id)
Check if type is excluded from recovery.
restoreReference($a_obj_id)
restore a reference for an object Creates a new reference entry in DB table object_reference for $a_o...
purgeMissingObjects($a_nodes=null)
Removes all missing objects from system.
getInvalidChilds()
Gets all tree entries without any link to a valid object.
getDeletedObjects()
Gets all object in trash.
getInvalidReferences()
Gets all reference entries that are not linked with a valid object id.
writeScanLogArray($a_arr)
filterWorkspaceObjects(array &$a_data, $a_index="obj_id")
getInvalidRolefolders()
Gets invalid rolefolders (same as missing objects)
purgeObjects($a_nodes)
removes objects from system
removeInvalidReferences($a_invalid_refs=null)
Removes all reference entries that are linked with invalid object IDs.
checkTreeStructure($a_startnode=null)
restoreSubTrees($a_nodes)
Restore objects (and their subobjects) to RecoveryFolder.
initGapsInTree()
Initializes gaps in lft/rgt values of a tree.
setModeDependencies()
Sets modes by considering mode dependencies; some modes require other modes to be activated.
getUnboundObjects()
Gets all tree entries having no valid parent (=> no valid path to root node) Returns an array with ch...
restoreDeletedObjects($a_nodes)
Restore deleted objects (and their subobjects) to RecoveryFolder.
isModeEnabled($a_mode)
Is a particular mode enabled?
get_last_scan($a_scan_log)
getPossibleModes()
get possible ilValidator modes @access public
restoreTrash($a_deleted_objects=null)
Restore all objects in trash to RecoveryFolder NOTE: All objects will be restored to top of RecoveryF...
restoreMissingObjects($a_missing_objects=null)
Restores missing reference and/or tree entry for all objects found by this::getMissingObjects() Resto...
findDeletedObjects()
Search database for all tree entries having no valid parent (=> no valid path to root node) and store...
hasScanLog()
Quickly determine if there is a scan log.
dumpTree()
Dumps the Tree structure into the scan log.
findInvalidChilds()
Search database for all tree entries without any link to a valid object and stores result in $this->i...
setMode($a_mode, $a_value)
set mode of ilValidator Usage: setMode("restore",true) => enable object restorey setMode("all",...
findMissingObjects()
Search database for all object entries with missing reference and/or tree entry and stores result in ...
findInvalidRBACEntries()
Search database for all role entries that are linked to invalid ref_ids.
purgeTrash($a_nodes=null)
Removes all objects in trash from system.
findInvalidReferences()
Search database for all reference entries that are not linked with a valid object id and stores resul...
findInvalidRolefolders()
Search database for all rolefolder object entries with missing reference entry.
validate()
Performs the validation for each enabled mode.
purgeUnboundObjects($a_nodes=null)
Removes all invalid objects from system.
getMissingObjects()
Gets all object entries with missing reference and/or tree entry.
foreach($_POST as $key=> $value) $res