Report_Rune_Enchantment_Page.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. <?php
  2. /**
  3. * Upgradeable runes report page file.
  4. *
  5. * Provides a class with all the properties and methods to display the page.
  6. *
  7. * @author Iñigo Valentin <i@inigovalentin.com>
  8. * @license https://www.gnu.org/licenses/gpl-3.0.en.html GNU General Public License V3
  9. * @package SWDB
  10. */
  11. require_once(PATH::PAGE . "Page.php");
  12. require_once(PATH::ENTITY . "Unit.php");
  13. require_once(PATH::ENTITY . "Rune.php");
  14. require_once(PATH::ENTITY . "Enchantment.php");
  15. /**
  16. * Upgradeable runes report page model.
  17. *
  18. * @category Page
  19. * @todo Some filters are not implemented (enchantment type, teams...)
  20. */
  21. class Report_Rune_Enchantment_Page extends Page{
  22. /**
  23. * @var mixed[] List of available upgrades.
  24. */
  25. private $upgrades = [];
  26. /**
  27. * @var mixed[] Default filter values.
  28. */
  29. private $filters = [
  30. "MONSTER_NAME" => "",
  31. "MONSTER_MIN_STARS" => 5,
  32. "MONSTER_MAX_STARS" => 6,
  33. "MONSTER_IN_STORAGE" => false,
  34. "TEAM" => false,
  35. "RUNE_MIN_STARS" => 5,
  36. "RUNE_MAX_STARS" => 6,
  37. "RUNE_MIN_LEVEL" => 0,
  38. "RUNE_MAX_LEVEL" => 15,
  39. "RUNE_MIN_QUALITY" => QUALITY_ID::HERO,
  40. "RUNE_MAX_QUALITY" => QUALITY_ID::LEGEND,
  41. "RUNE_MIN_ORIGINAL_QUALITY" => QUALITY_ID::HERO,
  42. "RUNE_MAX_ORIGINAL_QUALITY" => QUALITY_ID::LEGEND,
  43. "RUNE_MIN_EFFICIENCY" => 0,
  44. "RUNE_MAX_EFFICIENCY" => 100,
  45. "RUNE_MIN_MAX_EFFICIENCY" => 0,
  46. "RUNE_MAX_MAX_EFFICIENCY" => 100,
  47. "RUNE_SLOT" => [],
  48. "GRIND" => 1,
  49. "GRIND_MIN_QUALITY" => QUALITY_ID::RARE,
  50. "GRIND_STAT" => [
  51. RUNE_STAT_ID::HP_P,
  52. RUNE_STAT_ID::ATK_P,
  53. RUNE_STAT_ID::DEF_P,
  54. RUNE_STAT_ID::SPD,
  55. RUNE_STAT_ID::CRD,
  56. RUNE_STAT_ID::CRR,
  57. RUNE_STAT_ID::ACC
  58. ],
  59. "GEM" => 1,
  60. "GEM_MIN_QUALITY" => QUALITY_ID::RARE,
  61. "GEM_STAT_FROM" => [
  62. RUNE_STAT_ID::HP,
  63. RUNE_STAT_ID::ATK,
  64. RUNE_STAT_ID::DEF,
  65. RUNE_STAT_ID::RES
  66. ],
  67. "GEM_STAT_TO" => [
  68. RUNE_STAT_ID::HP_P,
  69. RUNE_STAT_ID::ATK_P,
  70. RUNE_STAT_ID::DEF_P,
  71. RUNE_STAT_ID::SPD,
  72. RUNE_STAT_ID::CRD,
  73. RUNE_STAT_ID::CRR,
  74. RUNE_STAT_ID::ACC
  75. ]
  76. ];
  77. /**
  78. * Constructor.
  79. *
  80. * Retrieves the data and initializes the variables.
  81. */
  82. public function __construct(){
  83. $this->view = PATH::VIEW . "report_rune_enchantment.php";
  84. $prev_monster = "";
  85. $prev_rune = "";
  86. $upgrade = null;
  87. $rupgrade = null;
  88. $this->parse_filters();
  89. $result_set = $this->prepare_statement()->execute();
  90. while ($result = $result_set->fetchArray(SQLITE3_ASSOC)){
  91. if ($result["unit"] != $prev_monster){
  92. if ($prev_rune != ""){
  93. array_push($upgrade["upgrade"], $rupgrade);
  94. }
  95. if ($prev_monster != ""){
  96. array_push($this->upgrades, $upgrade);
  97. }
  98. $prev_monster = $result["unit"];
  99. $prev_rune = "";
  100. $upgrade = [
  101. "unit" => new Unit($result["unit"]),
  102. "upgrade" => [],
  103. ];
  104. $rupgrade = [
  105. "rune" => new Rune($result["rune"]),
  106. "enchantment" => [],
  107. ];
  108. }
  109. if ($result["rune"] != $prev_rune){
  110. if ($prev_rune != ""){
  111. array_push($upgrade["upgrade"], $rupgrade);
  112. }
  113. $prev_rune = $result["rune"];
  114. $rupgrade = [
  115. "rune" => new Rune($result["rune"]),
  116. "enchantment" => [],
  117. ];
  118. }
  119. $enchantment= new Enchantment($result["enchantment"]);
  120. array_push($rupgrade["enchantment"], $enchantment);
  121. }
  122. // Last entries
  123. array_push($upgrade["upgrade"], $rupgrade);
  124. array_push($this->upgrades, $upgrade);
  125. $this->title = "Rune enchantment - SWDB";
  126. $this->description = "Find runes that can be upgraded via enchantments.";
  127. $this->canonical = URL::BASE . "report/rune_enchantment/";
  128. }
  129. /**
  130. * Parses the filters passed in the request and sets $filters.
  131. * Filters must be in $_GET, nd the available ones are max_stars (1-6),
  132. * min_stars (1-6) and in_storage (on/off).
  133. */
  134. private function parse_filters(){
  135. // Monster
  136. if (isset($_GET["monster_min_stars"]) && intval($_GET["monster_min_stars"]) > 0 && intval($_GET["monster_min_stars"]) < 7){
  137. $this->filters["MONSTER_MIN_STARS"] = $_GET["monster_min_stars"];
  138. }
  139. if (isset($_GET["monster_max_stars"]) && intval($_GET["monster_max_stars"]) > 0 && intval($_GET["monster_max_stars"]) < 7){
  140. $this->filters["MONSTER_MAX_STARS"] = $_GET["monster_max_stars"];
  141. }
  142. if (isset($_GET["monster_in_storage"]) && $_GET["monster_in_storage"] == "on"){
  143. $this->filters["MONSTER_IN_STORAGE"] = true;
  144. }
  145. else{
  146. $this->filters["MONSTER_IN_STORAGE"] = false;
  147. }
  148. if (isset($_GET["monster_name"]) && strlen($_GET["monster_name"]) > 0){
  149. $this->filters["MONSTER_NAME"] = SQLite3::escapeString($_GET["monster_name"]);
  150. }
  151. // Runes
  152. if (isset($_GET["rune_min_stars"]) && intval($_GET["rune_min_stars"]) > 0 && intval($_GET["rune_min_stars"]) < 7){
  153. $this->filters["RUNE_MIN_STARS"] = $_GET["rune_min_stars"];
  154. }
  155. if (isset($_GET["rune_max_stars"]) && intval($_GET["rune_max_stars"]) > 0 && intval($_GET["rune_max_stars"]) < 7){
  156. $this->filters["RUNE_MAX_STARS"] = $_GET["rune_max_stars"];
  157. }
  158. if (isset($_GET["rune_min_level"]) && intval($_GET["rune_min_level"]) >= 0 && intval($_GET["rune_min_level"]) <= 15){
  159. $this->filters["RUNE_MIN_LEVEL"] = $_GET["rune_min_level"];
  160. }
  161. if (isset($_GET["rune_max_level"]) && intval($_GET["rune_max_level"]) >= 0 && intval($_GET["rune_max_level"]) <= 15){
  162. $this->filters["RUNE_MAX_LEVEL"] = $_GET["rune_max_level"];
  163. }
  164. if (isset($_GET["rune_min_quality"]) && intval($_GET["rune_min_quality"]) >= QUALITY_ID::NORMAL && intval($_GET["rune_min_quality"]) <= QUALITY_ID::LEGEND){
  165. $this->filters["RUNE_MIN_QUALITY"] = $_GET["rune_min_quality"];
  166. }
  167. if (isset($_GET["rune_max_quality"]) && intval($_GET["rune_max_quality"]) >= QUALITY_ID::NORMAL && intval($_GET["rune_max_quality"]) <= QUALITY_ID::LEGEND){
  168. $this->filters["RUNE_MAX_QUALITY"] = $_GET["rune_max_quality"];
  169. }
  170. if (isset($_GET["rune_min_original_quality"]) && intval($_GET["rune_min_original_quality"]) >= QUALITY_ID::NORMAL && intval($_GET["rune_min_original_quality"]) <= QUALITY_ID::LEGEND){
  171. $this->filters["RUNE_MIN_ORIGINAL_QUALITY"] = $_GET["rune_min_original_quality"];
  172. }
  173. if (isset($_GET["rune_max_original_quality"]) && intval($_GET["rune_max_original_quality"]) >= QUALITY_ID::NORMAL && intval($_GET["rune_max_original_quality"]) <= QUALITY_ID::LEGEND){
  174. $this->filters["RUNE_MAX_ORIGINAL_QUALITY"] = $_GET["rune_max_original_quality"];
  175. }
  176. if (isset($_GET["rune_min_efficiency"]) && intval($_GET["rune_min_efficiency"]) >= 0 && intval($_GET["rune_min_efficiency"]) <= 100){
  177. $this->filters["RUNE_MIN_EFFICIENCY"] = $_GET["rune_min_efficiency"];
  178. }
  179. if (isset($_GET["rune_max_efficiency"]) && intval($_GET["rune_max_efficiency"]) >= 0 && intval($_GET["rune_max_efficiency"]) <= 100){
  180. $this->filters["RUNE_MAX_EFFICIENCY"] = $_GET["rune_max_efficiency"];
  181. }
  182. if (isset($_GET["rune_min_max_efficiency"]) && intval($_GET["rune_min_max_efficiency"]) >= 0 && intval($_GET["rune_min_max_efficiency"]) <= 100){
  183. $this->filters["RUNE_MIN_MAX_EFFICIENCY"] = $_GET["rune_min_max_efficiency"];
  184. }
  185. if (isset($_GET["rune_max_max_efficiency"]) && intval($_GET["rune_max_max_efficiency"]) >= 0 && intval($_GET["rune_max_max_efficiency"]) <= 100){
  186. $this->filters["RUNE_MAX_MAX_EFFICIENCY"] = $_GET["rune_max_max_efficiency"];
  187. }
  188. if (isset($_GET["rune_slot"])){
  189. $slots = $_GET["rune_slot"];
  190. foreach ($slots as $slot){
  191. if (intval($slot) >= 1 && intval($slot) < 7){
  192. array_push($this->filters["RUNE_SLOT"], intval($slot));
  193. }
  194. }
  195. }
  196. // Grindstones
  197. if (isset($_GET["grind_min_quality"]) && intval($_GET["grind_min_quality"]) >= QUALITY_ID::NORMAL && intval($_GET["grind_min_quality"]) < QUALITY_ID::LEGEND){
  198. $this->filters["GRIND_MIN_QUALITY"] = $_GET["grind_min_quality"];
  199. }
  200. if (isset($_GET["grind_stat"])){
  201. $stats = $_GET["grind_stat"];
  202. $this->filters["GRIND_STAT"] = [];
  203. foreach ($stats as $stat){
  204. array_push($this->filters["GRIND_STAT"], intval($stat));
  205. }
  206. }
  207. if (isset($_GET["gem_stat_from"])){
  208. $stats = $_GET["gem_stat_from"];
  209. $this->filters["GEM_STAT_FROM"] = [];
  210. foreach ($stats as $stat){
  211. array_push($this->filters["GEM_STAT_FROM"], intval($stat));
  212. }
  213. }
  214. if (isset($_GET["gem_stat_to"])){
  215. $stats = $_GET["gem_stat_to"];
  216. $this->filters["GEM_STAT_TO"] = [];
  217. foreach ($stats as $stat){
  218. array_push($this->filters["GEM_STAT_TO"], intval($stat));
  219. }
  220. }
  221. return;
  222. }
  223. /**
  224. * Prepares the statement to execute against the database using the filter values.
  225. *
  226. * @return SQLite3Stmt prepared statement.
  227. */
  228. private function prepare_statement(){
  229. // Common items
  230. $query = "
  231. SELECT DISTINCT
  232. unit.id AS unit,
  233. rune.id AS rune,
  234. enchantment.id AS enchantment
  235. FROM
  236. unit,
  237. monster,
  238. rune,
  239. unit_rune,
  240. enchantment,
  241. enchantment_type
  242. WHERE
  243. unit.player = :player AND
  244. rune.player = unit.player AND
  245. enchantment.player = unit.player AND
  246. unit.id = unit_rune.unit AND
  247. rune.id = unit_rune.rune AND
  248. unit_rune.rta = :rta AND
  249. unit.monster = monster.id AND
  250. enchantment.type = enchantment_type.id AND
  251. -- RUNE FILTERS
  252. rune.stars BETWEEN :rune_min_stars AND :rune_max_stars AND
  253. rune.quality BETWEEN :rune_min_quality AND :rune_max_quality AND
  254. rune.original_quality BETWEEN :rune_min_original_quality AND :rune_max_original_quality AND
  255. rune.level BETWEEN :rune_min_level AND :rune_max_level AND
  256. rune.efficiency BETWEEN :rune_min_efficiency AND :rune_max_efficiency AND
  257. rune.max_efficiency BETWEEN :rune_min_max_efficiency AND :rune_max_max_efficiency AND
  258. (rune.type = enchantment.rune OR enchantment_type.inmemorial = 1) AND
  259. enchantment_type.ancient = rune.ancient AND
  260. -- No enchantments with the same sat as the runes main or innate
  261. enchantment.stat NOT IN (
  262. SELECT stat
  263. FROM rune_stat
  264. WHERE
  265. rune_stat.rune = rune.id AND
  266. (
  267. rune_stat.slot = :stat_main OR
  268. rune_stat.slot = :stat_innate
  269. )
  270. ) AND
  271. ( -- TYPE SWITCH
  272. ( -- BEGIN GRINDSTONE BLOCK
  273. enchantment_type.gem = 0 AND
  274. enchantment.stat IN (SELECT stat FROM rune_stat WHERE rune_stat.rune = rune.id) AND
  275. enchantment.quality >= :grind_min_quality
  276. ";
  277. // GRindstone stats
  278. if (count($this->filters["GRIND_STAT"]) > 0){
  279. $query .= " AND enchantment.stat IN (";
  280. for ($i = 0; $i < sizeof($this->filters["GRIND_STAT"]); $i ++){
  281. $query .= ":grind_stat_$i, ";
  282. }
  283. $query = rtrim($query, ", ") . ") ";
  284. }
  285. $query .= "
  286. ) -- END GRINDSTONE BLOCK
  287. OR
  288. ( -- BEGIN GEM BLOCK
  289. enchantment_type.gem = 1 AND
  290. enchantment.stat NOT IN (SELECT stat FROM rune_stat WHERE rune_stat.rune = rune.id) AND
  291. enchantment.quality >= :gem_min_quality
  292. ";
  293. // Gem stats from
  294. if (count($this->filters["GEM_STAT_TO"]) > 0){
  295. $query .= " AND enchantment.stat IN (";
  296. for ($i = 0; $i < sizeof($this->filters["GEM_STAT_TO"]); $i ++){
  297. $query .= ":gem_stat_to_$i, ";
  298. }
  299. $query = rtrim($query, ", ") . ") ";
  300. }
  301. //Gem stats from
  302. if (count($this->filters["GEM_STAT_FROM"]) > 0){
  303. //$query .= " AND enchantment.stat IN (";
  304. $query .= "
  305. AND rune.id IN (
  306. SELECT DISTINCT rune
  307. FROM rune_stat
  308. WHERE
  309. rune_stat.rune = rune.id AND
  310. stat IN (
  311. ";
  312. for ($i = 0; $i < sizeof($this->filters["GEM_STAT_FROM"]); $i ++){
  313. $query .= ":gem_stat_from_$i, ";
  314. }
  315. $query = rtrim($query, ", ") . ")) ";
  316. }
  317. $query .= "
  318. ) -- END GEM BLOCK
  319. ) -- END SWITCH
  320. ";
  321. // Monster name
  322. if ($this->filters["MONSTER_NAME"] != ""){
  323. $query .= " AND upper(monster.name) LIKE upper(:monster_name) " ;
  324. }
  325. // Monsters in storage
  326. if (! $this->filters["MONSTER_IN_STORAGE"]){
  327. $query .= "AND unit.building <> :storage_building ";
  328. }
  329. // Rune slot
  330. if (count($this->filters["RUNE_SLOT"]) > 0){
  331. $query .= " AND rune.slot IN (";
  332. for ($i = 0; $i < sizeof($this->filters["RUNE_SLOT"]); $i ++){
  333. $query .= ":rune_slot_$i, ";
  334. }
  335. $query = rtrim($query, ", ") . ") ";
  336. }
  337. $statement = get_context()->get_db()->prepare($query);
  338. $statement->bindValue(":player", get_context()->get_player()->get_id(), SQLITE3_TEXT);
  339. $statement->bindValue(":rta", get_context()->get_game_mode(), SQLITE3_TEXT);
  340. $statement->bindValue(":rune_min_stars", $this->filters["RUNE_MIN_STARS"], SQLITE3_INTEGER);
  341. $statement->bindValue(":rune_max_stars", $this->filters["RUNE_MAX_STARS"], SQLITE3_INTEGER);
  342. $statement->bindValue(":rune_min_quality", $this->filters["RUNE_MIN_QUALITY"], SQLITE3_INTEGER);
  343. $statement->bindValue(":rune_max_quality", $this->filters["RUNE_MAX_QUALITY"], SQLITE3_INTEGER);
  344. $statement->bindValue(":rune_min_original_quality", $this->filters["RUNE_MIN_ORIGINAL_QUALITY"], SQLITE3_INTEGER);
  345. $statement->bindValue(":rune_max_original_quality", $this->filters["RUNE_MAX_ORIGINAL_QUALITY"], SQLITE3_INTEGER);
  346. $statement->bindValue(":rune_min_level", $this->filters["RUNE_MIN_LEVEL"], SQLITE3_INTEGER);
  347. $statement->bindValue(":rune_max_level", $this->filters["RUNE_MAX_LEVEL"], SQLITE3_INTEGER);
  348. $statement->bindValue(":rune_min_efficiency", $this->filters["RUNE_MIN_EFFICIENCY"], SQLITE3_FLOAT);
  349. $statement->bindValue(":rune_max_efficiency", $this->filters["RUNE_MAX_EFFICIENCY"], SQLITE3_FLOAT);
  350. $statement->bindValue(":rune_min_max_efficiency", $this->filters["RUNE_MIN_MAX_EFFICIENCY"], SQLITE3_FLOAT);
  351. $statement->bindValue(":rune_max_max_efficiency", $this->filters["RUNE_MAX_MAX_EFFICIENCY"], SQLITE3_FLOAT);
  352. $statement->bindValue(":monster_name", "%" . $this->filters["MONSTER_NAME"] . "%", SQLITE3_TEXT);
  353. $statement->bindValue(":storage_building", BUILDING_ID::MONSTER_STORAGE, SQLITE3_INTEGER);
  354. for ($i = 0; $i < sizeof($this->filters["RUNE_SLOT"]); $i ++){
  355. $statement->bindValue(":rune_slot_$i", $this->filters["RUNE_SLOT"][$i], SQLITE3_INTEGER);
  356. }
  357. $statement->bindValue(":stat_main", RUNE_STAT_SLOT_ID::MAIN, SQLITE3_INTEGER);
  358. $statement->bindValue(":stat_innate", RUNE_STAT_SLOT_ID::INNATE, SQLITE3_INTEGER);
  359. $statement->bindValue(":grind_min_quality", $this->filters["GRIND_MIN_QUALITY"], SQLITE3_INTEGER);
  360. for ($i = 0; $i < sizeof($this->filters["GRIND_STAT"]); $i ++){
  361. $statement->bindValue(":grind_stat_$i", $this->filters["GRIND_STAT"][$i], SQLITE3_INTEGER);
  362. }
  363. $statement->bindValue(":gem_min_quality", $this->filters["GEM_MIN_QUALITY"], SQLITE3_INTEGER);
  364. for ($i = 0; $i < sizeof($this->filters["GEM_STAT_TO"]); $i ++){
  365. $statement->bindValue(":gem_stat_to_$i", $this->filters["GEM_STAT_TO"][$i], SQLITE3_INTEGER);
  366. }
  367. for ($i = 0; $i < sizeof($this->filters["GEM_STAT_FROM"]); $i ++){
  368. $statement->bindValue(":gem_stat_from_$i", $this->filters["GEM_STAT_FROM"][$i], SQLITE3_INTEGER);
  369. }
  370. return $statement;
  371. }
  372. /**
  373. * Retrieves the computed upgrades.
  374. *
  375. * Can be described as:
  376. * $upgrades = [
  377. * [
  378. * unit (Unit),
  379. * upgrade = [
  380. * [
  381. * rune (Rune),
  382. * enchant = [(Enchantment)]
  383. * ]
  384. * ]
  385. * ]
  386. * ]
  387. *
  388. * @return mixed[] Upgrades to show.
  389. */
  390. public function get_upgrades(){
  391. return $this->upgrades;
  392. }
  393. /**
  394. * Retrieves the page filters.
  395. *
  396. * @return mixed[] Page filtes
  397. */
  398. public function get_filters(){
  399. return $this->filters;
  400. }
  401. /**
  402. * Retrieves one filter.
  403. *
  404. * @param string $key
  405. * @return mixed Filter value, null if if doesn't exist.
  406. */
  407. public function get_filter($key){
  408. if (array_key_exists($key, $this->filters)){
  409. return $this->filters[$key];
  410. }
  411. else{
  412. return null;
  413. }
  414. }
  415. }