SavedSearches.class.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Saved searches managing
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. if (! defined('PHPMYADMIN')) {
  9. exit;
  10. }
  11. /**
  12. * Saved searches managing
  13. *
  14. * @package PhpMyAdmin
  15. */
  16. class PMA_SavedSearches
  17. {
  18. /**
  19. * Global configuration
  20. * @var array
  21. */
  22. private $_config = null;
  23. /**
  24. * Id
  25. * @var int|null
  26. */
  27. private $_id = null;
  28. /**
  29. * Username
  30. * @var string
  31. */
  32. private $_username = null;
  33. /**
  34. * DB name
  35. * @var string
  36. */
  37. private $_dbname = null;
  38. /**
  39. * Saved search name
  40. * @var string
  41. */
  42. private $_searchName = null;
  43. /**
  44. * Setter of id
  45. *
  46. * @param int|null $searchId Id of search
  47. *
  48. * @return static
  49. */
  50. public function setId($searchId)
  51. {
  52. $searchId = (int)$searchId;
  53. if (empty($searchId)) {
  54. $searchId = null;
  55. }
  56. $this->_id = $searchId;
  57. return $this;
  58. }
  59. /**
  60. * Getter of id
  61. *
  62. * @return int|null
  63. */
  64. public function getId()
  65. {
  66. return $this->_id;
  67. }
  68. /**
  69. * Setter of searchName
  70. *
  71. * @param string $searchName Saved search name
  72. *
  73. * @return static
  74. */
  75. public function setSearchName($searchName)
  76. {
  77. $this->_searchName = $searchName;
  78. return $this;
  79. }
  80. /**
  81. * Getter of searchName
  82. *
  83. * @return string
  84. */
  85. public function getSearchName()
  86. {
  87. return $this->_searchName;
  88. }
  89. /**
  90. * Criterias
  91. * @var array
  92. */
  93. private $_criterias = null;
  94. /**
  95. * Setter of config
  96. *
  97. * @param array $config Global configuration
  98. *
  99. * @return static
  100. */
  101. public function setConfig($config)
  102. {
  103. $this->_config = $config;
  104. return $this;
  105. }
  106. /**
  107. * Getter of config
  108. *
  109. * @return array
  110. */
  111. public function getConfig()
  112. {
  113. return $this->_config;
  114. }
  115. /**
  116. * Setter for criterias
  117. *
  118. * @param array $criterias Criterias of saved searches
  119. * @param bool $json Criterias are in JSON format
  120. *
  121. * @return static
  122. */
  123. public function setCriterias($criterias, $json = false)
  124. {
  125. if (true === $json && is_string($criterias)) {
  126. $this->_criterias = json_decode($criterias, true);
  127. return $this;
  128. }
  129. $aListFieldsToGet = array(
  130. 'criteriaColumn',
  131. 'criteriaSort',
  132. 'criteriaShow',
  133. 'criteria',
  134. 'criteriaAndOrRow',
  135. 'criteriaAndOrColumn',
  136. 'rows'
  137. );
  138. $data = array();
  139. $data['criteriaColumnCount'] = count($criterias['criteriaColumn']);
  140. foreach ($aListFieldsToGet as $field) {
  141. $data[$field] = $criterias[$field];
  142. }
  143. for ($i = 0; $i <= $data['rows']; $i++) {
  144. $data['Or' . $i] = $criterias['Or' . $i];
  145. }
  146. $this->_criterias = $data;
  147. return $this;
  148. }
  149. /**
  150. * Getter for criterias
  151. *
  152. * @return array
  153. */
  154. public function getCriterias()
  155. {
  156. return $this->_criterias;
  157. }
  158. /**
  159. * Setter for username
  160. *
  161. * @param string $username Username
  162. *
  163. * @return static
  164. */
  165. public function setUsername($username)
  166. {
  167. $this->_username = $username;
  168. return $this;
  169. }
  170. /**
  171. * Getter for username
  172. *
  173. * @return string
  174. */
  175. public function getUsername()
  176. {
  177. return $this->_username;
  178. }
  179. /**
  180. * Setter for DB name
  181. *
  182. * @param string $dbname DB name
  183. *
  184. * @return static
  185. */
  186. public function setDbname($dbname)
  187. {
  188. $this->_dbname = $dbname;
  189. return $this;
  190. }
  191. /**
  192. * Getter for DB name
  193. *
  194. * @return string
  195. */
  196. public function getDbname()
  197. {
  198. return $this->_dbname;
  199. }
  200. /**
  201. * Public constructor
  202. *
  203. * @param array $config Global configuration
  204. */
  205. public function __construct($config)
  206. {
  207. $this->setConfig($config);
  208. }
  209. /**
  210. * Save the search
  211. *
  212. * @return boolean
  213. */
  214. public function save()
  215. {
  216. if (null == $this->getSearchName()) {
  217. $message = PMA_Message::error(
  218. __('Please provide a name for this bookmarked search.')
  219. );
  220. $response = PMA_Response::getInstance();
  221. $response->isSuccess($message->isSuccess());
  222. $response->addJSON('fieldWithError', 'searchName');
  223. $response->addJSON('message', $message);
  224. exit;
  225. }
  226. if (null == $this->getUsername()
  227. || null == $this->getDbname()
  228. || null == $this->getSearchName()
  229. || null == $this->getCriterias()
  230. ) {
  231. $message = PMA_Message::error(
  232. __('Missing information to save the bookmarked search.')
  233. );
  234. $response = PMA_Response::getInstance();
  235. $response->isSuccess($message->isSuccess());
  236. $response->addJSON('message', $message);
  237. exit;
  238. }
  239. $savedSearchesTbl
  240. = PMA_Util::backquote($this->_config['cfgRelation']['db']) . "."
  241. . PMA_Util::backquote($this->_config['cfgRelation']['savedsearches']);
  242. //If it's an insert.
  243. if (null === $this->getId()) {
  244. $wheres = array(
  245. "search_name = '" . PMA_Util::sqlAddSlashes($this->getSearchName())
  246. . "'"
  247. );
  248. $existingSearches = $this->getList($wheres);
  249. if (!empty($existingSearches)) {
  250. $message = PMA_Message::error(
  251. __('An entry with this name already exists.')
  252. );
  253. $response = PMA_Response::getInstance();
  254. $response->isSuccess($message->isSuccess());
  255. $response->addJSON('fieldWithError', 'searchName');
  256. $response->addJSON('message', $message);
  257. exit;
  258. }
  259. $sqlQuery = "INSERT INTO " . $savedSearchesTbl
  260. . "(`username`, `db_name`, `search_name`, `search_data`)"
  261. . " VALUES ("
  262. . "'" . PMA_Util::sqlAddSlashes($this->getUsername()) . "',"
  263. . "'" . PMA_Util::sqlAddSlashes($this->getDbname()) . "',"
  264. . "'" . PMA_Util::sqlAddSlashes($this->getSearchName()) . "',"
  265. . "'" . PMA_Util::sqlAddSlashes(json_encode($this->getCriterias()))
  266. . "')";
  267. $result = (bool)PMA_queryAsControlUser($sqlQuery);
  268. if (!$result) {
  269. return false;
  270. }
  271. $this->setId($GLOBALS['dbi']->insertId());
  272. return true;
  273. }
  274. //Else, it's an update.
  275. $wheres = array(
  276. "id != " . $this->getId(),
  277. "search_name = '" . PMA_Util::sqlAddSlashes($this->getSearchName()) . "'"
  278. );
  279. $existingSearches = $this->getList($wheres);
  280. if (!empty($existingSearches)) {
  281. $message = PMA_Message::error(
  282. __('An entry with this name already exists.')
  283. );
  284. $response = PMA_Response::getInstance();
  285. $response->isSuccess($message->isSuccess());
  286. $response->addJSON('fieldWithError', 'searchName');
  287. $response->addJSON('message', $message);
  288. exit;
  289. }
  290. $sqlQuery = "UPDATE " . $savedSearchesTbl
  291. . "SET `search_name` = '"
  292. . PMA_Util::sqlAddSlashes($this->getSearchName()) . "', "
  293. . "`search_data` = '"
  294. . PMA_Util::sqlAddSlashes(json_encode($this->getCriterias())) . "' "
  295. . "WHERE id = " . $this->getId();
  296. return (bool)PMA_queryAsControlUser($sqlQuery);
  297. }
  298. /**
  299. * Delete the search
  300. *
  301. * @return boolean
  302. */
  303. public function delete()
  304. {
  305. if (null == $this->getId()) {
  306. $message = PMA_Message::error(
  307. __('Missing information to delete the search.')
  308. );
  309. $response = PMA_Response::getInstance();
  310. $response->isSuccess($message->isSuccess());
  311. $response->addJSON('fieldWithError', 'searchId');
  312. $response->addJSON('message', $message);
  313. exit;
  314. }
  315. $savedSearchesTbl
  316. = PMA_Util::backquote($this->_config['cfgRelation']['db']) . "."
  317. . PMA_Util::backquote($this->_config['cfgRelation']['savedsearches']);
  318. $sqlQuery = "DELETE FROM " . $savedSearchesTbl
  319. . "WHERE id = '" . PMA_Util::sqlAddSlashes($this->getId()) . "'";
  320. return (bool)PMA_queryAsControlUser($sqlQuery);
  321. }
  322. /**
  323. * Load the current search from an id.
  324. *
  325. * @return bool Success
  326. */
  327. public function load()
  328. {
  329. if (null == $this->getId()) {
  330. $message = PMA_Message::error(
  331. __('Missing information to load the search.')
  332. );
  333. $response = PMA_Response::getInstance();
  334. $response->isSuccess($message->isSuccess());
  335. $response->addJSON('fieldWithError', 'searchId');
  336. $response->addJSON('message', $message);
  337. exit;
  338. }
  339. $savedSearchesTbl = PMA_Util::backquote($this->_config['cfgRelation']['db'])
  340. . "."
  341. . PMA_Util::backquote($this->_config['cfgRelation']['savedsearches']);
  342. $sqlQuery = "SELECT id, search_name, search_data "
  343. . "FROM " . $savedSearchesTbl . " "
  344. . "WHERE id = '" . PMA_Util::sqlAddSlashes($this->getId()) . "' ";
  345. $resList = PMA_queryAsControlUser($sqlQuery);
  346. if (false === ($oneResult = $GLOBALS['dbi']->fetchArray($resList))) {
  347. $message = PMA_Message::error(__('Error while loading the search.'));
  348. $response = PMA_Response::getInstance();
  349. $response->isSuccess($message->isSuccess());
  350. $response->addJSON('fieldWithError', 'searchId');
  351. $response->addJSON('message', $message);
  352. exit;
  353. }
  354. $this->setSearchName($oneResult['search_name'])
  355. ->setCriterias($oneResult['search_data'], true);
  356. return true;
  357. }
  358. /**
  359. * Get the list of saved search of a user on a DB
  360. *
  361. * @param array $wheres List of filters
  362. *
  363. * @return array|bool List of saved search or false on failure
  364. */
  365. public function getList(array $wheres = array())
  366. {
  367. if (null == $this->getUsername()
  368. || null == $this->getDbname()
  369. ) {
  370. return false;
  371. }
  372. $savedSearchesTbl = PMA_Util::backquote($this->_config['cfgRelation']['db'])
  373. . "."
  374. . PMA_Util::backquote($this->_config['cfgRelation']['savedsearches']);
  375. $sqlQuery = "SELECT id, search_name "
  376. . "FROM " . $savedSearchesTbl . " "
  377. . "WHERE "
  378. . "username = '" . PMA_Util::sqlAddSlashes($this->getUsername()) . "' "
  379. . "AND db_name = '" . PMA_Util::sqlAddSlashes($this->getDbname()) . "' ";
  380. foreach ($wheres as $where) {
  381. $sqlQuery .= "AND " . $where . " ";
  382. }
  383. $sqlQuery .= "order by search_name ASC ";
  384. $resList = PMA_queryAsControlUser($sqlQuery);
  385. $list = array();
  386. while ($oneResult = $GLOBALS['dbi']->fetchArray($resList)) {
  387. $list[$oneResult['id']] = $oneResult['search_name'];
  388. }
  389. return $list;
  390. }
  391. }