managecollections.class.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. <?php
  2. /**
  3. * Bibliotheca
  4. *
  5. * Copyright 2018-2023 Johannes Keßler
  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 http://www.gnu.org/licenses/gpl-3.0.
  19. */
  20. /**
  21. * Class ManageCollections to manage collections
  22. */
  23. class ManageCollections {
  24. /**
  25. * The database object
  26. *
  27. * @var mysqli
  28. */
  29. private mysqli $_DB;
  30. /**
  31. * The user object to query with
  32. *
  33. * @var Doomguy
  34. */
  35. private Doomguy $_User;
  36. /**
  37. * ManageCollections constructor.
  38. *
  39. * @param mysqli $databaseConnectionObject
  40. * @param Doomguy $userObj
  41. */
  42. public function __construct(mysqli $databaseConnectionObject, Doomguy $userObj) {
  43. $this->_DB = $databaseConnectionObject;
  44. $this->_User = $userObj;
  45. }
  46. /**
  47. * Get all available collections for display based on current user
  48. *
  49. * @return array
  50. */
  51. public function getCollections(): array{
  52. $ret = array();
  53. $queryStr = "SELECT `c`.`id`, `c`.`name`, `c`.`description`, `c`.`created`,
  54. `c`.`owner`, `c`.`group`, `c`.`rights`,
  55. `u`.`name` AS username, `g`.`name` AS groupname
  56. FROM `".DB_PREFIX."_collection` AS c
  57. LEFT JOIN `".DB_PREFIX."_user` AS u ON `c`.`owner` = `u`.`id`
  58. LEFT JOIN `".DB_PREFIX."_group` AS g ON `c`.`group` = `g`.`id`
  59. WHERE ".$this->_User->getSQLRightsString("write", "c")."
  60. ORDER BY `c`.`name`";
  61. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
  62. try {
  63. $query = $this->_DB->query($queryStr);
  64. if ($query !== false && $query->num_rows > 0) {
  65. while (($result = $query->fetch_assoc()) != false) {
  66. $ret[$result['id']] = $result;
  67. }
  68. }
  69. }
  70. catch (Exception $e) {
  71. Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
  72. }
  73. return $ret;
  74. }
  75. /**
  76. * Retrieve the groups for selection based on user rights
  77. *
  78. * @return array
  79. */
  80. public function getGroupsForSelection(): array {
  81. $ret = array();
  82. $queryStr = "SELECT `id`, `name`, `description`
  83. FROM `".DB_PREFIX."_group`
  84. WHERE ".$this->_User->getSQLRightsString()."
  85. ORDER BY `name`";
  86. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
  87. try {
  88. $query = $this->_DB->query($queryStr);
  89. if($query !== false && $query->num_rows > 0) {
  90. while(($result = $query->fetch_assoc()) != false) {
  91. $ret[$result['id']] = $result;
  92. }
  93. }
  94. }
  95. catch (Exception $e) {
  96. Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
  97. }
  98. return $ret;
  99. }
  100. /**
  101. * Fetch all available users for selection based on current user rights
  102. *
  103. * @return array
  104. */
  105. public function getUsersForSelection(): array {
  106. $ret = array();
  107. $queryStr = "SELECT `id`, `name`, `login`
  108. FROM `".DB_PREFIX."_user`
  109. WHERE ".$this->_User->getSQLRightsString()."";
  110. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
  111. try {
  112. $query = $this->_DB->query($queryStr);
  113. if($query !== false && $query->num_rows > 0) {
  114. while(($result = $query->fetch_assoc()) != false) {
  115. $ret[$result['id']] = $result;
  116. }
  117. }
  118. }
  119. catch (Exception $e) {
  120. Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
  121. }
  122. return $ret;
  123. }
  124. /**
  125. * Fetch all available tools based on current user rights
  126. *
  127. * @return array
  128. */
  129. public function getToolsForSelection(): array {
  130. $ret = array();
  131. $queryStr = "SELECT `id`, `name`, `description`
  132. FROM `".DB_PREFIX."_tool`
  133. WHERE ".$this->_User->getSQLRightsString()."";
  134. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
  135. try {
  136. $query = $this->_DB->query($queryStr);
  137. if($query !== false && $query->num_rows > 0) {
  138. while(($result = $query->fetch_assoc()) != false) {
  139. $ret[$result['id']] = $result;
  140. }
  141. }
  142. }
  143. catch (Exception $e) {
  144. Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
  145. }
  146. return $ret;
  147. }
  148. /**
  149. * Create new collection entry in collection table. Provide valid data
  150. * only $name will be checked again
  151. *
  152. * @param array $data
  153. * @return bool
  154. */
  155. public function createCollection(array $data): bool {
  156. $ret = false;
  157. if(!empty($data['name']) === true
  158. && $this->_validNewCollectionName($data['name']) === true
  159. ) {
  160. try {
  161. $this->_DB->begin_transaction(MYSQLI_TRANS_START_READ_WRITE);
  162. $queryStr = "INSERT INTO `".DB_PREFIX."_collection`
  163. SET `name` = '".$this->_DB->real_escape_string($data['name'])."',
  164. `description` = '".$this->_DB->real_escape_string($data['description'])."',
  165. `owner` = '".$this->_DB->real_escape_string($data['owner'])."',
  166. `group` = '".$this->_DB->real_escape_string($data['group'])."',
  167. `rights` = '".$this->_DB->real_escape_string($data['rights'])."',
  168. `defaultSearchField` = '".$this->_DB->real_escape_string($data['defaultSearchField'])."',
  169. `defaultSortField` = '".$this->_DB->real_escape_string($data['defaultSortField'])."',
  170. `defaultSortOrder` = '".$this->_DB->real_escape_string($data['defaultSortOrder'])."',
  171. `advancedSearchTableFields` = '".$this->_DB->real_escape_string($data['advancedSearchTableFields'])."'";
  172. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
  173. $this->_DB->query($queryStr);
  174. $newId = $this->_DB->insert_id;
  175. $this->_updateToolRelation($newId,$data['tool']);
  176. $this->_DB->commit();
  177. // mysql implicit commit with create table
  178. // rollback does not really solve if there is an error
  179. $queryEntry2lookup = "CREATE TABLE `".DB_PREFIX."_collection_entry2lookup_".$newId."` (
  180. `fk_field` int NOT NULL,
  181. `fk_entry` int NOT NULL,
  182. `value` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  183. KEY `fk_entry` (`fk_entry`),
  184. KEY `fk_field` (`fk_field`),
  185. FULLTEXT KEY `value` (`value`)
  186. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
  187. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryEntry2lookup));
  188. $this->_DB->query($queryEntry2lookup);
  189. $queryCollectionFields = "CREATE TABLE `".DB_PREFIX."_collection_fields_".$newId."` (
  190. `fk_field_id` int NOT NULL,
  191. `sort` int NOT NULL,
  192. UNIQUE KEY `fk_field_id` (`fk_field_id`),
  193. KEY `sort` (`sort`)
  194. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
  195. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryCollectionFields));
  196. $this->_DB->query($queryCollectionFields);
  197. $queryCollectionEntry = "CREATE TABLE `".DB_PREFIX."_collection_entry_".$newId."` (
  198. `id` int NOT NULL AUTO_INCREMENT,
  199. `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  200. `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  201. `modificationuser` int NOT NULL,
  202. `owner` int NOT NULL,
  203. `group` int NOT NULL,
  204. `rights` char(9) COLLATE utf8mb4_bin NOT NULL,
  205. PRIMARY KEY (`id`)
  206. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
  207. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryCollectionEntry));
  208. $this->_DB->query($queryCollectionEntry);
  209. $ret = true;
  210. }
  211. catch (Exception $e) {
  212. Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
  213. $this->_DB->rollback();
  214. }
  215. }
  216. return $ret;
  217. }
  218. /**
  219. * Load the information from collection table for given $id
  220. *
  221. * @param string $id Number
  222. * @return array
  223. */
  224. public function getEditData(string $id): array {
  225. $ret = array();
  226. if (Summoner::validate($id, 'digit')) {
  227. $queryStr = "SELECT `c`.`id`, `c`.`name`, `c`.`description`, `c`.`created`,
  228. `c`.`owner`, `c`.`group`, `c`.`rights`, `c`.`defaultSearchField`,
  229. `c`.`defaultSortField`, `c`.`advancedSearchTableFields`,
  230. `c`.`defaultSortOrder`,
  231. `u`.`name` AS username, `g`.`name` AS groupname
  232. FROM `".DB_PREFIX."_collection` AS c
  233. LEFT JOIN `".DB_PREFIX."_user` AS u ON `c`.`owner` = `u`.`id`
  234. LEFT JOIN `".DB_PREFIX."_group` AS g ON `c`.`group` = `g`.`id`
  235. WHERE ".$this->_User->getSQLRightsString("write", "c")."
  236. AND `c`.`id` = '".$this->_DB->real_escape_string($id)."'";
  237. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
  238. try {
  239. $query = $this->_DB->query($queryStr);
  240. if($query !== false && $query->num_rows > 0) {
  241. $ret = $query->fetch_assoc();
  242. $ret['rights'] = Summoner::prepareRightsArray($ret['rights']);
  243. $ret['tool'] = $this->getAvailableTools($id);
  244. $ret['advancedSearchTableFields'] = $this->_loadAdvancedSearchTableFields($ret['advancedSearchTableFields']);
  245. }
  246. }
  247. catch (Exception $e) {
  248. Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
  249. }
  250. }
  251. return $ret;
  252. }
  253. /**
  254. * Update collection with given data identified by given id
  255. * See method for the fields
  256. *
  257. * @param array $data
  258. * @return bool
  259. */
  260. public function updateCollection(array $data): bool {
  261. $ret = false;
  262. if(DEBUG) Summoner::sysLog("[DEBUG] ".__METHOD__." data: ".Summoner::cleanForLog($data));
  263. if(!empty($data['name']) === true
  264. && $this->_validUpdateCollectionName($data['name'], $data['id']) === true
  265. && Summoner::validate($data['id'], 'digit')
  266. ) {
  267. $queryStr = "UPDATE `".DB_PREFIX."_collection`
  268. SET `name` = '".$this->_DB->real_escape_string($data['name'])."',
  269. `description` = '".$this->_DB->real_escape_string($data['description'])."',
  270. `owner` = '".$this->_DB->real_escape_string($data['owner'])."',
  271. `group` = '".$this->_DB->real_escape_string($data['group'])."',
  272. `rights` = '".$this->_DB->real_escape_string($data['rights'])."',
  273. `defaultSearchField` = '".$this->_DB->real_escape_string($data['defaultSearchField'])."',
  274. `defaultSortField` = '".$this->_DB->real_escape_string($data['defaultSortField'])."',
  275. `defaultSortOrder` = '".$this->_DB->real_escape_string($data['defaultSortOrder'])."',
  276. `advancedSearchTableFields` = '".$this->_DB->real_escape_string($data['advancedSearchTableFields'])."'
  277. WHERE `id` = '".$this->_DB->real_escape_string($data['id'])."'";
  278. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
  279. try {
  280. $this->_DB->query($queryStr);
  281. $this->_updateToolRelation($data['id'],$data['tool']);
  282. if($data['doRightsForEntries'] === true) {
  283. $this->_updateEntryRights($data['id'], $data['owner'], $data['group'], $data['rights']);
  284. }
  285. $ret = true;
  286. }
  287. catch (Exception $e) {
  288. Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
  289. }
  290. // update the search field if it is a field from the collection entry table
  291. // and add the index. The lookup table has already a fulltext index on value
  292. $queryCheck = "SHOW COLUMNS FROM `".DB_PREFIX."_collection_entry_".$data['id']."`
  293. LIKE '".$this->_DB->real_escape_string($data['defaultSearchField'])."'";
  294. $queryStr = "CREATE FULLTEXT INDEX ".$this->_DB->real_escape_string($data['defaultSearchField'])."
  295. ON `".DB_PREFIX."_collection_entry_".$data['id']."`
  296. (`".$this->_DB->real_escape_string($data['defaultSearchField'])."`)";
  297. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryCheck));
  298. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
  299. try {
  300. $query = $this->_DB->query($queryCheck);
  301. if($query !== false && $query->num_rows > 0) {
  302. $this->_DB->query($queryStr);
  303. // altering or adding an index while data exists
  304. // ignores the collation (?)
  305. // optimize does a recreation and the column collation
  306. // is considered
  307. $this->_DB->query("OPTIMIZE TABLE `".DB_PREFIX."_collection_entry_".$data['id']."`");
  308. }
  309. } catch (Exception $e) {
  310. if($e->getCode() == "1061") {
  311. // duplicate key message if the index is already there.
  312. Summoner::sysLog("[NOTICE] ".__METHOD__." mysql query: ".$e->getMessage());
  313. }
  314. else {
  315. Summoner::sysLog("[ERROR] ".__METHOD__." mysql query: ".$e->getMessage());
  316. }
  317. }
  318. }
  319. return $ret;
  320. }
  321. /**
  322. * Delete collection identified by given id
  323. * This removes everything and drops tables!
  324. *
  325. * @param string $id Number
  326. * @return bool
  327. */
  328. public function deleteCollection(string $id): bool {
  329. $ret = false;
  330. if(!empty($id) && Summoner::validate($id, 'digit')) {
  331. $queryStr = "DELETE FROM `".DB_PREFIX."_collection`
  332. WHERE `id` = '".$this->_DB->real_escape_string($id)."'";
  333. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
  334. $queryStrTool = "DELETE FROM `".DB_PREFIX."_tool2collection`
  335. WHERE `fk_collection_id` = '".$this->_DB->real_escape_string($id)."'";
  336. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStrTool));
  337. $queryStre2l = "DROP TABLE `".DB_PREFIX."_collection_entry2lookup_".$this->_DB->real_escape_string($id)."`";
  338. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStre2l));
  339. $queryStrEntry = "DROP TABLE `".DB_PREFIX."_collection_entry_".$this->_DB->real_escape_string($id)."`";
  340. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStrEntry));
  341. $queryStrFields = "DROP TABLE `".DB_PREFIX."_collection_fields_".$this->_DB->real_escape_string($id)."`";
  342. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStrFields));
  343. // mysql implicit commit with drop command
  344. // transaction does not really help here.
  345. // https://dev.mysql.com/doc/refman/8.0/en/implicit-commit.html
  346. try {
  347. $this->_DB->begin_transaction(MYSQLI_TRANS_START_READ_WRITE);
  348. $this->_DB->query($queryStr);
  349. $this->_DB->query($queryStrTool);
  350. $this->_DB->commit();
  351. $this->_DB->query($queryStre2l);
  352. $this->_DB->query($queryStrEntry);
  353. $this->_DB->query($queryStrFields);
  354. Summoner::recursive_remove_directory(PATH_STORAGE.'/'.$id);
  355. $ret = true;
  356. }
  357. catch (Exception $e) {
  358. $this->_DB->rollback();
  359. Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
  360. }
  361. }
  362. return $ret;
  363. }
  364. /**
  365. * Load the tools configured to the given collection
  366. *
  367. * @param string $id Number
  368. * @return array
  369. */
  370. public function getAvailableTools(string $id): array {
  371. $ret = array();
  372. $queryStr = "SELECT `t`.`id`, `t`.`name`, `t`.`description`, `t`.`action`, `t`.`target`
  373. FROM `".DB_PREFIX."_tool2collection` AS t2c
  374. LEFT JOIN `".DB_PREFIX."_tool` AS t ON t.id = t2c.fk_tool_id
  375. WHERE t2c.fk_collection_id = '".$this->_DB->real_escape_string($id)."'";
  376. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
  377. try {
  378. $query = $this->_DB->query($queryStr);
  379. if($query !== false && $query->num_rows > 0) {
  380. while(($result = $query->fetch_assoc()) != false) {
  381. $ret[$result['id']] = $result;
  382. }
  383. }
  384. }
  385. catch (Exception $e) {
  386. Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
  387. }
  388. return $ret;
  389. }
  390. /**
  391. * Selects the text entry fields, gets their data, combines the words and writes it into the search field
  392. * for every entry in the current loaded collection
  393. *
  394. * @param string $collectionId The id of the collection
  395. * @param array $searchFields The available search fields of the given collection
  396. * @return bool
  397. */
  398. public function updateSearchData(string $collectionId, array $searchFields): bool {
  399. $ret = false;
  400. // simple search fields for loaded collection
  401. // Every field witch has a column in the entry table is a simple search field.
  402. // Name starts with entry. Here we want only the text fields
  403. // Those fields are the data for the combined search field
  404. $dataFields = array();
  405. $_fieldAvailable = false;
  406. if(!empty($searchFields)) {
  407. foreach($searchFields as $k=>$v) {
  408. if($v['identifier'] == "combSearch") {
  409. $_fieldAvailable = true;
  410. continue;
  411. }
  412. if(isset($v['searchtype']) && str_contains($v['searchtype'], 'Text')) {
  413. $dataFields[$k] = $v['identifier'];
  414. }
  415. }
  416. }
  417. // only if the combSearch field is available in the collection
  418. if(!$_fieldAvailable) return $ret;
  419. // get the search data for every entry in the collection
  420. $entryData = array();
  421. if(!empty($dataFields)) {
  422. $fieldStr = implode(",",$dataFields);
  423. $queryStr = "SELECT id,".$fieldStr." FROM `".DB_PREFIX."_collection_entry_".$collectionId."`";
  424. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
  425. try {
  426. $query = $this->_DB->query($queryStr);
  427. if($query !== false && $query->num_rows > 0) {
  428. $entryData = $query->fetch_all(MYSQLI_ASSOC);
  429. }
  430. }
  431. catch (Exception $e) {
  432. Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
  433. }
  434. }
  435. // build the search data and update the entries
  436. if(!empty($entryData)) {
  437. foreach($entryData as $d) {
  438. $entryid = $d['id'];
  439. unset($d['id']);
  440. $searchData = implode(" ",$d);
  441. $searchData = implode(" ", Summoner::words($searchData));
  442. $queryStr = "UPDATE `".DB_PREFIX."_collection_entry_".$collectionId."`
  443. SET `combSearch` = '".$this->_DB->real_escape_string($searchData)."'
  444. WHERE `id` = '".$entryid."'";
  445. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
  446. try {
  447. $this->_DB->query($queryStr);
  448. $ret = true;
  449. }
  450. catch (Exception $e) {
  451. Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
  452. }
  453. }
  454. }
  455. return $ret;
  456. }
  457. /**
  458. * Check if given name can be used as a new one
  459. *
  460. * @param string $name
  461. * @return bool
  462. */
  463. private function _validNewCollectionName(string $name): bool {
  464. $ret = false;
  465. if (Summoner::validate($name, 'nospace')) {
  466. $queryStr = "SELECT `id` FROM `".DB_PREFIX."_collection`
  467. WHERE `name` = '".$this->_DB->real_escape_string($name)."'";
  468. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
  469. try {
  470. $query = $this->_DB->query($queryStr);
  471. if ($query !== false && $query->num_rows < 1) {
  472. $ret = true;
  473. }
  474. }
  475. catch (Exception $e) {
  476. Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
  477. }
  478. }
  479. return $ret;
  480. }
  481. /**
  482. * Check if given name can be used as a new name for id
  483. *
  484. * @param string $name
  485. * @param string $id Number
  486. * @return bool
  487. */
  488. private function _validUpdateCollectionName(string $name, string $id): bool {
  489. $ret = false;
  490. if (Summoner::validate($name, 'nospace')
  491. && Summoner::validate($id,'digit')
  492. ) {
  493. $queryStr = "SELECT `id` FROM `".DB_PREFIX."_collection`
  494. WHERE `name` = '".$this->_DB->real_escape_string($name)."'
  495. AND `id` != '".$this->_DB->real_escape_string($id)."'";
  496. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
  497. try {
  498. $query = $this->_DB->query($queryStr);
  499. if ($query !== false && $query->num_rows < 1) {
  500. $ret = true;
  501. }
  502. }
  503. catch (Exception $e) {
  504. Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
  505. }
  506. }
  507. return $ret;
  508. }
  509. /**
  510. * Update the given colletion ($id) with the given tool array
  511. *
  512. * @param string $id Number
  513. * @param array $tool
  514. * @return bool
  515. */
  516. private function _updateToolRelation(string $id, array $tool): bool {
  517. $ret = false;
  518. $queryStr = "DELETE FROM `".DB_PREFIX."_tool2collection`
  519. WHERE `fk_collection_id` = '".$this->_DB->real_escape_string($id)."'";
  520. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
  521. try {
  522. $this->_DB->begin_transaction(MYSQLI_TRANS_START_READ_WRITE);
  523. $this->_DB->query($queryStr);
  524. if(!empty($tool)) {
  525. foreach($tool as $k=>$v) {
  526. if(!empty($v)) {
  527. $insertQueryStr = "INSERT IGNORE INTO `".DB_PREFIX."_tool2collection`
  528. SET `fk_tool_id` = '".$this->_DB->real_escape_string($v)."',
  529. `fk_collection_id` = '".$this->_DB->real_escape_string($id)."'";
  530. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($insertQueryStr));
  531. $this->_DB->query($insertQueryStr);
  532. }
  533. }
  534. }
  535. $this->_DB->commit();
  536. $ret = true;
  537. }
  538. catch (Exception $e) {
  539. $this->_DB->rollback();
  540. Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
  541. }
  542. return $ret;
  543. }
  544. /**
  545. * Update the rights from the group to the entries in this collection
  546. *
  547. * @param string $collectionId
  548. * @param string $owner
  549. * @param string $group
  550. * @param string $rights
  551. */
  552. private function _updateEntryRights(string $collectionId, string $owner='', string $group='', string $rights=''): void {
  553. if(!empty($collectionId)) {
  554. $queryStr = "UPDATE `".DB_PREFIX."_collection_entry_".$collectionId."` SET";
  555. if(Summoner::validate($owner, "digit")) {
  556. $queryStr .= " `owner` = '".$this->_DB->real_escape_string($owner)."',";
  557. }
  558. if(Summoner::validate($group, "digit")) {
  559. $queryStr .= " `group` = '".$this->_DB->real_escape_string($group)."',";
  560. }
  561. if(Summoner::validate($rights, "rights")) {
  562. $queryStr .= " `rights` = '".$this->_DB->real_escape_string($rights)."',";
  563. }
  564. $queryStr = trim($queryStr, ",");
  565. if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
  566. try {
  567. $this->_DB->query($queryStr);
  568. }
  569. catch (Exception $e) {
  570. Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
  571. }
  572. }
  573. }
  574. /**
  575. * Make a key=>value array of a comma seperated string and use the value as key
  576. *
  577. * @param string $data
  578. * @return array
  579. */
  580. private function _loadAdvancedSearchTableFields(string $data): array {
  581. $ret = array();
  582. $_t = explode(',',$data);
  583. foreach($_t as $e) {
  584. $ret[$e] = $e;
  585. }
  586. return $ret;
  587. }
  588. }