9 namespace Fossology\Lib\Dao;
19 const FOLDER_KEY =
"folder";
20 const DEPTH_KEY =
"depth";
21 const REUSE_KEY =
'reuse';
24 const MODE_FOLDER = 1;
25 const MODE_UPLOAD = 2;
40 $this->logger =
new Logger(self::class);
41 $this->uploadDao = $uploadDao;
42 $this->userDao = $userDao;
50 $folderInfo = $this->
dbManager->getSingleRow(
"SELECT count(*) cnt FROM folder WHERE folder_pk=$1", array(self::TOP_LEVEL), __METHOD__);
51 $hasFolder = $folderInfo[
'cnt'] > 0;
55 public function insertFolder($folderName, $folderDescription, $parentFolderId = self::TOP_LEVEL)
58 $statementName = __METHOD__;
61 "INSERT INTO folder (folder_name, folder_desc) VALUES ($1, $2) returning folder_pk");
62 $res = $this->
dbManager->execute($statementName, array($folderName, $folderDescription));
63 $folderRow = $this->
dbManager->fetchArray($res);
64 $folderId = $folderRow[
"folder_pk"];
66 $this->insertFolderContents($parentFolderId, self::MODE_FOLDER, $folderId);
71 public function getFolderId($folderName, $parentFolderId = self::TOP_LEVEL)
73 $statementName = __METHOD__;
75 "SELECT folder_pk FROM folder, foldercontents fc"
76 .
" WHERE LOWER(folder_name)=LOWER($1) AND fc.parent_fk=$2 AND fc.foldercontents_mode=$3 AND folder_pk=child_id");
77 $res = $this->
dbManager->execute($statementName, array( $folderName, $parentFolderId, self::MODE_FOLDER));
80 $rootFolder = !empty($rows) ? intval($rows[0][
'folder_pk']) : null;
86 public function insertFolderContents($parentId, $foldercontentsMode, $childId)
88 $statementName = __METHOD__;
90 "INSERT INTO foldercontents (parent_fk, foldercontents_mode, child_id) VALUES ($1, $2, $3)");
91 $res = $this->
dbManager->execute($statementName, array($parentId, $foldercontentsMode, $childId));
95 protected function fixFolderSequence()
97 $statementName = __METHOD__;
99 "SELECT setval('folder_folder_pk_seq', (SELECT max(folder_pk) + 1 FROM folder LIMIT 1))");
100 $res = $this->
dbManager->execute($statementName);
110 $statementName = __METHOD__;
111 $this->
dbManager->prepare($statementName,
112 "SELECT f.* FROM folder f INNER JOIN users u ON f.folder_pk = u.root_folder_fk WHERE u.user_pk = $1");
113 $res = $this->
dbManager->execute($statementName, array($userId));
114 $row = $this->
dbManager->fetchArray($res);
115 $rootFolder = $row ?
new Folder(intval($row[
'folder_pk']), $row[
'folder_name'], $row[
'folder_desc'], intval($row[
'folder_perm'])) :
null;
126 $statementName = __METHOD__;
127 $this->
dbManager->prepare($statementName,
128 "SELECT f.* FROM folder f INNER JOIN users u ON f.folder_pk = u.default_folder_fk WHERE u.user_pk = $1");
129 $res = $this->
dbManager->execute($statementName, array($userId));
130 $row = $this->
dbManager->fetchArray($res);
131 $rootFolder = $row ?
new Folder(intval($row[
'folder_pk']), $row[
'folder_name'], $row[
'folder_desc'], intval($row[
'folder_perm'])) :
null;
136 public function getFolderTreeCte($parentId =
null)
138 $parentCondition = $parentId ?
'folder_pk=$1' :
'folder_pk=' . self::TOP_LEVEL;
140 return "WITH RECURSIVE folder_tree(folder_pk, parent_fk, folder_name, folder_desc, folder_perm, id_path, name_path, depth, cycle_detected) AS (
142 f.folder_pk, fc.parent_fk, f.folder_name, f.folder_desc, f.folder_perm,
143 ARRAY [f.folder_pk] AS id_path,
144 ARRAY [f.folder_name] AS name_path,
146 FALSE AS cycle_detected
147 FROM folder f LEFT JOIN foldercontents fc ON fc.foldercontents_mode=" . self::MODE_FOLDER .
" AND f.folder_pk=fc.child_id
148 WHERE $parentCondition
151 f.folder_pk, fc.parent_fk, f.folder_name, f.folder_desc, f.folder_perm,
152 id_path || f.folder_pk,
153 name_path || f.folder_name,
154 array_length(id_path, 1),
155 f.folder_pk = ANY (id_path)
156 FROM folder f, foldercontents fc, folder_tree ft
157 WHERE f.folder_pk=fc.child_id AND foldercontents_mode=" . self::MODE_FOLDER .
" AND fc.parent_fk = ft.folder_pk AND NOT cycle_detected
161 public function getFolderStructure($parentId =
null)
163 $statementName = __METHOD__ . ($parentId ?
'.relativeToParent' :
'');
164 $parameters = $parentId ? array($parentId) : array();
165 $this->
dbManager->prepare($statementName, $this->getFolderTreeCte($parentId)
166 .
" SELECT folder_pk, parent_fk, folder_name, folder_desc, folder_perm, depth FROM folder_tree ORDER BY name_path");
167 $res = $this->
dbManager->execute($statementName, $parameters);
172 while ($row = $this->
dbManager->fetchArray($res)) {
176 self::FOLDER_KEY =>
new Folder(
177 intval($row[
'folder_pk']), $row[
'folder_name'], $row[
'folder_desc'], intval($row[
'folder_perm'])),
178 self::DEPTH_KEY => $row[
'depth'],
179 self::REUSE_KEY => $countUploads
193 $trustGroupIds = array_keys($userGroupMap);
194 $statementName = __METHOD__;
195 $trustedGroups =
'{' . implode(
',', $trustGroupIds) .
'}';
196 $parameters = array($parentId, $trustedGroups);
198 $this->
dbManager->prepare($statementName,
"
199 SELECT group_fk group_id,count(*) FROM foldercontents fc
200 INNER JOIN upload u ON u.upload_pk = fc.child_id
201 INNER JOIN upload_clearing uc ON u.upload_pk=uc.upload_fk AND uc.group_fk=ANY($2)
202 WHERE fc.parent_fk = $1 AND fc.foldercontents_mode = " . self::MODE_UPLOAD .
" AND (u.upload_mode = 100 OR u.upload_mode = 104)
205 $res = $this->
dbManager->execute($statementName, $parameters);
207 while ($row = $this->
dbManager->fetchArray($res)) {
208 $row[
'group_name'] = $userGroupMap[$row[
'group_id']];
209 $results[$row[
'group_name']] = $row;
215 public function getAllFolderIds()
217 $statementName = __METHOD__;
218 $this->
dbManager->prepare($statementName,
"SELECT DISTINCT folder_pk FROM folder");
219 $res = $this->
dbManager->execute($statementName);
220 $results = $this->
dbManager->fetchAll($res);
224 for ($i=0; $i <
sizeof($results); $i++) {
225 $allIds[] = intval($results[$i][
'folder_pk']);
231 public function getFolderChildUploads($parentId, $trustGroupId)
233 $statementName = __METHOD__;
234 $parameters = array($parentId, $trustGroupId);
236 $this->
dbManager->prepare($statementName, $sql =
"
237 SELECT u.*,uc.*,fc.foldercontents_pk FROM foldercontents fc
238 INNER JOIN upload u ON u.upload_pk = fc.child_id
239 INNER JOIN upload_clearing uc ON u.upload_pk=uc.upload_fk AND uc.group_fk=$2
240 WHERE fc.parent_fk = $1 AND fc.foldercontents_mode = " . self::MODE_UPLOAD .
" AND (u.upload_mode = 100 OR u.upload_mode = 104);");
241 $res = $this->
dbManager->execute($statementName, $parameters);
242 $results = $this->
dbManager->fetchAll($res);
254 if (empty($trustGroupId)) {
258 foreach ($this->getFolderChildUploads($parentId, $trustGroupId) as $row) {
264 public function createFolder($folderName, $folderDescription, $parentId)
266 $folderId = $this->
dbManager->insertTableRow(
"folder", array(
"folder_name" => $folderName,
"user_fk" =>
Auth::getUserId(),
"folder_desc" => $folderDescription),
null,
'folder_pk');
267 $this->insertFolderContents($parentId, self::MODE_FOLDER, $folderId);
272 public function ensureTopLevelFolder()
275 $this->
dbManager->insertTableRow(
"folder", array(
"folder_pk" => self::TOP_LEVEL,
"folder_name" =>
"Software Repository",
"folder_desc" =>
"Top Folder"));
276 $this->insertFolderContents(1, 0, 0);
277 $this->fixFolderSequence();
281 public function isWithoutReusableFolders($folderStructure)
283 foreach ($folderStructure as $folder) {
284 $posibilities = array_reduce($folder[self::REUSE_KEY],
function($sum,$groupInfo)
286 return $sum+$groupInfo[
'count'];
288 if ($posibilities > 0) {
295 protected function isInFolderTree($parentId, $folderId)
298 $this->getFolderTreeCte($parentId) .
" SELECT depth FROM folder_tree WHERE folder_pk=$2 LIMIT 1",
299 array($parentId, $folderId),
301 return !empty($cycle);
304 public function getContent($folderContentId)
306 $content = $this->
dbManager->getSingleRow(
'SELECT * FROM foldercontents WHERE foldercontents_pk=$1',
307 array($folderContentId),
308 __METHOD__ .
'.getContent');
309 if (empty($content)) {
310 throw new \Exception(
'invalid FolderContentId');
315 protected function isContentMovable($content, $newParentId)
317 if ($content[
'parent_fk'] == $newParentId) {
320 $newParent = $this->
dbManager->getSingleRow(
'SELECT * FROM folder WHERE folder_pk=$1',
322 __METHOD__ .
'.getParent');
323 if (empty($newParent)) {
324 throw new \Exception(
'invalid parent folder');
327 if ($content[
'foldercontents_mode'] == self::MODE_FOLDER) {
328 if ($this->isInFolderTree($content[
'child_id'], $newParentId)) {
329 throw new \Exception(
"action would cause a cycle");
331 } elseif ($content[
'foldercontents_mode'] == self::MODE_UPLOAD) {
332 $uploadId = $content[
'child_id'];
334 throw new \Exception(
'permission to upload denied');
341 public function moveContent($folderContentId, $newParentId)
343 $content = $this->getContent($folderContentId);
344 if (!$this->isContentMovable($content, $newParentId)) {
348 $this->
dbManager->getSingleRow(
'UPDATE foldercontents SET parent_fk=$2 WHERE foldercontents_pk=$1',
349 array($folderContentId, $newParentId), __METHOD__ .
'.updateFolderParent');
352 public function copyContent($folderContentId, $newParentId)
354 $content = $this->getContent($folderContentId);
355 if (!$this->isContentMovable($content, $newParentId)) {
359 $this->insertFolderContents($newParentId, $content[
'foldercontents_mode'], $content[
'child_id']);
362 public function getRemovableContents($folderId)
364 $sqlChildren =
"SELECT child_id,foldercontents_mode
365 FROM foldercontents GROUP BY child_id,foldercontents_mode
366 HAVING count(*)>1 AND bool_or(parent_fk=$1)";
367 $sql =
"SELECT fc.* FROM foldercontents fc,($sqlChildren) chi "
368 .
"WHERE fc.child_id=chi.child_id AND fc.foldercontents_mode=chi.foldercontents_mode and fc.parent_fk=$1";
369 $this->
dbManager->prepare($stmt = __METHOD__, $sql);
370 $res = $this->
dbManager->execute($stmt, array($folderId));
372 while ($row = $this->
dbManager->fetchArray($res)) {
373 $contents[] = $row[
'foldercontents_pk'];
379 public function isRemovableContent($childId, $mode)
381 $sql =
"SELECT count(parent_fk) FROM foldercontents WHERE child_id=$1 AND foldercontents_mode=$2";
382 $parentCounter = $this->
dbManager->getSingleRow($sql, array($childId, $mode), __METHOD__);
383 return $parentCounter[
'count'] > 1;
386 public function removeContent($folderContentId)
388 $content = $this->getContent($folderContentId);
389 if ($this->isRemovableContent($content[
'child_id'], $content[
'foldercontents_mode'])) {
390 $sql =
"DELETE FROM foldercontents WHERE foldercontents_pk=$1";
391 $this->
dbManager->getSingleRow($sql, array($folderContentId), __METHOD__);
397 public function removeContentById($uploadpk, $folderId)
399 $sql =
"DELETE FROM foldercontents WHERE child_id=$1 AND parent_fk=$2 AND foldercontents_mode=$3";
400 $this->
dbManager->getSingleRow($sql,array($uploadpk, $folderId,2),__METHOD__);
403 public function getFolderChildFolders($folderId)
406 $stmtFolder = __METHOD__;
407 $sqlFolder =
"SELECT foldercontents_pk,foldercontents_mode, folder_name FROM foldercontents JOIN folder"
408 .
" ON foldercontents.child_id=folder.folder_pk WHERE foldercontents.parent_fk=$1"
409 .
" AND foldercontents_mode=" . self::MODE_FOLDER;
410 $this->
dbManager->prepare($stmtFolder, $sqlFolder);
411 $res = $this->
dbManager->execute($stmtFolder, array($folderId));
412 while ($row = $this->
dbManager->fetchArray($res)) {
413 $results[$row[
'foldercontents_pk']] = $row;
425 $folderRow = $this->
dbManager->getSingleRow(
'SELECT * FROM folder WHERE folder_pk = $1', array($folderId));
429 return new Folder($folderRow[
'folder_pk'], $folderRow[
'folder_name'], $folderRow[
'folder_desc'], $folderRow[
'folder_perm']);
439 $allUserFolders = array();
440 if ($userId ==
null) {
445 if (in_array($folderId, array_keys($allUserFolders))) {
459 $folderContentsRow = $this->
dbManager->getSingleRow(
460 'SELECT foldercontents_pk FROM foldercontents '.
461 'WHERE child_id = $1 AND foldercontents_mode = $2', [$childId, $mode]);
462 if (!$folderContentsRow) {
465 return intval($folderContentsRow[
'foldercontents_pk']);
475 $sql =
"SELECT parent_fk FROM foldercontents " .
476 "WHERE foldercontents_mode = " . self::MODE_FOLDER .
477 " AND child_id = $1;";
478 $statement = __METHOD__ .
".getParentId";
479 $row = $this->
dbManager->getSingleRow($sql, [$folderPk], $statement);
480 return (empty($row)) ? null : $row[
'parent_fk'];
Contains the constants and helpers for authentication of user.
static getUserId()
Get the current user's id.
static getGroupId()
Get the current user's group id.
isFolderAccessible($folderId, $userId=null)
getFolderUploads($parentId, $trustGroupId=null)
getFolderParentId($folderPk)
getFolderContentsId($childId, $mode)
countFolderUploads($parentId, $userGroupMap)
getDefaultFolder($userId)
static createFromTable($row)
GetFolderArray($RootFolder, &$FolderArray)
Get an array of all the folders from a $RootFolder on down.
fo_dbManager * dbManager
fo_dbManager object