Passed
Pull Request — master (#5001)
by
unknown
06:31
created

clearTasksHistory()   B

Complexity

Conditions 6
Paths 9

Size

Total Lines 40
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 20
c 1
b 0
f 0
nc 9
nop 0
dl 0
loc 40
rs 8.9777
1
<?php
2
/**
3
 * Teampass - a collaborative passwords manager.
4
 * ---
5
 * This file is part of the TeamPass project.
6
 * 
7
 * TeamPass is free software: you can redistribute it and/or modify it
8
 * under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation, version 3 of the License.
10
 * 
11
 * TeamPass is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU General Public License for more details.
15
 * 
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18
 * 
19
 * Certain components of this file may be under different licenses. For
20
 * details, see the `licenses` directory or individual file headers.
21
 * ---3.0.0.22
22
 * @file      background_tasks___functions.php
23
 * @author    Nils Laumaillé ([email protected])
24
 * @copyright 2009-2025 Teampass.net
25
 * @license   GPL-3.0
26
 * @see       https://www.teampass.net
27
 */
28
29
use TeampassClasses\NestedTree\NestedTree;
30
31
// Load config
32
require_once __DIR__.'/../includes/config/include.php';
33
require_once __DIR__.'/../includes/config/settings.php';
34
header('Content-type: text/html; charset=utf-8');
35
header('Cache-Control: no-cache, must-revalidate');
36
37
38
/**
39
 * Permits to log task status
40
 *
41
 * @param string $status
42
 * @param string $job
43
 * @param integer $enable_tasks_log
44
 * @param integer|null $id
45
 * @return integer
46
 */
47
function doLog(string $status, string $job, int $enable_tasks_log = 0, ?int $id = null, ?int $treated_objects = null): int
48
{
49
    clearTasksLog();
50
    clearTasksHistory();
51
52
    // is log enabled?
53
    if ((int) $enable_tasks_log === 1) {
54
        // is log start?
55
        if (is_null($id) === true) {
56
            DB::insert(
57
                prefixTable('background_tasks_logs'),
58
                array(
59
                    'created_at' => time(),
60
                    'job' => $job,
61
                    'status' => $status,
62
                )
63
            );
64
            return DB::insertId();
65
        }
66
67
        // Case is an update
68
        DB::update(
69
            prefixTable('background_tasks_logs'),
70
            array(
71
                'status' => $status,
72
                'finished_at' => time(),
73
                'treated_objects' => $treated_objects,
74
            ),
75
            'increment_id = %i',
76
            $id
77
        );
78
    }
79
    
80
    return -1;
81
}
82
83
function clearTasksHistory(): void
84
{
85
    global $SETTINGS;
86
87
    // Run only once per PHP process (doLog can be called multiple times in a run)
88
    static $alreadyDone = false;
89
    if ($alreadyDone === true) {
90
        return;
91
    }
92
    $alreadyDone = true;
93
94
    $historyDelay = isset($SETTINGS['tasks_history_delay']) === true ? (int) $SETTINGS['tasks_history_delay'] : 0;
95
96
    // Safety: this setting is meant to be in seconds (admin UI stores seconds),
97
    // but if for any reason it is stored in days, convert it.
98
    if ($historyDelay > 0 && $historyDelay < 86400) {
99
        $historyDelay = $historyDelay * 86400;
100
    }
101
102
    if ($historyDelay <= 0) {
103
        return;
104
    }
105
106
    $threshold = time() - $historyDelay;
107
108
    // Delete subtasks linked to old finished tasks (avoid orphans)
109
    DB::query(
110
        'DELETE s
111
         FROM ' . prefixTable('background_subtasks') . ' s
112
         INNER JOIN ' . prefixTable('background_tasks') . ' t ON t.increment_id = s.task_id
113
         WHERE t.finished_at > 0
114
           AND t.finished_at < %i',
115
        $threshold
116
    );
117
118
    // Delete old finished tasks from history
119
    DB::delete(
120
        prefixTable('background_tasks'),
121
        'finished_at > 0 AND finished_at < %i',
122
        $threshold
123
    );
124
}
125
126
function clearTasksLog()
127
{
128
    global $SETTINGS;
129
    $retentionDays = isset($SETTINGS['tasks_log_retention_delay']) === true ? $SETTINGS['tasks_log_retention_delay'] : 30;
130
    $timestamp = strtotime('-'.$retentionDays.' days');
131
    DB::delete(
132
        prefixTable('background_tasks_logs'),
133
        'created_at < %s',
134
        $timestamp
135
    );
136
}
137
138
/**
139
 * Permits to run a task
140
 *
141
 * @param array $message
142
 * @param string $SETTINGS
143
 * @return void
144
 */
145
function provideLog(string $message, array $SETTINGS)
146
{
147
    if (defined('LOG_TO_SERVER') && LOG_TO_SERVER === true) {
148
        error_log((string) date($SETTINGS['date_format'] . ' ' . $SETTINGS['time_format'], time()) . ' - '.$message);
149
    }
150
}
151
152
function performVisibleFoldersHtmlUpdate (int $user_id)
153
{
154
    $html = [];
155
156
    // rebuild tree
157
    $tree = new NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title');
158
    $tree->rebuild();
159
160
    // get current folders visible for user
161
    $cache_tree = DB::queryFirstRow(
162
        'SELECT increment_id, data FROM ' . prefixTable('cache_tree') . ' WHERE user_id = %i',
163
        $user_id
164
    );
165
    $folders = json_decode($cache_tree['data'], true);
166
    foreach ($folders as $folder) {
167
        $idFolder = (int) explode("li_", $folder['id'])[1];
168
169
        // Get path
170
        $path = '';
171
        $tree_path = $tree->getPath($idFolder, false);
172
        foreach ($tree_path as $fld) {
173
            $path .= empty($path) === true ? $fld->title : '/'.$fld->title;
174
        }
175
176
        // get folder info
177
        $folder = DB::queryFirstRow(
178
            'SELECT title, parent_id, personal_folder FROM ' . prefixTable('nested_tree') . ' WHERE id = %i',
179
            $idFolder
180
        );
181
182
        // finalize
183
        array_push(
184
            $html,
185
            [
186
                "id" => $idFolder,
187
                "level" => count($tree_path),
188
                "title" => $folder['title'],
189
                "disabled" => 0,
190
                "parent_id" => $folder['parent_id'],
191
                "perso" => $folder['personal_folder'],
192
                "path" => $path,
193
                "is_visible_active" => 1,
194
            ]
195
        );
196
    }
197
198
    DB::update(
199
        prefixTable('cache_tree'),
200
        array(
201
            'visible_folders' => json_encode($html),
202
            'timestamp' => time(),
203
        ),
204
        'increment_id = %i',
205
        (int) $cache_tree['increment_id']
206
    );
207
}
208
209
210
function subTaskStatus($taskId)
211
{
212
    $subTasks = DB::query(
213
        'SELECT * FROM ' . prefixTable('background_subtasks') . ' WHERE task_id = %i',
214
        $taskId
215
    );
216
217
    $status = 0;
218
    foreach ($subTasks as $subTask) {
219
        if ($subTask['is_in_progress'] === 1) {
220
            $status = 1;
221
            break;
222
        }
223
    }
224
225
    return $status;
226
}
227