UserQuery.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <?php
  2. /**
  3. * Contains the description of a user query
  4. *
  5. * It allows to extract the meaningful bits of the query to be manipulated in an
  6. * easy way.
  7. */
  8. class FreshRSS_UserQuery {
  9. private bool $deprecated = false;
  10. private string $get = '';
  11. private string $get_name = '';
  12. private string $get_type = '';
  13. private string $name = '';
  14. private string $order = '';
  15. private FreshRSS_BooleanSearch $search;
  16. private int $state = 0;
  17. private string $url = '';
  18. private ?FreshRSS_FeedDAO $feed_dao;
  19. private ?FreshRSS_CategoryDAO $category_dao;
  20. private ?FreshRSS_TagDAO $tag_dao;
  21. /**
  22. * @param array{'get'?:string,'name'?:string,'order'?:string,'search'?:string,'state'?:int,'url'?:string} $query
  23. */
  24. public function __construct(array $query, FreshRSS_FeedDAO $feed_dao = null, FreshRSS_CategoryDAO $category_dao = null, FreshRSS_TagDAO $tag_dao = null) {
  25. $this->category_dao = $category_dao;
  26. $this->feed_dao = $feed_dao;
  27. $this->tag_dao = $tag_dao;
  28. if (isset($query['get'])) {
  29. $this->parseGet($query['get']);
  30. }
  31. if (isset($query['name'])) {
  32. $this->name = trim($query['name']);
  33. }
  34. if (isset($query['order'])) {
  35. $this->order = $query['order'];
  36. }
  37. if (empty($query['url'])) {
  38. if (!empty($query)) {
  39. unset($query['name']);
  40. $this->url = Minz_Url::display(['params' => $query]);
  41. }
  42. } else {
  43. $this->url = $query['url'];
  44. }
  45. if (!isset($query['search'])) {
  46. $query['search'] = '';
  47. }
  48. // linked too deeply with the search object, need to use dependency injection
  49. $this->search = new FreshRSS_BooleanSearch($query['search']);
  50. if (!empty($query['state'])) {
  51. $this->state = intval($query['state']);
  52. }
  53. }
  54. /**
  55. * Convert the current object to an array.
  56. *
  57. * @return array{'get'?:string,'name'?:string,'order'?:string,'search'?:string,'state'?:int,'url'?:string}
  58. */
  59. public function toArray(): array {
  60. return array_filter([
  61. 'get' => $this->get,
  62. 'name' => $this->name,
  63. 'order' => $this->order,
  64. 'search' => $this->search->__toString(),
  65. 'state' => $this->state,
  66. 'url' => $this->url,
  67. ]);
  68. }
  69. /**
  70. * Parse the get parameter in the query string to extract its name and type
  71. */
  72. private function parseGet(string $get): void {
  73. $this->get = $get;
  74. if (preg_match('/(?P<type>[acfst])(_(?P<id>\d+))?/', $get, $matches)) {
  75. $id = intval($matches['id'] ?? '0');
  76. switch ($matches['type']) {
  77. case 'a':
  78. $this->parseAll();
  79. break;
  80. case 'c':
  81. $this->parseCategory($id);
  82. break;
  83. case 'f':
  84. $this->parseFeed($id);
  85. break;
  86. case 's':
  87. $this->parseFavorite();
  88. break;
  89. case 't':
  90. $this->parseTag($id);
  91. break;
  92. }
  93. }
  94. }
  95. /**
  96. * Parse the query string when it is an "all" query
  97. */
  98. private function parseAll(): void {
  99. $this->get_name = 'all';
  100. $this->get_type = 'all';
  101. }
  102. /**
  103. * Parse the query string when it is a "category" query
  104. *
  105. * @throws FreshRSS_DAO_Exception
  106. */
  107. private function parseCategory(int $id): void {
  108. if ($this->category_dao === null) {
  109. $this->category_dao = FreshRSS_Factory::createCategoryDao();
  110. }
  111. $category = $this->category_dao->searchById($id);
  112. if ($category !== null) {
  113. $this->get_name = $category->name();
  114. } else {
  115. $this->deprecated = true;
  116. }
  117. $this->get_type = 'category';
  118. }
  119. /**
  120. * Parse the query string when it is a "feed" query
  121. *
  122. * @throws FreshRSS_DAO_Exception
  123. */
  124. private function parseFeed(int $id): void {
  125. if ($this->feed_dao === null) {
  126. $this->feed_dao = FreshRSS_Factory::createFeedDao();
  127. }
  128. $feed = $this->feed_dao->searchById($id);
  129. if ($feed !== null) {
  130. $this->get_name = $feed->name();
  131. } else {
  132. $this->deprecated = true;
  133. }
  134. $this->get_type = 'feed';
  135. }
  136. /**
  137. * Parse the query string when it is a "tag" query
  138. *
  139. * @throws FreshRSS_DAO_Exception
  140. */
  141. private function parseTag(int $id): void {
  142. if ($this->tag_dao === null) {
  143. $this->tag_dao = FreshRSS_Factory::createTagDao();
  144. }
  145. $tag = $this->tag_dao->searchById($id);
  146. if ($tag !== null) {
  147. $this->get_name = $tag->name();
  148. } else {
  149. $this->deprecated = true;
  150. }
  151. $this->get_type = 'tag';
  152. }
  153. /**
  154. * Parse the query string when it is a "favorite" query
  155. */
  156. private function parseFavorite(): void {
  157. $this->get_name = 'favorite';
  158. $this->get_type = 'favorite';
  159. }
  160. /**
  161. * Check if the current user query is deprecated.
  162. * It is deprecated if the category or the feed used in the query are
  163. * not existing.
  164. */
  165. public function isDeprecated(): bool {
  166. return $this->deprecated;
  167. }
  168. /**
  169. * Check if the user query has parameters.
  170. * If the type is 'all', it is considered equal to no parameters
  171. */
  172. public function hasParameters(): bool {
  173. if ($this->get_type === 'all') {
  174. return false;
  175. }
  176. if ($this->hasSearch()) {
  177. return true;
  178. }
  179. if ($this->state) {
  180. return true;
  181. }
  182. if ($this->order) {
  183. return true;
  184. }
  185. if ($this->get) {
  186. return true;
  187. }
  188. return false;
  189. }
  190. /**
  191. * Check if there is a search in the search object
  192. */
  193. public function hasSearch(): bool {
  194. return $this->search->getRawInput() !== '';
  195. }
  196. public function getGet(): string {
  197. return $this->get;
  198. }
  199. public function getGetName(): string {
  200. return $this->get_name;
  201. }
  202. public function getGetType(): string {
  203. return $this->get_type;
  204. }
  205. public function getName(): string {
  206. return $this->name;
  207. }
  208. public function getOrder(): string {
  209. return $this->order;
  210. }
  211. public function getSearch(): FreshRSS_BooleanSearch {
  212. return $this->search;
  213. }
  214. public function getState(): int {
  215. return $this->state;
  216. }
  217. public function getUrl(): string {
  218. return $this->url;
  219. }
  220. }