Issues (2811)

public/htdocs/ecm/index.php (2 issues)

1
<?php
2
3
/* Copyright (C) 2008-2017  Laurent Destailleur         <[email protected]>
4
 * Copyright (C) 2008-2010  Regis Houssin               <[email protected]>
5
 * Copyright (C) 2024       Rafael San José             <[email protected]>
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19
 *
20
 * You can call this page with param module=medias to get a filemanager for medias.
21
 */
22
23
use Dolibarr\Code\Core\Classes\Form;
24
use Dolibarr\Code\Ecm\Classes\EcmDirectory;
25
use Dolibarr\Code\User\Classes\User;
26
use Dolibarr\Lib\ViewMain;
27
28
/**
29
 *  \file       htdocs/ecm/index.php
30
 *  \ingroup    ecm
31
 *  \brief      Main page for ECM section area
32
 */
33
34
// Load Dolibarr environment
35
require constant('DOL_DOCUMENT_ROOT') . '/main.inc.php';
36
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/ecm.lib.php';
37
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/files.lib.php';
38
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/treeview.lib.php';
39
40
// Load translation files required by the page
41
$langs->loadLangs(array('ecm', 'companies', 'other', 'users', 'orders', 'propal', 'bills', 'contracts'));
42
43
// Get parameters
44
$socid = GETPOSTINT('socid');
45
$action = GETPOST('action', 'aZ09');
46
$section = GETPOSTINT('section') ? GETPOSTINT('section') : GETPOSTINT('section_id');
47
if (!$section) {
48
    $section = 0;
49
}
50
$section_dir = GETPOST('section_dir', 'alpha');
51
$overwritefile = GETPOSTINT('overwritefile');
52
53
$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
54
$sortfield = GETPOST('sortfield', 'aZ09comma');
55
$sortorder = GETPOST('sortorder', 'aZ09comma');
56
$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
57
if (empty($page) || $page == -1) {
58
    $page = 0;
59
}     // If $page is not defined, or '' or -1
60
$offset = $limit * $page;
61
$pageprev = $page - 1;
62
$pagenext = $page + 1;
63
if (!$sortorder) {
64
    $sortorder = "ASC";
65
}
66
if (!$sortfield) {
67
    $sortfield = "name";
68
}
69
70
$ecmdir = new EcmDirectory($db);
71
if ($section > 0) {
72
    $result = $ecmdir->fetch($section);
73
    if (!($result > 0)) {
74
        dol_print_error($db, $ecmdir->error);
75
        exit;
76
    }
77
}
78
79
$form = new Form($db);
80
$ecmdirstatic = new EcmDirectory($db);
81
$userstatic = new User($db);
82
83
$error = 0;
84
85
// Security check
86
if ($user->socid) {
87
    $socid = $user->socid;
88
}
89
$result = restrictedArea($user, 'ecm', 0);
90
91
$permissiontoread = $user->hasRight('ecm', 'read');
92
$permissiontocreate = $user->hasRight('ecm', 'upload');
93
$permissiontocreatedir = $user->hasRight('ecm', 'setup');
94
$permissiontodelete = $user->hasRight('ecm', 'upload');
95
$permissiontodeletedir = $user->hasRight('ecm', 'setup');
96
97
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
98
$hookmanager->initHooks(array('ecmindexcard', 'globalcard'));
99
100
/*
101
 *	Actions
102
 */
103
104
// TODO Replace sendit and confirm_deletefile with
105
//$backtopage=$_SERVER["PHP_SELF"].'?file_manager=1&website='.$websitekey.'&pageid='.$pageid;   // used after a confirm_deletefile into actions_linkedfiles.inc.php
106
//include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php';
107
108
// Upload file (code similar but different than actions_linkedfiles.inc.php)
109
if (GETPOST("sendit", 'alphanohtml') && getDolGlobalString('MAIN_UPLOAD_DOC') && $permissiontocreate) {
110
    // Define relativepath and upload_dir
111
    $relativepath = '';
112
    if ($ecmdir->id) {
113
        $relativepath = $ecmdir->getRelativePath();
114
    } else {
115
        $relativepath = $section_dir;
116
    }
117
    $upload_dir = $conf->ecm->dir_output . '/' . $relativepath;
118
119
    $userfiles = [];
120
    if (is_array($_FILES['userfile'])) {
121
        if (is_array($_FILES['userfile']['tmp_name'])) {
122
            $userfiles = $_FILES['userfile']['tmp_name'];
123
        } else {
124
            $userfiles = array($_FILES['userfile']['tmp_name']);
125
        }
126
    }
127
128
    foreach ($userfiles as $key => $userfile) {
129
        if (empty($_FILES['userfile']['tmp_name'][$key])) {
130
            $error++;
131
            if ($_FILES['userfile']['error'][$key] == 1 || $_FILES['userfile']['error'][$key] == 2) {
132
                setEventMessages($langs->trans('ErrorFileSizeTooLarge'), null, 'errors');
133
            } else {
134
                setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("File")), null, 'errors');
135
            }
136
        }
137
    }
138
139
    if (!$error) {
140
        $generatethumbs = 0;
141
        $res = dol_add_file_process($upload_dir, $overwritefile, 1, 'userfile', '', null, '', $generatethumbs);
142
        if ($res > 0) {
143
            $result = $ecmdir->changeNbOfFiles('+');
144
        }
145
    }
146
}
147
148
// Remove file (code similar but different than actions_linkedfiles.inc.php)
149
if ($action == 'confirm_deletefile' && $permissiontodelete) {
150
    if (GETPOST('confirm') == 'yes') {
151
        // GETPOST('urlfile','alpha') is full relative URL from ecm root dir. Contains path of all sections.
152
153
        $upload_dir = $conf->ecm->dir_output . ($relativepath ? '/' . $relativepath : '');
154
        $file = $upload_dir . "/" . GETPOST('urlfile', 'alpha');
155
        $ret = dol_delete_file($file); // This include also the delete from file index in database.
156
        if ($ret) {
157
            $urlfiletoshow = GETPOST('urlfile', 'alpha');
158
            $urlfiletoshow = preg_replace('/\.noexe$/', '', $urlfiletoshow);
159
            setEventMessages($langs->trans("FileWasRemoved", $urlfiletoshow), null, 'mesgs');
160
            $result = $ecmdir->changeNbOfFiles('-');
161
        } else {
162
            setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile', 'alpha')), null, 'errors');
163
        }
164
165
        clearstatcache();
166
    }
167
    $action = 'file_manager';
168
}
169
170
// Add directory
171
if ($action == 'add' && $permissiontocreatedir) {
172
    $ecmdir->ref = 'NOTUSEDYET';
173
    $ecmdir->label = GETPOST("label");
0 ignored issues
show
Documentation Bug introduced by
It seems like GETPOST('label') can also be of type array or array or array. However, the property $label is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
174
    $ecmdir->description = GETPOST("desc");
0 ignored issues
show
Documentation Bug introduced by
It seems like GETPOST('desc') can also be of type array or array or array. However, the property $description is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
175
176
    $id = $ecmdir->create($user);
177
    if ($id > 0) {
178
        header("Location: " . $_SERVER["PHP_SELF"]);
179
        exit;
180
    } else {
181
        setEventMessages('Error ' . $langs->trans($ecmdir->error), null, 'errors');
182
        $action = "create";
183
    }
184
185
    clearstatcache();
186
}
187
188
// Remove directory
189
if ($action == 'confirm_deletesection' && GETPOST('confirm', 'alpha') == 'yes' && $permissiontodeletedir) {
190
    $result = $ecmdir->delete($user);
191
    setEventMessages($langs->trans("ECMSectionWasRemoved", $ecmdir->label), null, 'mesgs');
192
193
    clearstatcache();
194
}
195
196
// Refresh directory view
197
// This refresh list of dirs, not list of files (for performance reason). List of files is refresh only if dir was not synchronized.
198
// To refresh content of dir with cache, just open the dir in edit mode.
199
if ($action == 'refreshmanual' && $permissiontoread) {
200
    $ecmdirtmp = new EcmDirectory($db);
201
202
    // This part of code is same than into file ecm/ajax/ecmdatabase.php TODO Remove duplicate
203
    clearstatcache();
204
205
    $diroutputslash = str_replace('\\', '/', $conf->ecm->dir_output);
206
    $diroutputslash .= '/';
207
208
    // Scan directory tree on disk
209
    $disktree = dol_dir_list($conf->ecm->dir_output, 'directories', 1, '', '^temp$', '', '', 0);
210
211
    // Scan directory tree in database
212
    $sqltree = $ecmdirstatic->get_full_arbo(0);
213
214
    $adirwascreated = 0;
215
216
    // Now we compare both trees to complete missing trees into database
217
    //var_dump($disktree);
218
    //var_dump($sqltree);
219
    foreach ($disktree as $dirdesc) {    // Loop on tree onto disk
220
        $dirisindatabase = 0;
221
        foreach ($sqltree as $dirsqldesc) {
222
            if ($conf->ecm->dir_output . '/' . $dirsqldesc['fullrelativename'] == $dirdesc['fullname']) {
223
                $dirisindatabase = 1;
224
                break;
225
            }
226
        }
227
228
        if (!$dirisindatabase) {
229
            $txt = "Directory found on disk " . $dirdesc['fullname'] . ", not found into database so we add it";
230
            dol_syslog($txt);
231
            //print $txt."<br>\n";
232
233
            // We must first find the fk_parent of directory to create $dirdesc['fullname']
234
            $fk_parent = -1;
235
            $relativepathmissing = str_replace($diroutputslash, '', $dirdesc['fullname']);
236
            $relativepathtosearchparent = $relativepathmissing;
237
            //dol_syslog("Try to find parent id for directory ".$relativepathtosearchparent);
238
            if (preg_match('/\//', $relativepathtosearchparent)) {
239
                //while (preg_match('/\//',$relativepathtosearchparent))
240
                $relativepathtosearchparent = preg_replace('/\/[^\/]*$/', '', $relativepathtosearchparent);
241
                $txt = "Is relative parent path " . $relativepathtosearchparent . " for " . $relativepathmissing . " found in sql tree ?";
242
                dol_syslog($txt);
243
                //print $txt." -> ";
244
                $parentdirisindatabase = 0;
245
                foreach ($sqltree as $dirsqldesc) {
246
                    if ($dirsqldesc['fullrelativename'] == $relativepathtosearchparent) {
247
                        $parentdirisindatabase = $dirsqldesc['id'];
248
                        break;
249
                    }
250
                }
251
                if ($parentdirisindatabase > 0) {
252
                    dol_syslog("Yes with id " . $parentdirisindatabase);
253
                    //print "Yes with id ".$parentdirisindatabase."<br>\n";
254
                    $fk_parent = $parentdirisindatabase;
255
                    //break;  // We found parent, we can stop the while loop
256
                } else {
257
                    dol_syslog("No");
258
                    //print "No<br>\n";
259
                }
260
            } else {
261
                dol_syslog("Parent is root");
262
                $fk_parent = 0; // Parent is root
263
            }
264
265
            if ($fk_parent >= 0) {
266
                $ecmdirtmp->ref = 'NOTUSEDYET';
267
                $ecmdirtmp->label = dol_basename($dirdesc['fullname']);
268
                $ecmdirtmp->description = '';
269
                $ecmdirtmp->fk_parent = $fk_parent;
270
271
                $txt = "We create directory " . $ecmdirtmp->label . " with parent " . $fk_parent;
272
                dol_syslog($txt);
273
                //print $ecmdirtmp->cachenbofdoc."<br>\n";exit;
274
                $id = $ecmdirtmp->create($user);
275
                if ($id > 0) {
276
                    $newdirsql = array('id' => $id,
277
                        'id_mere' => $ecmdirtmp->fk_parent,
278
                        'label' => $ecmdirtmp->label,
279
                        'description' => $ecmdirtmp->description,
280
                        'fullrelativename' => $relativepathmissing);
281
                    $sqltree[] = $newdirsql; // We complete fulltree for following loops
282
                    //var_dump($sqltree);
283
                    $adirwascreated = 1;
284
                } else {
285
                    dol_syslog("Failed to create directory " . $ecmdirtmp->label, LOG_ERR);
286
                }
287
            } else {
288
                $txt = "Parent of " . $dirdesc['fullname'] . " not found";
289
                dol_syslog($txt);
290
                //print $txt."<br>\n";
291
            }
292
        }
293
    }
294
295
    // Loop now on each sql tree to check if dir exists
296
    foreach ($sqltree as $dirdesc) {    // Loop on each sqltree to check dir is on disk
297
        $dirtotest = $conf->ecm->dir_output . '/' . $dirdesc['fullrelativename'];
298
        if (!dol_is_dir($dirtotest)) {
299
            $ecmdirtmp->id = $dirdesc['id'];
300
            $ecmdirtmp->delete($user, 'databaseonly');
301
            //exit;
302
        }
303
    }
304
305
    $sql = "UPDATE " . MAIN_DB_PREFIX . "ecm_directories set cachenbofdoc = -1 WHERE cachenbofdoc < 0"; // If pb into cache counting, we set to value -1 = "unknown"
306
    dol_syslog("sql = " . $sql);
307
    $db->query($sql);
308
309
    // If a directory was added, the fulltree array is not correctly completed and sorted, so we clean
310
    // it to be sure that fulltree array is not used without reloading it.
311
    if ($adirwascreated) {
312
        $sqltree = null;
313
    }
314
}
315
316
317
/*
318
 *	View
319
 */
320
321
// Define height of file area (depends on $_SESSION["dol_screenheight"])
322
//print $_SESSION["dol_screenheight"];
323
$maxheightwin = (isset($_SESSION["dol_screenheight"]) && $_SESSION["dol_screenheight"] > 466) ? ($_SESSION["dol_screenheight"] - 136) : 660; // Also into index_auto.php file
324
325
$moreheadcss = '';
326
$moreheadjs = '';
327
328
//$morejs=array();
329
$morejs = array('includes/jquery/plugins/blockUI/jquery.blockUI.js', 'core/js/blockUI.js'); // Used by ecm/tpl/enabledfiletreeajax.tpl.pgp
330
if (!getDolGlobalString('MAIN_ECM_DISABLE_JS')) {
331
    $morejs[] = "includes/jquery/plugins/jqueryFileTree/jqueryFileTree.js";
332
}
333
334
$moreheadjs .= '<script type="text/javascript">' . "\n";
335
$moreheadjs .= 'var indicatorBlockUI = \'' . constant('DOL_URL_ROOT') . "/theme/" . $conf->theme . "/img/working.gif" . '\';' . "\n";
336
$moreheadjs .= '</script>' . "\n";
337
338
ViewMain::llxHeader($moreheadcss . $moreheadjs, $langs->trans("ECMArea"), '', '', '', '', $morejs, '', 0, 0);
339
340
$head = ecm_prepare_dasboard_head(null);
341
print dol_get_fiche_head($head, 'index', '', -1, '');
342
343
344
// Add filemanager component
345
$module = 'ecm';
346
if (empty($url)) {
347
    $url = constant('BASE_URL') . '/ecm/index.php'; // Must be an url without param
348
}
349
include DOL_DOCUMENT_ROOT . '/core/tpl/filemanager.tpl.php';
350
351
// End of page
352
print dol_get_fiche_end();
353
354
ViewMain::llxFooter();
355
356
$db->close();
357