* @license https://www.gnu.org/licenses/gpl-3.0.en.html GNU General Public License V3 * @package SWDB */ require_once(PATH::PAGE . "Page.php"); require_once(PATH::ENTITY . "Unit.php"); require_once(PATH::ENTITY . "Rune.php"); require_once(PATH::ENTITY . "Enchantment.php"); /** * Upgradeable runes report page model. * * @category Page * @todo Some filters are not implemented (enchantment type, teams...) */ class Report_Rune_Enchantment_Page extends Page{ /** * @var mixed[] List of available upgrades. */ private $upgrades = []; /** * @var mixed[] Default filter values. */ private $filters = [ "MONSTER_NAME" => "", "MONSTER_MIN_STARS" => 5, "MONSTER_MAX_STARS" => 6, "MONSTER_IN_STORAGE" => false, "TEAM" => false, "RUNE_MIN_STARS" => 5, "RUNE_MAX_STARS" => 6, "RUNE_MIN_LEVEL" => 0, "RUNE_MAX_LEVEL" => 15, "RUNE_MIN_QUALITY" => QUALITY_ID::HERO, "RUNE_MAX_QUALITY" => QUALITY_ID::LEGEND, "RUNE_MIN_ORIGINAL_QUALITY" => QUALITY_ID::HERO, "RUNE_MAX_ORIGINAL_QUALITY" => QUALITY_ID::LEGEND, "RUNE_MIN_EFFICIENCY" => 0, "RUNE_MAX_EFFICIENCY" => 100, "RUNE_MIN_MAX_EFFICIENCY" => 0, "RUNE_MAX_MAX_EFFICIENCY" => 100, "RUNE_SLOT" => [], "GRIND" => 1, "GRIND_MIN_QUALITY" => QUALITY_ID::RARE, "GRIND_STAT" => [ RUNE_STAT_ID::HP_P, RUNE_STAT_ID::ATK_P, RUNE_STAT_ID::DEF_P, RUNE_STAT_ID::SPD, RUNE_STAT_ID::CRD, RUNE_STAT_ID::CRR, RUNE_STAT_ID::ACC ], "GEM" => 1, "GEM_MIN_QUALITY" => QUALITY_ID::RARE, "GEM_STAT_FROM" => [ RUNE_STAT_ID::HP, RUNE_STAT_ID::ATK, RUNE_STAT_ID::DEF, RUNE_STAT_ID::RES ], "GEM_STAT_TO" => [ RUNE_STAT_ID::HP_P, RUNE_STAT_ID::ATK_P, RUNE_STAT_ID::DEF_P, RUNE_STAT_ID::SPD, RUNE_STAT_ID::CRD, RUNE_STAT_ID::CRR, RUNE_STAT_ID::ACC ] ]; /** * Constructor. * * Retrieves the data and initializes the variables. */ public function __construct(){ parent::__construct(); $this->set_public(true); $this->set_view("report_rune_enchantment.php"); $this->set_title("Rune enchantment"); $this->set_description("Find runes that can be upgraded via enchantments"); $this->set_canonical("player/" . get_context()->get_player()->get_id() . "/report/rune_enchantment//"); $this->add_css("report_rune_enchantment.css"); $prev_monster = ""; $prev_rune = ""; $upgrade = null; $rupgrade = null; $this->parse_filters(); $result_set = $this->prepare_statement()->execute(); while ($result = $result_set->fetchArray(SQLITE3_ASSOC)){ if ($result["unit"] != $prev_monster){ if ($prev_rune != ""){ array_push($upgrade["upgrade"], $rupgrade); } if ($prev_monster != ""){ array_push($this->upgrades, $upgrade); } $prev_monster = $result["unit"]; $prev_rune = ""; $upgrade = [ "unit" => new Unit($result["unit"]), "upgrade" => [], ]; $rupgrade = [ "rune" => new Rune($result["rune"]), "enchantment" => [], ]; } if ($result["rune"] != $prev_rune){ if ($prev_rune != ""){ array_push($upgrade["upgrade"], $rupgrade); } $prev_rune = $result["rune"]; $rupgrade = [ "rune" => new Rune($result["rune"]), "enchantment" => [], ]; } $enchantment= new Enchantment($result["enchantment"]); array_push($rupgrade["enchantment"], $enchantment); } // Last entries array_push($upgrade["upgrade"], $rupgrade); array_push($this->upgrades, $upgrade); $this->set_code(200); $this->set_message("OK"); } /** * Parses the filters passed in the request and sets $filters. * Filters must be in $_GET, nd the available ones are max_stars (1-6), * min_stars (1-6) and in_storage (on/off). */ private function parse_filters(){ // Monster if (isset($_GET["monster_min_stars"]) && intval($_GET["monster_min_stars"]) > 0 && intval($_GET["monster_min_stars"]) < 7){ $this->filters["MONSTER_MIN_STARS"] = $_GET["monster_min_stars"]; } if (isset($_GET["monster_max_stars"]) && intval($_GET["monster_max_stars"]) > 0 && intval($_GET["monster_max_stars"]) < 7){ $this->filters["MONSTER_MAX_STARS"] = $_GET["monster_max_stars"]; } if (isset($_GET["monster_in_storage"]) && $_GET["monster_in_storage"] == "on"){ $this->filters["MONSTER_IN_STORAGE"] = true; } else{ $this->filters["MONSTER_IN_STORAGE"] = false; } if (isset($_GET["monster_name"]) && strlen($_GET["monster_name"]) > 0){ $this->filters["MONSTER_NAME"] = SQLite3::escapeString($_GET["monster_name"]); } // Runes if (isset($_GET["rune_min_stars"]) && intval($_GET["rune_min_stars"]) > 0 && intval($_GET["rune_min_stars"]) < 7){ $this->filters["RUNE_MIN_STARS"] = $_GET["rune_min_stars"]; } if (isset($_GET["rune_max_stars"]) && intval($_GET["rune_max_stars"]) > 0 && intval($_GET["rune_max_stars"]) < 7){ $this->filters["RUNE_MAX_STARS"] = $_GET["rune_max_stars"]; } if (isset($_GET["rune_min_level"]) && intval($_GET["rune_min_level"]) >= 0 && intval($_GET["rune_min_level"]) <= 15){ $this->filters["RUNE_MIN_LEVEL"] = $_GET["rune_min_level"]; } if (isset($_GET["rune_max_level"]) && intval($_GET["rune_max_level"]) >= 0 && intval($_GET["rune_max_level"]) <= 15){ $this->filters["RUNE_MAX_LEVEL"] = $_GET["rune_max_level"]; } if (isset($_GET["rune_min_quality"]) && intval($_GET["rune_min_quality"]) >= QUALITY_ID::NORMAL && intval($_GET["rune_min_quality"]) <= QUALITY_ID::LEGEND){ $this->filters["RUNE_MIN_QUALITY"] = $_GET["rune_min_quality"]; } if (isset($_GET["rune_max_quality"]) && intval($_GET["rune_max_quality"]) >= QUALITY_ID::NORMAL && intval($_GET["rune_max_quality"]) <= QUALITY_ID::LEGEND){ $this->filters["RUNE_MAX_QUALITY"] = $_GET["rune_max_quality"]; } 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){ $this->filters["RUNE_MIN_ORIGINAL_QUALITY"] = $_GET["rune_min_original_quality"]; } 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){ $this->filters["RUNE_MAX_ORIGINAL_QUALITY"] = $_GET["rune_max_original_quality"]; } if (isset($_GET["rune_min_efficiency"]) && intval($_GET["rune_min_efficiency"]) >= 0 && intval($_GET["rune_min_efficiency"]) <= 100){ $this->filters["RUNE_MIN_EFFICIENCY"] = $_GET["rune_min_efficiency"]; } if (isset($_GET["rune_max_efficiency"]) && intval($_GET["rune_max_efficiency"]) >= 0 && intval($_GET["rune_max_efficiency"]) <= 100){ $this->filters["RUNE_MAX_EFFICIENCY"] = $_GET["rune_max_efficiency"]; } if (isset($_GET["rune_min_max_efficiency"]) && intval($_GET["rune_min_max_efficiency"]) >= 0 && intval($_GET["rune_min_max_efficiency"]) <= 100){ $this->filters["RUNE_MIN_MAX_EFFICIENCY"] = $_GET["rune_min_max_efficiency"]; } if (isset($_GET["rune_max_max_efficiency"]) && intval($_GET["rune_max_max_efficiency"]) >= 0 && intval($_GET["rune_max_max_efficiency"]) <= 100){ $this->filters["RUNE_MAX_MAX_EFFICIENCY"] = $_GET["rune_max_max_efficiency"]; } if (isset($_GET["rune_slot"])){ $slots = $_GET["rune_slot"]; foreach ($slots as $slot){ if (intval($slot) >= 1 && intval($slot) < 7){ array_push($this->filters["RUNE_SLOT"], intval($slot)); } } } // Grindstones if (isset($_GET["grind_min_quality"]) && intval($_GET["grind_min_quality"]) >= QUALITY_ID::NORMAL && intval($_GET["grind_min_quality"]) < QUALITY_ID::LEGEND){ $this->filters["GRIND_MIN_QUALITY"] = $_GET["grind_min_quality"]; } if (isset($_GET["grind_stat"])){ $stats = $_GET["grind_stat"]; $this->filters["GRIND_STAT"] = []; foreach ($stats as $stat){ array_push($this->filters["GRIND_STAT"], intval($stat)); } } if (isset($_GET["gem_stat_from"])){ $stats = $_GET["gem_stat_from"]; $this->filters["GEM_STAT_FROM"] = []; foreach ($stats as $stat){ array_push($this->filters["GEM_STAT_FROM"], intval($stat)); } } if (isset($_GET["gem_stat_to"])){ $stats = $_GET["gem_stat_to"]; $this->filters["GEM_STAT_TO"] = []; foreach ($stats as $stat){ array_push($this->filters["GEM_STAT_TO"], intval($stat)); } } return; } /** * Prepares the statement to execute against the database using the filter values. * * @return SQLite3Stmt prepared statement. */ private function prepare_statement(){ // Common items $query = " SELECT DISTINCT unit.id AS unit, rune.id AS rune, enchantment.id AS enchantment FROM unit, monster, rune, unit_rune, enchantment, enchantment_type WHERE unit.player = :player AND rune.player = unit.player AND enchantment.player = unit.player AND unit.id = unit_rune.unit AND rune.id = unit_rune.rune AND unit_rune.rta = :rta AND unit.monster = monster.id AND enchantment.type = enchantment_type.id AND -- RUNE FILTERS rune.stars BETWEEN :rune_min_stars AND :rune_max_stars AND rune.quality BETWEEN :rune_min_quality AND :rune_max_quality AND rune.original_quality BETWEEN :rune_min_original_quality AND :rune_max_original_quality AND rune.level BETWEEN :rune_min_level AND :rune_max_level AND rune.efficiency BETWEEN :rune_min_efficiency AND :rune_max_efficiency AND rune.max_efficiency BETWEEN :rune_min_max_efficiency AND :rune_max_max_efficiency AND (rune.type = enchantment.rune OR enchantment_type.inmemorial = 1) AND enchantment_type.ancient = rune.ancient AND -- No enchantments with the same sat as the runes main or innate enchantment.stat NOT IN ( SELECT stat FROM rune_stat WHERE rune_stat.rune = rune.id AND ( rune_stat.slot = :stat_main OR rune_stat.slot = :stat_innate ) ) AND ( -- TYPE SWITCH ( -- BEGIN GRINDSTONE BLOCK enchantment_type.gem = 0 AND enchantment.stat IN (SELECT stat FROM rune_stat WHERE rune_stat.rune = rune.id) AND enchantment.quality >= :grind_min_quality "; // GRindstone stats if (count($this->filters["GRIND_STAT"]) > 0){ $query .= " AND enchantment.stat IN ("; for ($i = 0; $i < sizeof($this->filters["GRIND_STAT"]); $i ++){ $query .= ":grind_stat_$i, "; } $query = rtrim($query, ", ") . ") "; } $query .= " ) -- END GRINDSTONE BLOCK OR ( -- BEGIN GEM BLOCK enchantment_type.gem = 1 AND enchantment.stat NOT IN (SELECT stat FROM rune_stat WHERE rune_stat.rune = rune.id) AND enchantment.quality >= :gem_min_quality "; // Gem stats from if (count($this->filters["GEM_STAT_TO"]) > 0){ $query .= " AND enchantment.stat IN ("; for ($i = 0; $i < sizeof($this->filters["GEM_STAT_TO"]); $i ++){ $query .= ":gem_stat_to_$i, "; } $query = rtrim($query, ", ") . ") "; } //Gem stats from if (count($this->filters["GEM_STAT_FROM"]) > 0){ //$query .= " AND enchantment.stat IN ("; $query .= " AND rune.id IN ( SELECT DISTINCT rune FROM rune_stat WHERE rune_stat.rune = rune.id AND stat IN ( "; for ($i = 0; $i < sizeof($this->filters["GEM_STAT_FROM"]); $i ++){ $query .= ":gem_stat_from_$i, "; } $query = rtrim($query, ", ") . ")) "; } $query .= " ) -- END GEM BLOCK ) -- END SWITCH "; // Monster name if ($this->filters["MONSTER_NAME"] != ""){ $query .= " AND upper(monster.name) LIKE upper(:monster_name) " ; } // Monsters in storage if (! $this->filters["MONSTER_IN_STORAGE"]){ $query .= "AND unit.building <> :storage_building "; } // Rune slot if (count($this->filters["RUNE_SLOT"]) > 0){ $query .= " AND rune.slot IN ("; for ($i = 0; $i < sizeof($this->filters["RUNE_SLOT"]); $i ++){ $query .= ":rune_slot_$i, "; } $query = rtrim($query, ", ") . ") "; } $statement = get_context()->get_db()->prepare($query); $statement->bindValue(":player", get_context()->get_player()->get_id(), SQLITE3_TEXT); $statement->bindValue(":rta", get_context()->get_game_mode(), SQLITE3_TEXT); $statement->bindValue(":rune_min_stars", $this->filters["RUNE_MIN_STARS"], SQLITE3_INTEGER); $statement->bindValue(":rune_max_stars", $this->filters["RUNE_MAX_STARS"], SQLITE3_INTEGER); $statement->bindValue(":rune_min_quality", $this->filters["RUNE_MIN_QUALITY"], SQLITE3_INTEGER); $statement->bindValue(":rune_max_quality", $this->filters["RUNE_MAX_QUALITY"], SQLITE3_INTEGER); $statement->bindValue(":rune_min_original_quality", $this->filters["RUNE_MIN_ORIGINAL_QUALITY"], SQLITE3_INTEGER); $statement->bindValue(":rune_max_original_quality", $this->filters["RUNE_MAX_ORIGINAL_QUALITY"], SQLITE3_INTEGER); $statement->bindValue(":rune_min_level", $this->filters["RUNE_MIN_LEVEL"], SQLITE3_INTEGER); $statement->bindValue(":rune_max_level", $this->filters["RUNE_MAX_LEVEL"], SQLITE3_INTEGER); $statement->bindValue(":rune_min_efficiency", $this->filters["RUNE_MIN_EFFICIENCY"], SQLITE3_FLOAT); $statement->bindValue(":rune_max_efficiency", $this->filters["RUNE_MAX_EFFICIENCY"], SQLITE3_FLOAT); $statement->bindValue(":rune_min_max_efficiency", $this->filters["RUNE_MIN_MAX_EFFICIENCY"], SQLITE3_FLOAT); $statement->bindValue(":rune_max_max_efficiency", $this->filters["RUNE_MAX_MAX_EFFICIENCY"], SQLITE3_FLOAT); $statement->bindValue(":monster_name", "%" . $this->filters["MONSTER_NAME"] . "%", SQLITE3_TEXT); $statement->bindValue(":storage_building", BUILDING_ID::MONSTER_STORAGE, SQLITE3_INTEGER); for ($i = 0; $i < sizeof($this->filters["RUNE_SLOT"]); $i ++){ $statement->bindValue(":rune_slot_$i", $this->filters["RUNE_SLOT"][$i], SQLITE3_INTEGER); } $statement->bindValue(":stat_main", RUNE_STAT_SLOT_ID::MAIN, SQLITE3_INTEGER); $statement->bindValue(":stat_innate", RUNE_STAT_SLOT_ID::INNATE, SQLITE3_INTEGER); $statement->bindValue(":grind_min_quality", $this->filters["GRIND_MIN_QUALITY"], SQLITE3_INTEGER); for ($i = 0; $i < sizeof($this->filters["GRIND_STAT"]); $i ++){ $statement->bindValue(":grind_stat_$i", $this->filters["GRIND_STAT"][$i], SQLITE3_INTEGER); } $statement->bindValue(":gem_min_quality", $this->filters["GEM_MIN_QUALITY"], SQLITE3_INTEGER); for ($i = 0; $i < sizeof($this->filters["GEM_STAT_TO"]); $i ++){ $statement->bindValue(":gem_stat_to_$i", $this->filters["GEM_STAT_TO"][$i], SQLITE3_INTEGER); } for ($i = 0; $i < sizeof($this->filters["GEM_STAT_FROM"]); $i ++){ $statement->bindValue(":gem_stat_from_$i", $this->filters["GEM_STAT_FROM"][$i], SQLITE3_INTEGER); } return $statement; } /** * Retrieves the computed upgrades. * * Can be described as: * $upgrades = [ * [ * unit (Unit), * upgrade = [ * [ * rune (Rune), * enchant = [(Enchantment)] * ] * ] * ] * ] * * @return mixed[] Upgrades to show. */ public function get_upgrades(){ return $this->upgrades; } /** * Retrieves the page filters. * * @return mixed[] Page filtes */ public function get_filters(){ return $this->filters; } /** * Retrieves one filter. * * @param string $key * @return mixed Filter value, null if if doesn't exist. */ public function get_filter($key){ if (array_key_exists($key, $this->filters)){ return $this->filters[$key]; } else{ return null; } } }