* @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 . "Effect.php"); /** * Unit list page model. * * @category Page */ class Units_Page extends Page{ /** * @var Unit[] Units to show. */ private $units = []; /** * @var mixed[] Default filter values. */ private $filters = [ "ELEMENT" => -1, "NAME" => "", "MIN_STARS" => 1, "MAX_STARS" => 6, "IN_STORAGE" => false, "WITHOUT_RUNES" => false, "EFFECT" => [], "EFFECT_OPTION" => "any" ]; /** * @var Effect[] All availabe skill effects, for the filter selector. */ private $effects = []; /** * Constructor. * * Retrieves the data and initializes the variables. */ public function __construct(){ parent::__construct(); $this->set_public(true); $this->set_view("units.php"); $this->set_title("Units"); $this->set_description(get_context()->get_player()->get_name() . "'s units"); $this->set_canonical("player/" . get_context()->get_player()->get_id() . "/units/"); $this->add_css("units.css"); $this->parse_filters(); $result_set = $this->prepare_statement()->execute(); while ($result = $result_set->fetchArray(SQLITE3_ASSOC)){ array_push($this->units, new Unit($result["id"])); } // Get skill effects $s_eff = "SELECT id FROM effect ORDER BY is_buff DESC"; $q_eff = get_context()->get_db()->query($s_eff); while ($r_eff = $q_eff->fetchArray(SQLITE3_ASSOC)){ array_push($this->effects, new Effect($r_eff["id"])); } $this->set_code(200); $this->set_message("OK"); } /** * Parses the request looking for the selected filters, validates them * and adds them to the $filters array. */ private function parse_filters(){ if (isset($_GET["element"]) && APPLICATION::valid_id("ELEMENT_ID", strtoupper($_GET["element"]))){ $this->filters["ELEMENT"] = $_GET["element"]; } if (isset($_GET["name"]) && strlen($_GET["name"]) > 0){ $this->filters["NAME"] = SQLite3::escapeString($_GET["name"]); } if (isset($_GET["min_stars"]) && intval($_GET["min_stars"]) > 0 && intval($_GET["min_stars"]) <= 6){ $this->filters["MIN_STARS"] = $_GET["min_stars"]; } if (isset($_GET["max_stars"]) && intval($_GET["max_stars"]) > 0 && intval($_GET["max_stars"]) <= 6){ $this->filters["MAX_STARS"] = $_GET["max_stars"]; } if (isset($_GET["in_storage"]) && $_GET["in_storage"] == "on"){ $this->filters["IN_STORAGE"] = true; } else{ $this->filters["IN_STORAGE"] = false; } if (isset($_GET["without_runes"]) && $_GET["without_runes"] == "on"){ $this->filters["WITHOUT_RUNES"] = true; } if (isset($_GET["effect"])){ $effects = $_GET["effect"]; foreach ($effects as $effect){ if (intval($effect) > 0){ array_push($this->filters["EFFECT"], intval($effect)); } } } if (isset($_GET["effect_option"]) && ($_GET["effect_option"] == "and" || $_GET["effect_option"] == "or")){ $this->filters["EFFECT_OPTION"] = $_GET["effect_option"]; } 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 unit.id AS id FROM unit, monster WHERE unit.player = :player AND unit.monster = monster.id AND unit.stars BETWEEN :min_stars AND :max_stars "; if (APPLICATION::valid_id("ELEMENT_ID", $this->filters["ELEMENT"])){ $query .= " AND monster.element = :element "; } if ($this->filters["NAME"] != ""){ $query .= " AND upper(monster.name) LIKE upper(:name) "; } if (! $this->filters["IN_STORAGE"]){ $query .= " AND unit.building <> :storage_building "; } if (!$this->filters["WITHOUT_RUNES"]){ $query .= " AND unit.id IN (SELECT DISTINCT unit FROM unit_rune WHERE rta = :rta) "; } if (sizeof($this->filters["EFFECT"]) > 0){ if ($this->filters["EFFECT_OPTION"] == "and"){ for ($i = 0; $i < sizeof($this->filters["EFFECT"]); $i ++){ $query .= " AND monster.id IN ( SELECT DISTINCT monster FROM monster_skill, skill_effect WHERE monster_skill.skill = skill_effect.skill AND skill_effect.effect = :effect_$i ) "; } } elseif ($this->filters["EFFECT_OPTION"] == "or"){ $query .= " AND ( "; for ($i = 0; $i < sizeof($this->filters["EFFECT"]); $i ++){ $query .= " monster.id IN ( SELECT DISTINCT monster FROM monster_skill, skill_effect WHERE monster_skill.skill = skill_effect.skill AND skill_effect.effect = :effect_$i ) OR "; } $query = rtrim($query, " OR ") . ") "; } } $query .= " ORDER BY stars DESC, level DESC, element = :fire DESC, element = :water DESC, element = :wind DESC, element = :light DESC, element = :dark DESC "; $statement = get_context()->get_db()->prepare($query); $statement->bindValue(":player", get_context()->get_player()->get_id(), SQLITE3_TEXT); $statement->bindValue(":min_stars", $this->filters["MIN_STARS"], SQLITE3_INTEGER); $statement->bindValue(":max_stars", $this->filters["MAX_STARS"], SQLITE3_INTEGER); $statement->bindValue(":element", $this->filters["ELEMENT"], SQLITE3_INTEGER); $statement->bindValue(":name", "%" . $this->filters["NAME"] . "%", SQLITE3_TEXT); $statement->bindValue(":storage_building", BUILDING_ID::MONSTER_STORAGE, SQLITE3_INTEGER); $statement->bindValue(":rta", get_context()->get_game_mode(), SQLITE3_INTEGER); for ($i = 0; $i < sizeof($this->filters["EFFECT"]); $i ++){ $statement->bindValue(":effect_$i", $this->filters["EFFECT"][$i], SQLITE3_INTEGER); } $statement->bindValue(":fire", ELEMENT_ID::FIRE, SQLITE3_INTEGER); $statement->bindValue(":water", ELEMENT_ID::WATER, SQLITE3_INTEGER); $statement->bindValue(":wind", ELEMENT_ID::WIND, SQLITE3_INTEGER); $statement->bindValue(":light", ELEMENT_ID::LIGHT, SQLITE3_INTEGER); $statement->bindValue(":dark", ELEMENT_ID::DARK, SQLITE3_INTEGER); return $statement; } /** * 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; } } /** * Retrieves the selection of units. * * @return Unit[] Unit to show on the page. */ public function get_units(){ return $this->units; } /** * Retrieves all existing skill effects. * * @return Effect[] Every skill effects. */ public function get_effects(){ return $this->effects; } }