Compare commits

..

No commits in common. "master" and "v2.0" have entirely different histories.
master ... v2.0

559 changed files with 11346 additions and 16255 deletions

17
.gitignore vendored
View file

@ -1,5 +1,10 @@
# Git
*.orig
# cache
/cache/*
/cache/template/*
/cache/alphaMaps/*
/cache/setup/*
# extract from MPQ
/setup/mpqdata/*
@ -12,8 +17,10 @@
/static/widgets/searchbox.js
/static/widgets/searchbox/searchbox.html
/static/download/searchplugins/aowow.xml
/config/*
/config/config.php
/datasets/*
!/datasets/zones
# /datasets/item-scaling
# extracted sounds
/static/wowsounds/*
@ -23,7 +30,7 @@
/static/images/wow/icons/medium/*
/static/images/wow/icons/small/*
/static/images/wow/icons/tiny/*
!/static/images/wow/icons/tiny/quest_[end|start]
!/static/images/wow/icons/tiny/quest_*
/static/images/wow/hunterpettalents/*
/static/images/wow/Interface/*
/static/images/wow/loadingscreens/*
@ -43,7 +50,3 @@
/static/uploads/signatures/*
/static/uploads/temp/*
/static/uploads/guide/images/*
# composer
/includes/libs/*
composer.phar

View file

@ -26,10 +26,8 @@ AddDefaultCharset utf8
</IfModule>
# UHD screenshots can get pretty large (cannot be set in config)
<IfModule mod_php.c>
php_value upload_max_filesize 20M
php_value post_max_size 25M
</IfModule>
RewriteEngine on
# RewriteBase /~user/localPath/ # enable if the rules do not work, when they should

View file

@ -2,7 +2,7 @@
## Build Status
![fuck it ship it](https://forthebadge.com/badges/fuck-it-ship-it.svg)
![fuck it ship it](http://forthebadge.com/images/badges/fuck-it-ship-it.svg)
## Introduction
@ -27,8 +27,7 @@ Also, this project is not meant to be used for commercial purposes of any kind!
+ [Internationalization](https://www.php.net/manual/en/book.intl.php)
+ [GNU Multiple Precision](https://www.php.net/manual/en/book.gmp.php) (When using TrinityCore as auth source)
+ MySQL ≥ 5.7.0 OR MariaDB ≥ 10.6.4 OR similar
+ [Composer](https://getcomposer.org/download/)
+ [TDB 335.25101](https://github.com/TrinityCore/TrinityCore/releases/tag/TDB335.25101) including updates up to [TrinityCore/TrinityCore@f3b691d](https://github.com/TrinityCore/TrinityCore/commit/f3b691dcb085014ec3f0e2c60ab94fc9c00e8aa8) (no other other providers are supported at this time)
+ [TDB 335.21101](https://github.com/TrinityCore/TrinityCore/releases/tag/TDB335.21101) (no other other providers are supported at this time)
+ WIN: php.exe needs to be added to the `PATH` system variable, if it isn't already.
+ Tools require cmake: Please refer to the individual repositories for detailed information
+ [MPQExtractor](https://github.com/Sarjuuk/MPQExtractor) / [FFmpeg](https://ffmpeg.org/download.html) / (optional: [BLPConverter](https://github.com/Sarjuuk/BLPConverter))
@ -39,7 +38,7 @@ audio processing may require [lame](https://sourceforge.net/projects/lame/files/
#### Highly Recommended
+ setting the following configuration values on your TrinityCore server (and running it once) will greatly increase the accuracy of spawn points
+ setting the following configuration values on your TrinityCore server will greatly increase the accuracy of spawn points
> Calculate.Creature.Zone.Area.Data = 1
> Calculate.Gameobject.Zone.Area.Data = 1
@ -51,10 +50,8 @@ audio processing may require [lame](https://sourceforge.net/projects/lame/files/
`git clone git@github.com:Sarjuuk/MPQExtractor.git MPQExtractor`
#### 2. Prepare the database
Ensure that the account you are going to use has **full** access on the database AoWoW is going to occupy and ideally only **read** access on the world and optionally auth and characters databases you are going to reference.
Import files 01 - 03 from `setup/sql/` in order into the AoWoW database `mysql --default-character-set=utf8 -p {your-db-here} < setup/sql/01-db_structure.sql`, etc.
**Optional**: If you are using MySQL ≥ 8.4.0 and want to support fulltext search for locale zhCN, additionally import `setup/sql/04-db_optional_mysql_only.sql`. Enables this in settings after AoWoW has been set up.
Ensure that the account you are going to use has **full** access on the database AoWoW is going to occupy and ideally only **read** access on the world database you are going to reference.
Import files 01 - 03 from `setup/sql/` in order into the AoWoW database `mysql -p {your-db-here} < setup/sql/01-db_structure.sql`, etc.
#### 3. Server created files
See to it, that the web server is able to write the following directories and their children. If they are missing, the setup will create them with appropriate permissions
@ -85,17 +82,17 @@ Extract the following directories from the client archives into `setup/mpqdata/`
> \<localeCode>/Interface/FlavorImages
> \<localeCode>/Interface/Calendar/Holidays/
> \<localeCode>/Sound/
.. optionally (not used in AoWoW):
> \<localeCode>/Interface/Glues/Loadingscreens/
> \<localeCode>/Interface/Glues/Credits/
#### 5. Reencode the audio files
WAV-files need to be reencoded as `ogg/vorbis` and some MP3s may identify themselves as `application/octet-stream` instead of `audio/mpeg`.
* [example for WIN](https://gist.github.com/Sarjuuk/d77b203f7b71d191509afddabad5fc9f)
* [example for \*nix](https://gist.github.com/Sarjuuk/1f05ef2affe49a7e7ca0fad7b01c081d)
#### 6. Install dependencies with composer
`php composer.phar install --no-dev` on a project level composer install, or
`composer install --no-dev` on a system level composer install
#### 7. Run the initial setup from the CLI
#### 6. Run the initial setup from the CLI
`php aowow --setup`.
This should guide you through with minimal input required from your end, but will take some time though, especially compiling the zone-images. Use it to familiarize yourself with the other functions this setup has. Yes, I'm dead serious: *Go read the code!* It will help you understand how to configure AoWoW and keep it in sync with your world database.
When you've created your admin account you are done.
@ -104,10 +101,10 @@ When you've created your admin account you are done.
## Troubleshooting
Q: The Page appears white, without any styles.
A: The static content is not being displayed. You are either using SSL and AoWoW is unable to detect it or STATIC_HOST is not defined properly. Either way this can be fixed via config `php aowow --configure`
A: The static content is not being displayed. You are either using SSL and AoWoW is unable to detect it or STATIC_HOST is not defined properly. Either way this can be fixed via config `php aowow --siteconfig`
Q: Fatal error: Can't inherit abstract function \<functionName> (previously declared abstract in \<className>) in \<path>
A: You are using multiple cache optimization modules for php that are in conflict with each other. (Zend OPcache, XCache, ..) Disable all but one.
A: You are using cache optimization modules for php, that are in conflict with each other. (Zend OPcache, XCache, ..) Disable all but one.
Q: Some generated images appear distorted or have alpha-channel issues.
A: Image compression is beyond my understanding, so i am unable to fix these issues within the blpReader.
@ -121,7 +118,7 @@ Q: I'm getting random javascript errors!
A: Some server configurations or external services (like Cloudflare) come with modules, that automatically minify js and css files. Sometimes they break in the process. Disable the module in this case.
Q: Some search results within the profiler act rather strange. How does it work?
A: Whenever you try to view a new character, AoWoW needs to fetch it first. Since the data is structured for the needs of TrinityCore and not for easy viewing, AoWoW needs to save and restructure it locally. To this end, every char request is placed in a queue. While the queue is not empty, a single instance of `prQueue` is run in the background as not to overwhelm the characters database with requests. This also means complex search queries can't be run against the characters database and have to use the incomplete/outdated cached profiles of AoWoW.
A: Whenever you try to view a new character, AoWoW needs to fetch it first. Since the data is structured for the needs of TrinityCore and not for easy viewing, AoWoW needs to save and restructure it locally. To this end, every char request is placed in a queue. While the queue is not empty, a single instance of `prQueue` is run in the background as not to overwhelm the characters database with requests. This also means, some more exotic search queries can't be run against the characters database and have to use the incomplete/outdated cached profiles of AoWoW.
Q: Screenshot upload fails, because the file size is too large and/or the subdirectories are visible from the web!
A: That's a web server configuration issue. If you are using Apache you may need to [enable the use of .htaccess](http://httpd.apache.org/docs/2.4/de/mod/core.html#allowoverride). Other servers require individual configuration.
@ -141,4 +138,4 @@ A: A search is only conducted against the currently used locale. You may have on
Said website with the red smiling rocket, for providing this beautiful website!
Please do not regard this project as blatant rip-off, rather as "We do really liked your presentation, but since time and content progresses, you are sadly no longer supplying the data we need".
![uses badges](https://forthebadge.com/badges/uses-badges.svg)
![uses badges](http://forthebadge.com/images/badges/uses-badges.svg)

3
aowow
View file

@ -9,9 +9,6 @@ if (PHP_SAPI === 'cli' && getcwd().DIRECTORY_SEPARATOR.'aowow' != __FILE__)
require_once 'includes/kernel.php';
require_once 'includes/setup/cli.class.php';
require_once 'includes/setup/timer.class.php';
require_once 'includes/setup/datatypes/primitives.php';
require_once 'includes/setup/files/binaryfile.class.php';
require_once 'includes/setup/files/dbcfile.class.php';
require_once 'setup/setup.php';

View file

@ -1,30 +0,0 @@
{
"name": "aowow/aowow",
"description": "Server and client database visualization for World of Warcraft/TrinityCore v3.3.5a, including community tools.",
"version": "2.0",
"type": "project",
"keywords": ["World of Warcraft", "wow", "database", "db", "frontend", "Wrath of the Lich King", "wotlk", "335a", "3.3.5a"],
"authors": [
{
"name": "Sarjuuk",
"role": "Developer"
}
],
"config": {
"vendor-dir": "includes/libs"
},
"require": {
"dibi/dibi": "^5.1",
"php": "8.2 - 8.4",
"ext-mbstring": "*",
"ext-simplexml": "*",
"ext-gd": "*",
"ext-mysqli": "*",
"ext-fileinfo": "*",
"ext-intl": "*"
},
"require-dev": {
"jfcherng/php-diff": "6.16",
"triggerhappy/mpq": "dev-master"
}
}

454
composer.lock generated
View file

@ -1,454 +0,0 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "25b289a987a7600746f0fd1f2491864b",
"packages": [
{
"name": "dibi/dibi",
"version": "v5.1.0",
"source": {
"type": "git",
"url": "https://github.com/dg/dibi.git",
"reference": "32b6976209859f61eb79380c5a8904ea33db47df"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dg/dibi/zipball/32b6976209859f61eb79380c5a8904ea33db47df",
"reference": "32b6976209859f61eb79380c5a8904ea33db47df",
"shasum": ""
},
"require": {
"php": "8.2 - 8.5"
},
"replace": {
"dg/dibi": "*"
},
"require-dev": {
"jetbrains/phpstorm-attributes": "^1.0",
"nette/di": "^3.1",
"nette/tester": "^2.5",
"phpstan/phpstan-nette": "^2.0@stable",
"tracy/tracy": "^2.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.1-dev"
}
},
"autoload": {
"psr-4": {
"Dibi\\": "src/Dibi"
},
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause",
"GPL-2.0-only",
"GPL-3.0-only"
],
"authors": [
{
"name": "David Grudl",
"homepage": "https://davidgrudl.com"
}
],
"description": "Dibi is Database Abstraction Library for PHP",
"homepage": "https://dibiphp.com",
"keywords": [
"access",
"database",
"dbal",
"mssql",
"mysql",
"odbc",
"oracle",
"pdo",
"postgresql",
"sqlite",
"sqlsrv"
],
"support": {
"issues": "https://github.com/dg/dibi/issues",
"source": "https://github.com/dg/dibi/tree/v5.1.0"
},
"time": "2025-08-06T22:26:19+00:00"
}
],
"packages-dev": [
{
"name": "chdemko/sorted-collections",
"version": "1.0.10",
"source": {
"type": "git",
"url": "https://github.com/chdemko/php-sorted-collections.git",
"reference": "d9cf7021e6fda1eb68b9f35caf99215327f6db76"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/chdemko/php-sorted-collections/zipball/d9cf7021e6fda1eb68b9f35caf99215327f6db76",
"reference": "d9cf7021e6fda1eb68b9f35caf99215327f6db76",
"shasum": ""
},
"require": {
"php": ">=8.2"
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.7",
"phpbench/phpbench": "^1.3",
"phpunit/phpunit": "^11.3",
"squizlabs/php_codesniffer": "^3.10"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"chdemko\\SortedCollection\\": "src/SortedCollection"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Christophe Demko",
"email": "chdemko@gmail.com",
"homepage": "https://chdemko.pagelab.univ-lr.fr/",
"role": "Developer"
}
],
"description": "Sorted Collections for PHP >= 8.1",
"homepage": "https://php-sorted-collections.readthedocs.io/en/latest/?badge=latest",
"keywords": [
"avl",
"collection",
"iterator",
"map",
"ordered",
"set",
"sorted",
"tree",
"treemap",
"treeset"
],
"support": {
"issues": "https://github.com/chdemko/php-sorted-collections/issues",
"source": "https://github.com/chdemko/php-sorted-collections/tree/1.0.10"
},
"time": "2024-08-04T14:31:40+00:00"
},
{
"name": "jfcherng/php-color-output",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/jfcherng/php-color-output.git",
"reference": "6c7bf16686cc6a291647fcb87491640a2d5edd20"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jfcherng/php-color-output/zipball/6c7bf16686cc6a291647fcb87491640a2d5edd20",
"reference": "6c7bf16686cc6a291647fcb87491640a2d5edd20",
"shasum": ""
},
"require": {
"php": ">=7.1.3"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.19",
"liip/rmt": "^1.6",
"phan/phan": "^2 || ^3 || ^4",
"phpunit/phpunit": ">=7 <10",
"squizlabs/php_codesniffer": "^3.5"
},
"type": "library",
"autoload": {
"psr-4": {
"Jfcherng\\Utility\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jack Cherng",
"email": "jfcherng@gmail.com"
}
],
"description": "Make your PHP command-line application colorful.",
"keywords": [
"ansi-colors",
"color",
"command-line",
"str-color"
],
"support": {
"issues": "https://github.com/jfcherng/php-color-output/issues",
"source": "https://github.com/jfcherng/php-color-output/tree/3.0.0"
},
"funding": [
{
"url": "https://www.paypal.me/jfcherng/5usd",
"type": "custom"
}
],
"time": "2021-05-27T02:45:54+00:00"
},
{
"name": "jfcherng/php-diff",
"version": "6.16.0",
"source": {
"type": "git",
"url": "https://github.com/jfcherng/php-diff.git",
"reference": "8b49edeba6e367df22977fca0f0324b4a99b78a0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jfcherng/php-diff/zipball/8b49edeba6e367df22977fca0f0324b4a99b78a0",
"reference": "8b49edeba6e367df22977fca0f0324b4a99b78a0",
"shasum": ""
},
"require": {
"jfcherng/php-color-output": "^3",
"jfcherng/php-mb-string": "^1.4.6 || ^2",
"jfcherng/php-sequence-matcher": "^3.2.10 || ^4",
"php": ">=7.4"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.8",
"liip/rmt": "^1.6",
"phan/phan": "^5",
"phpunit/phpunit": "^9",
"squizlabs/php_codesniffer": "^3.6"
},
"type": "library",
"autoload": {
"psr-4": {
"Jfcherng\\Diff\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Jack Cherng",
"email": "jfcherng@gmail.com"
},
{
"name": "Chris Boulton",
"email": "chris.boulton@interspire.com"
}
],
"description": "A comprehensive library for generating differences between two strings in multiple formats (unified, side by side HTML etc).",
"keywords": [
"diff",
"udiff",
"unidiff",
"unified diff"
],
"support": {
"issues": "https://github.com/jfcherng/php-diff/issues",
"source": "https://github.com/jfcherng/php-diff/tree/6.16.0"
},
"funding": [
{
"url": "https://www.paypal.me/jfcherng/5usd",
"type": "custom"
}
],
"time": "2024-03-05T08:44:05+00:00"
},
{
"name": "jfcherng/php-mb-string",
"version": "2.0.1",
"source": {
"type": "git",
"url": "https://github.com/jfcherng/php-mb-string.git",
"reference": "8407bfefde47849c9e7c9594e6de2ac85a0f845d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jfcherng/php-mb-string/zipball/8407bfefde47849c9e7c9594e6de2ac85a0f845d",
"reference": "8407bfefde47849c9e7c9594e6de2ac85a0f845d",
"shasum": ""
},
"require": {
"ext-iconv": "*",
"php": ">=8.1"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3",
"phan/phan": "^5",
"phpunit/phpunit": "^9 || ^10"
},
"suggest": {
"ext-iconv": "Either \"ext-iconv\" or \"ext-mbstring\" is requried.",
"ext-mbstring": "Either \"ext-iconv\" or \"ext-mbstring\" is requried."
},
"type": "library",
"autoload": {
"psr-4": {
"Jfcherng\\Utility\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jack Cherng",
"email": "jfcherng@gmail.com"
}
],
"description": "A high performance multibytes sting implementation for frequently reading/writing operations.",
"support": {
"issues": "https://github.com/jfcherng/php-mb-string/issues",
"source": "https://github.com/jfcherng/php-mb-string/tree/2.0.1"
},
"funding": [
{
"url": "https://www.paypal.me/jfcherng/5usd",
"type": "custom"
}
],
"time": "2023-04-17T14:23:16+00:00"
},
{
"name": "jfcherng/php-sequence-matcher",
"version": "4.0.3",
"source": {
"type": "git",
"url": "https://github.com/jfcherng/php-sequence-matcher.git",
"reference": "d2038ac29627340a7458609072a8ba355e80ec5b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jfcherng/php-sequence-matcher/zipball/d2038ac29627340a7458609072a8ba355e80ec5b",
"reference": "d2038ac29627340a7458609072a8ba355e80ec5b",
"shasum": ""
},
"require": {
"php": ">=8.1"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3",
"phan/phan": "^5",
"phpunit/phpunit": "^9 || ^10",
"squizlabs/php_codesniffer": "^3.7"
},
"type": "library",
"autoload": {
"psr-4": {
"Jfcherng\\Diff\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Jack Cherng",
"email": "jfcherng@gmail.com"
},
{
"name": "Chris Boulton",
"email": "chris.boulton@interspire.com"
}
],
"description": "A longest sequence matcher. The logic is primarily based on the Python difflib package.",
"support": {
"issues": "https://github.com/jfcherng/php-sequence-matcher/issues",
"source": "https://github.com/jfcherng/php-sequence-matcher/tree/4.0.3"
},
"funding": [
{
"url": "https://www.paypal.me/jfcherng/5usd",
"type": "custom"
}
],
"time": "2023-05-21T07:57:08+00:00"
},
{
"name": "triggerhappy/mpq",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/cipherxof/PHP-MPQ.git",
"reference": "628ca77b307d1cdf28b76da9750f3c8cbe958f49"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/cipherxof/PHP-MPQ/zipball/628ca77b307d1cdf28b76da9750f3c8cbe958f49",
"reference": "628ca77b307d1cdf28b76da9750f3c8cbe958f49",
"shasum": ""
},
"require": {
"chdemko/sorted-collections": "1.0.*@dev",
"php": ">=5.4"
},
"require-dev": {
"phpunit/phpunit": "5.2.*"
},
"default-branch": true,
"type": "project",
"autoload": {
"psr-4": {
"TriggerHappy\\MPQ\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-3.0-only"
],
"description": "Handle the MPQ (MoPaQ) format natively from PHP with support for Warcraft III & Starcraft II.",
"keywords": [
"MPQ",
"archive",
"mopaq",
"php-mpq",
"phpmpq",
"triggerhappy"
],
"support": {
"issues": "https://github.com/cipherxof/PHP-MPQ/issues",
"source": "https://github.com/cipherxof/PHP-MPQ/tree/master"
},
"time": "2018-07-31T04:22:01+00:00"
}
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
"triggerhappy/mpq": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": "8.2 - 8.4",
"ext-mbstring": "*",
"ext-simplexml": "*",
"ext-gd": "*",
"ext-mysqli": "*",
"ext-fileinfo": "*",
"ext-intl": "*"
},
"platform-dev": {},
"plugin-api-version": "2.9.0"
}

View file

@ -4,7 +4,7 @@ if (!defined('AOWOW_REVISION'))
die('illegal access');
function extAuth(string &$usernameOrEmail, #[\SensitiveParameter] string $password, int &$userId = 0, int &$userGroup = -1) : int
function extAuth(string &$usernameOrEmail, string $password, int &$userId = 0, int &$userGroup = -1) : int
{
/*
insert some auth mechanism here

View file

@ -13,11 +13,11 @@ class AboutusBaseResponse extends TemplateResponse
protected ?int $activeTab = parent::TAB_MORE;
protected array $breadcrumb = [2, 0];
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
parent::__construct($rawParam);
parent::__construct($pageParam);
if ($rawParam)
if ($pageParam)
$this->generateError();
}

View file

@ -42,19 +42,19 @@ class AccountBaseResponse extends TemplateResponse
public ?array $bans;
public function __construct($rawParam)
public function __construct($pageParam)
{
if (!User::isLoggedIn())
$this->forwardToSignIn('account');
parent::__construct($rawParam);
parent::__construct($pageParam);
}
protected function generate() : void
{
array_unshift($this->title, Lang::account('settings'));
$user = DB::Aowow()->selectRow('SELECT `debug`, `email`, `description`, `avatar`, `wowicon`, `renameCooldown` FROM ::account WHERE `id` = %i', User::$id);
$user = DB::Aowow()->selectRow('SELECT `debug`, `email`, `description`, `avatar`, `wowicon`, `renameCooldown` FROM ?_account WHERE `id` = ?d', User::$id);
Lang::sort('game', 'ra');
@ -65,11 +65,11 @@ class AccountBaseResponse extends TemplateResponse
/* Ban Popup */
/*************/
$b = DB::Aowow()->selectAssoc(
$b = DB::Aowow()->select(
'SELECT ab.`end` AS "0", ab.`reason` AS "1", a.`username` AS "2"
FROM ::account_banned ab
LEFT JOIN ::account a ON a.`id` = ab.`staffId`
WHERE ab.`userId` = %i AND ab.`typeMask` & %i AND (ab.`end` = 0 OR ab.`end` > UNIX_TIMESTAMP())',
FROM ?_account_banned ab
LEFT JOIN ?_account a ON a.`id` = ab.`staffId`
WHERE ab.`userId` = ?d AND ab.`typeMask` & ?d AND (ab.`end` = 0 OR ab.`end` > UNIX_TIMESTAMP())',
User::$id, ACC_BAN_TEMP | ACC_BAN_PERM
);
@ -99,7 +99,7 @@ class AccountBaseResponse extends TemplateResponse
/* GENERAL */
// Modelviewer
if ($_ = DB::Aowow()->selectCell('SELECT `data` FROM ::account_cookies WHERE `name` = %s AND `userId` = %i', 'default_3dmodel', User::$id))
if ($_ = DB::Aowow()->selectCell('SELECT `data` FROM ?_account_cookies WHERE `name` = ? AND `userId` = ?d', 'default_3dmodel', User::$id))
[$this->modelrace, $this->modelgender] = explode(',', $_);
// Lists
@ -112,10 +112,10 @@ class AccountBaseResponse extends TemplateResponse
// Username
$this->curName = User::$username;
$this->renameCD = DateTime::formatTimeElapsedFloat(Cfg::get('ACC_RENAME_DECAY') * 1000);
$this->renameCD = Util::formatTime(Cfg::get('ACC_RENAME_DECAY') * 1000);
if ($user['renameCooldown'] > time())
{
$locCode = substr_replace(Lang::getLocale()->json(), '_', 2, 0); // ._.
$locCode = implode('_', str_split(Lang::getLocale()->json(), 2)); // ._.
$this->activeCD = (new \IntlDateFormatter($locCode, pattern: Lang::main('dateFmtIntl')))->format($user['renameCooldown']);
}
@ -131,6 +131,24 @@ class AccountBaseResponse extends TemplateResponse
$this->wowicon = $user['wowicon'];
$this->avMode = $user['avatar'];
// status [reviewing, ok, rejected]? (only 2: rejected processed in js)
if (User::isPremium() && ($cuAvatars = DB::Aowow()->select('SELECT `id`, `name`, `current`, `size`, `status`, `when` FROM ?_account_avatars WHERE `userId` = ?d', User::$id)))
{
array_walk($cuAvatars, function (&$x) {
$x['when'] *= 1000; // uploaded timestamp expected as msec for some reason
$x['caption'] = $x['name']; // only used for getVisibleText, duplicates name?
$x['type'] = 1; // always 1 ?, Dialog-popup doesn't work without it
});
foreach ($cuAvatars as $a)
if ($a['status'] != AvatarMgr::STATUS_REJECTED)
$this->customicons[$a['id']] = $a['name'];
// TODO - replace with array_find in PHP 8.4
if ($x = array_filter($cuAvatars, fn($x) => $x['current'] > 0 ))
$this->customicon = array_pop($x)['id'];
}
/* PREMIUM */
$this->premium = User::isPremium();
@ -138,23 +156,8 @@ class AccountBaseResponse extends TemplateResponse
if (!$this->premium)
return;
// required by js to calc reputation border color in user selection
$this->reputation = User::getReputation();
// status [reviewing, ok, rejected]? (only 2: rejected processed in js)
// * 'when': uploaded timestamp expected as msec for some reason
// * 'caption': only used for getVisibleText, duplicates name?
// * 'type': always 1 ?, Dialog-popup doesn't work without it
if ($cuAvatars = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `id`, `name`, `name` AS "caption", `current`, `size`, `status`, `when` * 1000 AS "when", 1 AS "type" FROM ::account_avatars WHERE `userId` = %i', User::$id))
{
foreach ($cuAvatars as $id => $a)
if ($a['status'] != AvatarMgr::STATUS_REJECTED)
$this->customicons[$id] = $a['name'];
if ($id = array_find_key($cuAvatars, fn($x) => $x['current'] > 0 ))
$this->customicon = $id;
}
// Avatar Manager
$this->avatarManager = new Listview([
'template' => 'avatar',

View file

@ -52,13 +52,13 @@ class AccountActivateResponse extends TemplateResponse
if (!$this->assertGET('key'))
return Lang::main('intError');
if (DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE `status` IN %in AND `token` = %s', [ACC_STATUS_NONE, ACC_STATUS_NEW], $this->_get['key']))
if (DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE `status` IN (?a) AND `token` = ?', [ACC_STATUS_NONE, ACC_STATUS_NEW], $this->_get['key']))
{
// don't remove the token yet. It's needed on signin page.
DB::Aowow()->qry('UPDATE ::account SET `status` = %i, `statusTimer` = 0, `userGroups` = %i WHERE `token` = %s', ACC_STATUS_NONE, U_GROUP_NONE, $this->_get['key']);
DB::Aowow()->query('UPDATE ?_account SET `status` = ?d, `statusTimer` = 0, `userGroups` = ?d WHERE `token` = ?', ACC_STATUS_NONE, U_GROUP_NONE, $this->_get['key']);
// fully apply block for further registration attempts from this ip
DB::Aowow()->qry('REPLACE INTO ::account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (%s, %i, %i + 1, UNIX_TIMESTAMP() + %i)',
DB::Aowow()->query('REPLACE INTO ?_account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (?, ?d, ?d + 1, UNIX_TIMESTAMP() + ?d)',
User::$ip, IP_BAN_TYPE_REGISTRATION_ATTEMPT, Cfg::get('ACC_FAILED_AUTH_COUNT'), Cfg::get('ACC_FAILED_AUTH_BLOCK'));
$this->success = true;

View file

@ -35,12 +35,12 @@ class AccountConfirmdeleteResponse extends TemplateResponse
private bool $success = false;
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
if (Cfg::get('ACC_AUTH_MODE') != AUTH_MODE_SELF)
$this->generateError();
parent::__construct($rawParam);
parent::__construct($pageParam);
}
protected function generate() : void
@ -54,14 +54,14 @@ class AccountConfirmdeleteResponse extends TemplateResponse
$msg = Lang::account('inputbox', 'error', 'purgeTokenUsed');
// display default confirm template
if ($this->assertGET('key') && DB::Aowow()->selectCell('SELECT 1 FROM ::account WHERE `status` = %i AND `statusTimer` > UNIX_TIMESTAMP() AND `token` = %s', ACC_STATUS_PURGING, $this->_get['key']))
if ($this->assertGET('key') && DB::Aowow()->selectCell('SELECT 1 FROM ?_account WHERE `status` = ?d AND `statusTimer` > UNIX_TIMESTAMP() AND `token` = ?', ACC_STATUS_PURGING, $this->_get['key']))
{
$this->key = $this->_get['key'];
return;
}
// perform action and display status
if ($this->assertPOST('key') && ($userId = DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE `status` = %i AND `statusTimer` > UNIX_TIMESTAMP() AND `token` = %s', ACC_STATUS_PURGING, $this->_post['key'])))
if ($this->assertPOST('key') && ($userId = DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE `status` = ?d AND `statusTimer` > UNIX_TIMESTAMP() AND `token` = ?', ACC_STATUS_PURGING, $this->_post['key'])))
{
if ($this->_post['cancel'])
$msg = $this->cancel($userId);
@ -79,7 +79,7 @@ class AccountConfirmdeleteResponse extends TemplateResponse
private function cancel(int $userId) : string
{
if (DB::Aowow()->qry('UPDATE ::account SET `status` = %i, `statusTimer` = 0, `token` = "" WHERE `id` = %i', ACC_STATUS_NONE, $userId))
if (DB::Aowow()->query('UPDATE ?_account SET `status` = ?d, `statusTimer` = 0, `token` = "" WHERE `id` = ?d', ACC_STATUS_NONE, $userId))
{
$this->success = true;
return Lang::account('inputbox', 'message', 'deleteCancel');
@ -91,32 +91,32 @@ class AccountConfirmdeleteResponse extends TemplateResponse
private function purge(int $userId) : string
{
// empty all user settings and cookies
DB::Aowow()->qry('DELETE FROM ::account_cookies WHERE `userId` = %i', $userId);
DB::Aowow()->qry('DELETE FROM ::account_avatars WHERE `userId` = %i', $userId);
DB::Aowow()->qry('DELETE FROM ::account_excludes WHERE `userId` = %i', $userId);
DB::Aowow()->qry('DELETE FROM ::account_favorites WHERE `userId` = %i', $userId);
DB::Aowow()->qry('DELETE FROM ::account_reputation WHERE `userId` = %i', $userId);
DB::Aowow()->qry('DELETE FROM ::account_weightscales WHERE `userId` = %i', $userId); // cascades to aowow_account_weightscale_data
DB::Aowow()->query('DELETE FROM ?_account_cookies WHERE `userId` = ?d', $userId);
DB::Aowow()->query('DELETE FROM ?_account_avatars WHERE `userId` = ?d', $userId);
DB::Aowow()->query('DELETE FROM ?_account_excludes WHERE `userId` = ?d', $userId);
DB::Aowow()->query('DELETE FROM ?_account_favorites WHERE `userId` = ?d', $userId);
DB::Aowow()->query('DELETE FROM ?_account_reputation WHERE `userId` = ?d', $userId);
DB::Aowow()->query('DELETE FROM ?_account_weightscales WHERE `userId` = ?d', $userId); // cascades to aowow_account_weightscale_data
// delete profiles, unlink chars
DB::Aowow()->qry('DELETE pp FROM ::profiler_profiles pp JOIN ::account_profiles ap ON ap.`profileId` = pp.`id` WHERE ap.`accountId` = %i', $userId);
// DB::Aowow()->qry('DELETE FROM ::account_profiles WHERE `accountId` = %i', $userId); // already deleted via FK?
DB::Aowow()->query('DELETE pp FROM ?_profiler_profiles pp JOIN ?_account_profiles ap ON ap.`profileId` = pp.`id` WHERE ap.`accountId` = ?d', $userId);
// DB::Aowow()->query('DELETE FROM ?_account_profiles WHERE `accountId` = ?d', $userId); // already deleted via FK?
// delete all sessions and bans
DB::Aowow()->qry('DELETE FROM ::account_banned WHERE `userId` = %i', $userId);
DB::Aowow()->qry('DELETE FROM ::account_sessions WHERE `userId` = %i', $userId);
DB::Aowow()->query('DELETE FROM ?_account_banned WHERE `userId` = ?d', $userId);
DB::Aowow()->query('DELETE FROM ?_account_sessions WHERE `userId` = ?d', $userId);
// delete forum posts (msg: This post was from a user who has deleted their account. (no translations at src); comments/replies are unaffected)
// ...
// replace username with userId and empty fields
DB::Aowow()->qry(
'UPDATE ::account SET
DB::Aowow()->query(
'UPDATE ?_account SET
`login` = "", `passHash` = "", `username` = `id`, `email` = NULL, `userGroups` = 0, `userPerms` = 0,
`curIp` = "", `prevIp` = "", `curLogin` = 0, `prevLogin` = 0,
`locale` = 0, `debug` = 0, `avatar` = 0, `wowicon` = "", `title` = "", `description` = "", `excludeGroups` = 0,
`status` = %i, `statusTimer` = 0, `token` = "", `updateValue` = "", `renameCooldown` = 0
WHERE `id` = %i',
`status` = ?d, `statusTimer` = 0, `token` = "", `updateValue` = "", `renameCooldown` = 0
WHERE `id` = ?d',
ACC_STATUS_DELETED, $userId
);

View file

@ -46,12 +46,12 @@ class AccountConfirmemailaddressResponse extends TemplateResponse
if (!$this->assertGET('key'))
return Lang::main('intError');
$acc = DB::Aowow()->selectRow('SELECT `updateValue`, `status`, `statusTimer` FROM ::account WHERE `token` = %s', $this->_get['key']);
$acc = DB::Aowow()->selectRow('SELECT `updateValue`, `status`, `statusTimer` FROM ?_account WHERE `token` = ?', $this->_get['key']);
if (!$acc || $acc['status'] != ACC_STATUS_CHANGE_EMAIL || $acc['statusTimer'] < time())
return Lang::account('inputbox', 'error', 'mailTokenUsed');
// 0 changes == error
if (!DB::Aowow()->qry('UPDATE ::account SET `email` = `updateValue`, `status` = %i, `statusTimer` = 0, `token` = "", `updateValue` = "" WHERE `token` = %s', ACC_STATUS_NONE, $this->_get['key']))
if (!DB::Aowow()->query('UPDATE ?_account SET `email` = `updateValue`, `status` = ?d, `statusTimer` = 0, `token` = "", `updateValue` = "" WHERE `token` = ?', ACC_STATUS_NONE, $this->_get['key']))
return Lang::main('intError');
$this->success = true;

View file

@ -44,12 +44,12 @@ class AccountConfirmpasswordResponse extends TemplateResponse
if (!$this->assertGET('key'))
return Lang::main('intError');
$acc = DB::Aowow()->selectRow('SELECT `updateValue`, `status`, `statusTimer` FROM ::account WHERE `token` = %s', $this->_get['key']);
$acc = DB::Aowow()->selectRow('SELECT `updateValue`, `status`, `statusTimer` FROM ?_account WHERE `token` = ?', $this->_get['key']);
if (!$acc || $acc['status'] != ACC_STATUS_CHANGE_PASS || $acc['statusTimer'] < time())
return Lang::account('inputbox', 'error', 'passTokenUsed');
// 0 changes == error
if (!DB::Aowow()->qry('UPDATE ::account SET `passHash` = `updateValue`, `status` = %i, `statusTimer` = 0, `token` = "", `updateValue` = "" WHERE `token` = %s', ACC_STATUS_NONE, $this->_get['key']))
if (!DB::Aowow()->query('UPDATE ?_account SET `passHash` = `updateValue`, `status` = ?d, `statusTimer` = 0, `token` = "", `updateValue` = "" WHERE `token` = ?', ACC_STATUS_NONE, $this->_get['key']))
return Lang::main('intError');
$this->success = true;

View file

@ -28,15 +28,15 @@ class AccountDeleteiconResponse extends TextResponse
return;
// non-int > error
$selected = DB::Aowow()->selectCell('SELECT `current` FROM ::account_avatars WHERE `id` = %i AND `userId` = %i', $this->_post['id'], User::$id);
$selected = DB::Aowow()->selectCell('SELECT `current` FROM ?_account_avatars WHERE `id` = ?d AND `userId` = ?d', $this->_post['id'], User::$id);
if ($selected === null || $selected === false)
return;
DB::Aowow()->qry('DELETE FROM ::account_avatars WHERE `id` = %i AND `userId` = %i', $this->_post['id'], User::$id);
DB::Aowow()->query('DELETE FROM ?_account_avatars WHERE `id` = ?d AND `userId` = ?d', $this->_post['id'], User::$id);
// if deleted avatar is also currently selected, unset
if ($selected)
DB::Aowow()->qry('UPDATE ::account SET `avatar` = 0 WHERE `id` = %i', User::$id);
DB::Aowow()->query('UPDATE ?_account SET `avatar` = 0 WHERE `id` = ?d', User::$id);
$path = sprintf('static/uploads/avatars/%d.jpg', $this->_post['id']);
if (!unlink($path))

View file

@ -28,12 +28,12 @@ class AccountDeleteResponse extends TemplateResponse
public string $deleteFormTarget = '?account=delete';
public ?array $inputbox = null;
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
if (Cfg::get('ACC_AUTH_MODE') != AUTH_MODE_SELF)
$this->generateError();
parent::__construct($rawParam);
parent::__construct($pageParam);
}
protected function generate() : void
@ -47,11 +47,11 @@ class AccountDeleteResponse extends TemplateResponse
if ($this->_post['proceed'])
{
$error = false;
if (!DB::Aowow()->selectCell('SELECT 1 FROM ::account WHERE `status` NOT IN %in AND `statusTimer` > UNIX_TIMESTAMP() AND `id` = %i', [ACC_STATUS_NEW, ACC_STATUS_NONE, ACC_STATUS_PURGING], User::$id))
if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_account WHERE `status` NOT IN (?a) AND `statusTimer` > UNIX_TIMESTAMP() AND `id` = ?d', [ACC_STATUS_NEW, ACC_STATUS_NONE, ACC_STATUS_PURGING], User::$id))
{
$token = Util::createHash(40);
DB::Aowow()->qry('UPDATE ::account SET `status` = %i, `statusTimer` = UNIX_TIMESTAMP() + %i, `token` = %s WHERE `id` = %i',
DB::Aowow()->query('UPDATE ?_account SET `status` = ?d, `statusTimer` = UNIX_TIMESTAMP() + ?d, `token` = ? WHERE `id` = ?d',
ACC_STATUS_PURGING, Cfg::get('ACC_RECOVERY_DECAY'), $token, User::$id);
Util::sendMail(User::$email, 'delete-account', [$token, User::$email, User::$username]);

View file

@ -34,7 +34,7 @@ class AccountExcludeResponse extends TextResponse
else if ($this->_post['reset'] == 1) // defaults to unavailable
$this->resetExcludes();
else if ($this->_post['groups'] !== null) // exclude by group mask
else if ($this->_post['groups']) // exclude by group mask
$this->updateGroups();
}
@ -49,17 +49,12 @@ class AccountExcludeResponse extends TextResponse
// we don't get signaled whether an id should be added to or removed from either includes or excludes
// so we throw everything into one table and toggle the mode if its already in here
$includes = DB::Aowow()->selectCol('SELECT `typeId` FROM ::profiler_excludes WHERE `type` = %i AND `typeId` IN %in', $this->_post['type'], $validIds);
$insert = [];
foreach ($validIds as $typeId)
{
$insert['userId'][] = User::$id;
$insert['type'][] = $this->_post['type'];
$insert['typeId'][] = $typeId;
$insert['mode'][] = in_array($typeId, $includes) ? Profiler::COMPLETION_INCLUDE : Profiler::COMPLETION_EXCLUDE;
};
$includes = DB::Aowow()->selectCol('SELECT `typeId` FROM ?_profiler_excludes WHERE `type` = ?d AND `typeId` IN (?a)', $this->_post['type'], $validIds);
DB::Aowow()->qry('INSERT INTO ::account_excludes %m ON DUPLICATE KEY UPDATE `mode` = (`mode` ^ 0x3)', $insert);
foreach ($validIds as $typeId)
DB::Aowow()->query('INSERT INTO ?_account_excludes (`userId`, `type`, `typeId`, `mode`) VALUES (?a) ON DUPLICATE KEY UPDATE `mode` = (`mode` ^ 0x3)',
[User::$id, $this->_post['type'], $typeId, in_array($typeId, $includes) ? 2 : 1]
);
}
else
trigger_error('AccountExcludeResponse::excludeById - validation failed [type: '.$this->_post['type'].', typeId: '.implode(',', $this->_post['id']).']', E_USER_NOTICE);
@ -67,14 +62,14 @@ class AccountExcludeResponse extends TextResponse
private function resetExcludes() : void
{
DB::Aowow()->qry('DELETE FROM ::account_excludes WHERE `userId` = %i', User::$id);
DB::Aowow()->qry('UPDATE ::account SET `excludeGroups` = %i WHERE `id` = %i', PR_EXCLUDE_GROUP_UNAVAILABLE, User::$id);
DB::Aowow()->query('DELETE FROM ?_account_excludes WHERE `userId` = ?d', User::$id);
DB::Aowow()->query('UPDATE ?_account SET `excludeGroups` = ?d WHERE `id` = ?d', PR_EXCLUDE_GROUP_UNAVAILABLE, User::$id);
}
private function updateGroups() : void
{
if ($this->assertPOST('groups')) // clamp to real groups
DB::Aowow()->qry('UPDATE ::account SET `excludeGroups` = %i WHERE `id` = %i', $this->_post['groups'] & PR_EXCLUDE_GROUP_ANY, User::$id);
DB::Aowow()->query('UPDATE ?_account SET `excludeGroups` = ?d WHERE `id` = ?d', $this->_post['groups'] & PR_EXCLUDE_GROUP_ANY, User::$id);
}
}

View file

@ -37,13 +37,13 @@ class AccountFavoritesResponse extends TextResponse
private function removeFavorite() : void
{
if ($this->assertPOST('id', 'remove'))
DB::Aowow()->qry('DELETE FROM ::account_favorites WHERE `userId` = %i AND `type` = %i AND `typeId` = %i', User::$id, $this->_post['remove'], $this->_post['id']);
DB::Aowow()->query('DELETE FROM ?_account_favorites WHERE `userId` = ?d AND `type` = ?d AND `typeId` = ?d', User::$id, $this->_post['remove'], $this->_post['id']);
}
private function addFavorite() : void
{
if ($this->assertPOST('id', 'add') && Type::validateIds($this->_post['add'], $this->_post['id']))
DB::Aowow()->qry('INSERT INTO ::account_favorites (`userId`, `type`, `typeId`) VALUES (%i, %i, %i)', User::$id, $this->_post['add'], $this->_post['id']);
DB::Aowow()->query('INSERT INTO ?_account_favorites (`userId`, `type`, `typeId`) VALUES (?d, ?d, ?d)', User::$id, $this->_post['add'], $this->_post['id']);
else
trigger_error('AccountFavoritesResponse::addFavorite() - failed to add [userId: '.User::$id.', type: '.$this->_post['add'].', typeId: '.$this->_post['id'], E_USER_NOTICE);
}

View file

@ -29,7 +29,7 @@ class AccountforgotpasswordResponse extends TemplateResponse
private bool $success = false;
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
// don't redirect logged in users
// you can be forgetful AND logged in
@ -40,7 +40,7 @@ class AccountforgotpasswordResponse extends TemplateResponse
if (Cfg::get('ACC_AUTH_MODE') != AUTH_MODE_SELF)
$this->generateError();
parent::__construct($rawParam);
parent::__construct($pageParam);
}
protected function generate() : void
@ -72,14 +72,14 @@ class AccountforgotpasswordResponse extends TemplateResponse
if (!$this->_post['email'])
return Lang::account('emailInvalid');
$timeout = DB::Aowow()->selectCell('SELECT `unbanDate` FROM ::account_bannedips WHERE `ip` = %s AND `type` = %i AND `count` > %i AND `unbanDate` > UNIX_TIMESTAMP()', User::$ip, IP_BAN_TYPE_PASSWORD_RECOVERY, Cfg::get('ACC_FAILED_AUTH_COUNT'));
$timeout = DB::Aowow()->selectCell('SELECT `unbanDate` FROM ?_account_bannedips WHERE `ip` = ? AND `type` = ?d AND `count` > ?d AND `unbanDate` > UNIX_TIMESTAMP()', User::$ip, IP_BAN_TYPE_PASSWORD_RECOVERY, Cfg::get('ACC_FAILED_AUTH_COUNT'));
// on cooldown pretend we dont know the email address
if ($timeout && $timeout > time())
return Cfg::get('DEBUG') ? 'resend on cooldown: '.DateTime::formatTimeElapsed($timeout * 1000).' remaining' : Lang::account('inputbox', 'error', 'emailNotFound');
return Cfg::get('DEBUG') ? 'resend on cooldown: '.Util::formatTimeDiff($timeout).' remaining' : Lang::account('inputbox', 'error', 'emailNotFound');
// pretend recovery started
if (!DB::Aowow()->selectCell('SELECT 1 FROM ::account WHERE `email` = %s', $this->_post['email']))
if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_account WHERE `email` = ?', $this->_post['email']))
{
// do not confirm or deny existence of email
$this->success = !Cfg::get('DEBUG');
@ -90,7 +90,7 @@ class AccountforgotpasswordResponse extends TemplateResponse
if ($err = $this->startRecovery(ACC_STATUS_RECOVER_PASS, 'reset-password', $this->_post['email']))
return $err;
DB::Aowow()->qry('INSERT INTO ::account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (%s, %i, %i, UNIX_TIMESTAMP() + %i) ON DUPLICATE KEY UPDATE `count` = `count` + %i, `unbanDate` = UNIX_TIMESTAMP() + %i',
DB::Aowow()->query('INSERT INTO ?_account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (?, ?d, ?d, UNIX_TIMESTAMP() + ?d) ON DUPLICATE KEY UPDATE `count` = `count` + ?d, `unbanDate` = UNIX_TIMESTAMP() + ?d',
User::$ip, IP_BAN_TYPE_PASSWORD_RECOVERY, Cfg::get('ACC_FAILED_AUTH_COUNT') + 1, Cfg::get('ACC_FAILED_AUTH_COUNT'), Cfg::get('ACC_FAILED_AUTH_BLOCK'), Cfg::get('ACC_FAILED_AUTH_BLOCK'));
$this->success = true;

View file

@ -28,7 +28,7 @@ class AccountforgotusernameResponse extends TemplateResponse
private bool $success = false;
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
// if the user is looged in goto account dashboard
if (User::isLoggedIn())
@ -40,7 +40,7 @@ class AccountforgotusernameResponse extends TemplateResponse
if (Cfg::get('ACC_AUTH_MODE') != AUTH_MODE_SELF)
$this->generateError();
parent::__construct($rawParam);
parent::__construct($pageParam);
}
protected function generate() : void
@ -71,14 +71,14 @@ class AccountforgotusernameResponse extends TemplateResponse
if (!$this->_post['email'])
return Lang::account('emailInvalid');
$timeout = DB::Aowow()->selectCell('SELECT `unbanDate` FROM ::account_bannedips WHERE `ip` = %s AND `type` = %i AND `count` > %i AND `unbanDate` > UNIX_TIMESTAMP()', User::$ip, IP_BAN_TYPE_USERNAME_RECOVERY, Cfg::get('ACC_FAILED_AUTH_COUNT'));
$timeout = DB::Aowow()->selectCell('SELECT `unbanDate` FROM ?_account_bannedips WHERE `ip` = ? AND `type` = ?d AND `count` > ?d AND `unbanDate` > UNIX_TIMESTAMP()', User::$ip, IP_BAN_TYPE_USERNAME_RECOVERY, Cfg::get('ACC_FAILED_AUTH_COUNT'));
// on cooldown pretend we dont know the email address
if ($timeout && $timeout > time())
return Cfg::get('DEBUG') ? 'resend on cooldown: '.DateTime::formatTimeElapsed($timeout * 1000).' remaining' : Lang::account('inputbox', 'error', 'emailNotFound');
return Cfg::get('DEBUG') ? 'resend on cooldown: '.Util::formatTimeDiff($timeout).' remaining' : Lang::account('inputbox', 'error', 'emailNotFound');
// pretend recovery started
if (!DB::Aowow()->selectCell('SELECT 1 FROM ::account WHERE `email` = %s', $this->_post['email']))
if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_account WHERE `email` = ?', $this->_post['email']))
{
// do not confirm or deny existence of email
$this->success = !Cfg::get('DEBUG');
@ -89,7 +89,7 @@ class AccountforgotusernameResponse extends TemplateResponse
if ($err = $this->startRecovery(ACC_STATUS_RECOVER_USER, 'recover-user', $this->_post['email']))
return $err;
DB::Aowow()->qry('INSERT INTO ::account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (%s, %i, %i, UNIX_TIMESTAMP() + %i) ON DUPLICATE KEY UPDATE `count` = `count` + %i, `unbanDate` = UNIX_TIMESTAMP() + %i',
DB::Aowow()->query('INSERT INTO ?_account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (?, ?d, ?d, UNIX_TIMESTAMP() + ?d) ON DUPLICATE KEY UPDATE `count` = `count` + ?d, `unbanDate` = UNIX_TIMESTAMP() + ?d',
User::$ip, IP_BAN_TYPE_USERNAME_RECOVERY, Cfg::get('ACC_FAILED_AUTH_COUNT') + 1, Cfg::get('ACC_FAILED_AUTH_COUNT'), Cfg::get('ACC_FAILED_AUTH_BLOCK'), Cfg::get('ACC_FAILED_AUTH_BLOCK'));
$this->success = true;

View file

@ -48,7 +48,7 @@ class AccountForumavatarResponse extends TextResponse
private function unset() : string
{
$x = DB::Aowow()->qry('UPDATE ::account SET `avatar` = 0 WHERE `id` = %i', User::$id);
$x = DB::Aowow()->query('UPDATE ?_account SET `avatar` = 0 WHERE `id` = ?d', User::$id);
if ($x === null || $x === false)
return Lang::main('genericError');
@ -64,17 +64,17 @@ class AccountForumavatarResponse extends TextResponse
$icon = strtolower(trim($this->_post['wowicon']));
if (!DB::Aowow()->selectCell('SELECT 1 FROM ::icons WHERE `name` = %s', $icon))
if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_icons WHERE `name` = ?', $icon))
return Lang::account('updateMessage', 'avNotFound');
$x = DB::Aowow()->qry('UPDATE ::account SET `avatar` = 1, `wowicon` = %s WHERE `id` = %i', $icon, User::$id);
if (is_null($x))
$x = DB::Aowow()->query('UPDATE ?_account SET `avatar` = 1, `wowicon` = ? WHERE `id` = ?d', strtolower($icon), User::$id);
if ($x === null || $x === false)
return Lang::main('genericError');
$this->success = true;
$msg = Lang::account('updateMessage', $x === 0 ? 'avNoChange' : 'avSuccess');
if (($qty = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ::account WHERE `wowicon` = %s', $icon)) > 1)
if (($qty = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_account WHERE `wowicon` = ?', $icon)) > 1)
$msg .= ' '.Lang::account('updateMessage', 'avNthUser', [$qty]);
else
$msg .= ' '.Lang::account('updateMessage', 'av1stUser');
@ -92,11 +92,11 @@ class AccountForumavatarResponse extends TextResponse
$customIcon = $this->_post['customicon'] ?? $this->_get['customicon'];
$x = DB::Aowow()->qry('UPDATE ::account_avatars SET `current` = IF(`id` = %i, 1, 0) WHERE `userId` = %i AND `status` <> %i', $customIcon, User::$id, AvatarMgr::STATUS_REJECTED);
$x = DB::Aowow()->query('UPDATE ?_account_avatars SET `current` = IF(`id` = ?d, 1, 0) WHERE `userId` = ?d AND `status` <> ?d', $customIcon, User::$id, AvatarMgr::STATUS_REJECTED);
if (!is_int($x))
return Lang::main('genericError');
if (!is_int(DB::Aowow()->qry('UPDATE ::account SET `avatar` = 2 WHERE `id` = %i', User::$id)))
if (!is_int(DB::Aowow()->query('UPDATE ?_account SET `avatar` = 2 WHERE `id` = ?d', User::$id)))
return Lang::main('intError');
$this->success = true;

View file

@ -28,8 +28,8 @@ class AccountPremiumborderResponse extends TextResponse
if (!$this->assertPOST('avatarborder'))
return;
$x = DB::Aowow()->qry('UPDATE ::account SET `avatarborder` = %i WHERE `id` = %i', $this->_post['avatarborder'], User::$id);
if (is_null($x))
$x = DB::Aowow()->query('UPDATE ?_account SET `avatarborder` = ?d WHERE `id` = ?d', $this->_post['avatarborder'], User::$id);
if (!is_int($x))
$_SESSION['msg'] = ['premiumborder', false, Lang::main('genericError')];
else if (!$x)
$_SESSION['msg'] = ['premiumborder', true, Lang::account('updateMessage', 'avNoChange')];

View file

@ -29,7 +29,7 @@ class AccountRenameiconResponse extends TextResponse
return;
// regexp same as in account.js
DB::Aowow()->qry('UPDATE ::account_avatars SET `name` = %s WHERE `id` = %i AND `userId` = %i', trim($this->_post['name']), $this->_post['id'], User::$id);
DB::Aowow()->query('UPDATE ?_account_avatars SET `name` = ? WHERE `id` = ?d AND `userId` = ?d', trim($this->_post['name']), $this->_post['id'], User::$id);
}
}

View file

@ -20,12 +20,12 @@ class AccountResendsubmitResponse extends TemplateResponse
'email' => ['filter' => FILTER_VALIDATE_EMAIL, 'flags' => FILTER_FLAG_STRIP_AOWOW]
);
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
if (!Cfg::get('ACC_ALLOW_REGISTER') || Cfg::get('ACC_AUTH_MODE') != AUTH_MODE_SELF)
$this->generateError();
parent::__construct($rawParam);
parent::__construct($pageParam);
}
protected function generate() : void

View file

@ -22,7 +22,7 @@ class AccountResendResponse extends TemplateResponse
private bool $success = false;
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
if (Cfg::get('ACC_EXT_RECOVER_URL'))
$this->forward(Cfg::get('ACC_EXT_RECOVER_URL'));
@ -30,7 +30,7 @@ class AccountResendResponse extends TemplateResponse
if (!Cfg::get('ACC_ALLOW_REGISTER') || Cfg::get('ACC_AUTH_MODE') != AUTH_MODE_SELF)
$this->generateError();
parent::__construct($rawParam);
parent::__construct($pageParam);
}
protected function generate() : void
@ -69,19 +69,19 @@ class AccountResendResponse extends TemplateResponse
if (!$this->_post['email'])
return Lang::account('emailInvalid');
$timeout = DB::Aowow()->selectCell('SELECT `unbanDate` FROM ::account_bannedips WHERE `ip` = %s AND `type` = %i AND `count` > %i AND `unbanDate` > UNIX_TIMESTAMP()', User::$ip, IP_BAN_TYPE_REGISTRATION_ATTEMPT, Cfg::get('ACC_FAILED_AUTH_COUNT'));
$timeout = DB::Aowow()->selectCell('SELECT `unbanDate` FROM ?_account_bannedips WHERE `ip` = ? AND `type` = ?d AND `count` > ?d AND `unbanDate` > UNIX_TIMESTAMP()', User::$ip, IP_BAN_TYPE_REGISTRATION_ATTEMPT, Cfg::get('ACC_FAILED_AUTH_COUNT'));
// on cooldown pretend we dont know the email address
if ($timeout && $timeout > time())
return Cfg::get('DEBUG') ? 'resend on cooldown: '.DateTime::formatTimeElapsed($timeout * 1000).' remaining' : Lang::account('inputbox', 'error', 'emailNotFound');
return Cfg::get('DEBUG') ? 'resend on cooldown: '.Util::formatTimeDiff($timeout).' remaining' : Lang::account('inputbox', 'error', 'emailNotFound');
// check email and account status
if ($token = DB::Aowow()->selectCell('SELECT `token` FROM ::account WHERE `email` = %s AND `status` = %i', $this->_post['email'], ACC_STATUS_NEW))
if ($token = DB::Aowow()->selectCell('SELECT `token` FROM ?_account WHERE `email` = ? AND `status` = ?d', $this->_post['email'], ACC_STATUS_NEW))
{
if (!Util::sendMail($this->_post['email'], 'activate-account', [$token]))
return Lang::main('intError');
DB::Aowow()->qry('INSERT INTO ::account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (%s, %i, %i, UNIX_TIMESTAMP() + %i) ON DUPLICATE KEY UPDATE `count` = `count` + %i, `unbanDate` = UNIX_TIMESTAMP() + %i',
DB::Aowow()->query('INSERT INTO ?_account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (?, ?d, ?d, UNIX_TIMESTAMP() + ?d) ON DUPLICATE KEY UPDATE `count` = `count` + ?d, `unbanDate` = UNIX_TIMESTAMP() + ?d',
User::$ip, IP_BAN_TYPE_REGISTRATION_ATTEMPT, Cfg::get('ACC_FAILED_AUTH_COUNT') + 1, Cfg::get('ACC_FAILED_AUTH_COUNT'), Cfg::get('ACC_FAILED_AUTH_BLOCK'), Cfg::get('ACC_FAILED_AUTH_BLOCK'));
$this->success = true;

View file

@ -25,7 +25,7 @@ class AccountresetpasswordResponse extends TemplateResponse
protected array $expectedGET = array(
'key' => ['filter' => FILTER_VALIDATE_REGEXP, 'options' => ['regexp' => '/^[a-zA-Z0-9]{40}$/']],
'next' => ['filter' => FILTER_VALIDATE_REGEXP, 'options' => ['regexp' => '/^[[:print:]]+$/' ]]
'next' => ['filter' => FILTER_SANITIZE_URL, 'flags' => FILTER_FLAG_STRIP_AOWOW ]
);
protected array $expectedPOST = array(
'key' => ['filter' => FILTER_VALIDATE_REGEXP, 'options' => ['regexp' => '/^[a-zA-Z0-9]{40}$/']],
@ -59,7 +59,7 @@ class AccountresetpasswordResponse extends TemplateResponse
$errMsg = '';
if (!$this->assertGET('key') && !$this->assertPOST('key'))
$errMsg = Lang::account('inputbox', 'error', 'passTokenLost');
else if ($this->_get['key'] && !DB::Aowow()->selectCell('SELECT 1 FROM ::account WHERE `token` = %s AND `status` = %i AND `statusTimer` > UNIX_TIMESTAMP()', $this->_get['key'], ACC_STATUS_RECOVER_PASS))
else if ($this->_get['key'] && !DB::Aowow()->selectCell('SELECT 1 FROM ?_account WHERE `token` = ? AND `status` = ?d AND `statusTimer` > UNIX_TIMESTAMP()', $this->_get['key'], ACC_STATUS_RECOVER_PASS))
$errMsg = Lang::account('inputbox', 'error', 'passTokenUsed');
if ($errMsg)
@ -99,7 +99,7 @@ class AccountresetpasswordResponse extends TemplateResponse
if ($this->_post['password'] != $this->_post['c_password'])
return Lang::account('passCheckFail');
$userData = DB::Aowow()->selectRow('SELECT `id`, `passHash` FROM ::account WHERE `token` = %s AND `email` = %s AND `status` = %i AND `statusTimer` > UNIX_TIMESTAMP()',
$userData = DB::Aowow()->selectRow('SELECT `id`, `passHash` FROM ?_account WHERE `token` = ? AND `email` = ? AND `status` = ?d AND `statusTimer` > UNIX_TIMESTAMP()',
$this->_post['key'],
$this->_post['email'],
ACC_STATUS_RECOVER_PASS
@ -110,7 +110,7 @@ class AccountresetpasswordResponse extends TemplateResponse
if (!User::verifyCrypt($this->_post['c_password'], $userData['passHash']))
return Lang::account('newPassDiff');
if (!DB::Aowow()->qry('UPDATE ::account SET `passHash` = %s, `status` = %i WHERE `id` = %i', User::hashCrypt($this->_post['c_password']), ACC_STATUS_NONE, $userData['id']))
if (!DB::Aowow()->query('UPDATE ?_account SET `passHash` = ?, `status` = ?d WHERE `id` = ?d', User::hashCrypt($this->_post['c_password']), ACC_STATUS_NONE, $userData['id']))
return Lang::main('intError');
$this->success = true;

View file

@ -46,12 +46,12 @@ class AccountRevertemailaddressResponse extends TemplateResponse
if (!$this->assertGET('key'))
return Lang::main('intError');
$acc = DB::Aowow()->selectRow('SELECT `updateValue`, `status`, `statusTimer` FROM ::account WHERE `token` = %s', $this->_get['key']);
$acc = DB::Aowow()->selectRow('SELECT `updateValue`, `status`, `statusTimer` FROM ?_account WHERE `token` = ?', $this->_get['key']);
if (!$acc || $acc['status'] != ACC_STATUS_CHANGE_EMAIL || $acc['statusTimer'] < time())
return Lang::account('inputbox', 'error', 'mailTokenUsed');
// 0 changes == error
if (!DB::Aowow()->qry('UPDATE ::account SET `status` = %i, `statusTimer` = 0, `token` = "", `updateValue` = "" WHERE `token` = %s', ACC_STATUS_NONE, $this->_get['key']))
if (!DB::Aowow()->query('UPDATE ?_account SET `status` = ?d, `statusTimer` = 0, `token` = "", `updateValue` = "" WHERE `token` = ?', ACC_STATUS_NONE, $this->_get['key']))
return Lang::main('intError');
$this->success = true;

View file

@ -28,7 +28,7 @@ class AccountSigninResponse extends TemplateResponse
);
protected array $expectedGET = array(
'key' => ['filter' => FILTER_VALIDATE_REGEXP, 'options' => ['regexp' => '/^[a-zA-Z0-9]{40}$/']],
'next' => ['filter' => FILTER_VALIDATE_REGEXP, 'options' => ['regexp' => '/^[[:print:]]+$/'] ]
'next' => ['filter' => FILTER_SANITIZE_URL, 'flags' => FILTER_FLAG_STRIP_AOWOW ]
);
private bool $success = false;
@ -53,7 +53,7 @@ class AccountSigninResponse extends TemplateResponse
// coming from user recovery or creation, prefill username
if ($this->_get['key'])
{
if ($userData = DB::Aowow()->selectRow('SELECT a.`login` AS "0", IF(s.`expires`, 0, 1) AS "1" FROM ::account a LEFT JOIN ::account_sessions s ON a.`id` = s.`userId` AND a.`token` = s.`sessionId` WHERE a.`status` IN %in AND a.`token` = %s',
if ($userData = DB::Aowow()->selectRow('SELECT a.`login` AS "0", IF(s.`expires`, 0, 1) AS "1" FROM ?_account a LEFT JOIN ?_account_sessions s ON a.`id` = s.`userId` AND a.`token` = s.`sessionId` WHERE a.`status` IN (?a) AND a.`token` = ?',
[ACC_STATUS_RECOVER_USER, ACC_STATUS_NONE], $this->_get['key']))
[$username, $rememberMe] = $userData;
}
@ -99,7 +99,7 @@ class AccountSigninResponse extends TemplateResponse
// AUTH_BANNED => Lang::account('accBanned'); // ToDo: should this return an error? the actual account functionality should be blocked elsewhere
AUTH_WRONGUSER => Lang::account('userNotFound'),
AUTH_WRONGPASS => Lang::account('wrongPass'),
AUTH_IPBANNED => Lang::account('inputbox', 'error', 'loginExceeded', [DateTime::formatTimeElapsedFloat(Cfg::get('ACC_FAILED_AUTH_BLOCK') * 1000)]),
AUTH_IPBANNED => Lang::account('inputbox', 'error', 'loginExceeded', [Util::formatTime(Cfg::get('ACC_FAILED_AUTH_BLOCK') * 1000)]),
AUTH_INTERNAL_ERR => Lang::main('intError'),
default => Lang::main('intError')
};
@ -116,7 +116,7 @@ class AccountSigninResponse extends TemplateResponse
}
// reset account status, update expiration
$ok = DB::Aowow()->qry('UPDATE ::account SET `prevIP` = IF(`curIp` = %s, `prevIP`, `curIP`), `curIP` = IF(`curIp` = %s, `curIP`, %s), `status` = IF(`status` = %i, `status`, 0), `statusTimer` = IF(`status` = %i, `statusTimer`, 0), `token` = IF(`status` = %i, `token`, "") WHERE `id` = %i',
$ok = DB::Aowow()->query('UPDATE ?_account SET `prevIP` = IF(`curIp` = ?, `prevIP`, `curIP`), `curIP` = IF(`curIp` = ?, `curIP`, ?), `status` = IF(`status` = ?d, `status`, 0), `statusTimer` = IF(`status` = ?d, `statusTimer`, 0), `token` = IF(`status` = ?d, `token`, "") WHERE `id` = ?d',
User::$ip, User::$ip, User::$ip,
ACC_STATUS_NEW, ACC_STATUS_NEW, ACC_STATUS_NEW,
User::$id // available after successful User:authenticate
@ -130,12 +130,12 @@ class AccountSigninResponse extends TemplateResponse
// DELETE temp session
if ($this->_get['key'])
DB::Aowow()->qry('DELETE FROM ::account_sessions WHERE `sessionId` = %s', $this->_get['key']);
DB::Aowow()->query('DELETE FROM ?_account_sessions WHERE `sessionId` = ?', $this->_get['key']);
session_regenerate_id(true); // user status changed => regenerate id
// create new session entry
DB::Aowow()->qry('INSERT INTO ::account_sessions (`userId`, `sessionId`, `created`, `expires`, `touched`, `deviceInfo`, `ip`, `status`) VALUES (%i, %s, %i, %i, %i, %s, %s, %i)',
DB::Aowow()->query('INSERT INTO ?_account_sessions (`userId`, `sessionId`, `created`, `expires`, `touched`, `deviceInfo`, `ip`, `status`) VALUES (?d, ?, ?d, ?d, ?d, ?, ?, ?d)',
User::$id, session_id(), time(), $this->_post['remember_me'] ? 0 : time() + Cfg::get('SESSION_TIMEOUT_DELAY'), time(), User::$agent, User::$ip, SESSION_ACTIVE);
if (User::init()) // reinitialize the user

View file

@ -11,25 +11,25 @@ class AccountSignoutResponse extends TextResponse
use TrGetNext;
protected array $expectedGET = array(
'next' => ['filter' => FILTER_VALIDATE_REGEXP, 'options' => ['regexp' => '/^[[:print:]]+$/']],
'global' => ['filter' => FILTER_CALLBACK, 'options' => [self::class, 'checkEmptySet'] ]
'next' => ['filter' => FILTER_SANITIZE_URL, 'flags' => FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH],
'global' => ['filter' => FILTER_CALLBACK, 'options' => [self::class, 'checkEmptySet'] ]
);
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
// if the user not is logged in goto login page
if (!User::isLoggedIn())
$this->forwardToSignIn();
parent::__construct($rawParam);
parent::__construct($pageParam);
}
protected function generate() : void
{
if ($this->_get['global'])
DB::Aowow()->qry('UPDATE ::account_sessions SET `touched` = %i, `status` = %i WHERE `userId` = %i', time(), SESSION_FORCED_LOGOUT, User::$id);
DB::Aowow()->query('UPDATE ?_account_sessions SET `touched` = ?d, `status` = ?d WHERE `userId` = ?d', time(), SESSION_FORCED_LOGOUT, User::$id);
else
DB::Aowow()->qry('UPDATE ::account_sessions SET `touched` = %i, `status` = %i WHERE `sessionId` = %s', time(), SESSION_LOGOUT, session_id());
DB::Aowow()->query('UPDATE ?_account_sessions SET `touched` = ?d, `status` = ?d WHERE `sessionId` = ?', time(), SESSION_LOGOUT, session_id());
User::destroy();

View file

@ -26,7 +26,7 @@ class AccountSignupResponse extends TemplateResponse
);
protected array $expectedGET = array(
'next' => ['filter' => FILTER_VALIDATE_REGEXP, 'options' => ['regexp' => '/^[[:print:]]+$/']]
'next' => ['filter' => FILTER_SANITIZE_URL, 'flags' => FILTER_FLAG_STRIP_AOWOW]
);
private bool $success = false;
@ -99,7 +99,7 @@ class AccountSignupResponse extends TemplateResponse
// check password
if (!Util::validatePassword($this->_post['password'], $e))
return $e == 1 ? Lang::account('errPassLength') : Lang::main('intError');
return Lang::account($e == 1 ? 'errPassLength' : 'errPassChars');
if ($this->_post['password'] !== $this->_post['c_password'])
return Lang::account('passMismatch');
@ -109,24 +109,24 @@ class AccountSignupResponse extends TemplateResponse
return Lang::main('intError');
// limit account creation
if (DB::Aowow()->selectRow('SELECT 1 FROM ::account_bannedips WHERE `type` = %i AND `ip` = %s AND `count` >= %i AND `unbanDate` >= UNIX_TIMESTAMP()', IP_BAN_TYPE_REGISTRATION_ATTEMPT, User::$ip, Cfg::get('ACC_FAILED_AUTH_COUNT')))
if (DB::Aowow()->selectRow('SELECT 1 FROM ?_account_bannedips WHERE `type` = ?d AND `ip` = ? AND `count` >= ?d AND `unbanDate` >= UNIX_TIMESTAMP()', IP_BAN_TYPE_REGISTRATION_ATTEMPT, User::$ip, Cfg::get('ACC_FAILED_AUTH_COUNT')))
{
DB::Aowow()->qry('UPDATE ::account_bannedips SET `count` = `count` + 1, `unbanDate` = UNIX_TIMESTAMP() + %i WHERE `ip` = %s AND `type` = %i', Cfg::get('ACC_FAILED_AUTH_BLOCK'), User::$ip, IP_BAN_TYPE_REGISTRATION_ATTEMPT);
return Lang::account('inputbox', 'error', 'signupExceeded', [DateTime::formatTimeElapsedFloat(Cfg::get('ACC_FAILED_AUTH_BLOCK') * 1000)]);
DB::Aowow()->query('UPDATE ?_account_bannedips SET `count` = `count` + 1, `unbanDate` = UNIX_TIMESTAMP() + ?d WHERE `ip` = ? AND `type` = ?d', Cfg::get('ACC_FAILED_AUTH_BLOCK'), User::$ip, IP_BAN_TYPE_REGISTRATION_ATTEMPT);
return Lang::account('inputbox', 'error', 'signupExceeded', [Util::formatTime(Cfg::get('ACC_FAILED_AUTH_BLOCK') * 1000)]);
}
// username / email taken
if ($inUseData = DB::Aowow()->SelectRow('SELECT `id`, `username`, `status` = %i AND `statusTimer` < UNIX_TIMESTAMP() AS "expired" FROM ::account WHERE (LOWER(`username`) = LOWER(%s) OR LOWER(`email`) = LOWER(%s))', ACC_STATUS_NEW, $this->_post['username'], $this->_post['email']))
if ($inUseData = DB::Aowow()->SelectRow('SELECT `id`, `username`, `status` = ?d AND `statusTimer` < UNIX_TIMESTAMP() AS "expired" FROM ?_account WHERE (LOWER(`username`) = LOWER(?) OR LOWER(`email`) = LOWER(?))', ACC_STATUS_NEW, $this->_post['username'], $this->_post['email']))
{
if ($inUseData['expired'])
DB::Aowow()->qry('DELETE FROM ::account WHERE `id` = %i', $inUseData['id']);
DB::Aowow()->query('DELETE FROM ?_account WHERE `id` = ?d', $inUseData['id']);
else
return Util::lower($inUseData['username']) == Util::lower($this->_post['username']) ? Lang::account('nameInUse') : Lang::account('mailInUse');
}
// create..
$token = Util::createHash();
$userId = DB::Aowow()->qry('INSERT INTO ::account (`login`, `passHash`, `username`, `email`, `joindate`, `curIP`, `locale`, `userGroups`, `status`, `statusTimer`, `token`) VALUES (%s, %s, %s, %s, UNIX_TIMESTAMP(), %s, %i, %i, %i, UNIX_TIMESTAMP() + %i, %s)',
$userId = DB::Aowow()->query('INSERT INTO ?_account (`login`, `passHash`, `username`, `email`, `joindate`, `curIP`, `locale`, `userGroups`, `status`, `statusTimer`, `token`) VALUES (?, ?, ?, ?, UNIX_TIMESTAMP(), ?, ?d, ?d, ?d, UNIX_TIMESTAMP() + ?d, ?)',
$this->_post['username'],
User::hashCrypt($this->_post['password']),
$this->_post['username'],
@ -143,14 +143,14 @@ class AccountSignupResponse extends TemplateResponse
return Lang::main('intError');
// create session tied to the token to store remember_me status
DB::Aowow()->qry('INSERT INTO ::account_sessions (`userId`, `sessionId`, `created`, `expires`, `touched`, `deviceInfo`, `ip`, `status`) VALUES (%i, %s, %i, %i, %i, %s, %s, %i)',
DB::Aowow()->query('INSERT INTO ?_account_sessions (`userId`, `sessionId`, `created`, `expires`, `touched`, `deviceInfo`, `ip`, `status`) VALUES (?d, ?, ?d, ?d, ?d, ?, ?, ?d)',
$userId, $token, time(), $this->_post['remember_me'] ? 0 : time() + Cfg::get('SESSION_TIMEOUT_DELAY'), time(), User::$agent, User::$ip, SESSION_ACTIVE);
if (!Util::sendMail($this->_post['email'], 'activate-account', [$token], Cfg::get('ACC_CREATE_SAVE_DECAY')))
return Lang::main('intError2', ['send mail']);
// success: update ip-bans
DB::Aowow()->qry('INSERT INTO ::account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (%s, %i, 1, UNIX_TIMESTAMP() + %i) ON DUPLICATE KEY UPDATE `count` = `count` + 1, `unbanDate` = UNIX_TIMESTAMP() + %i',
DB::Aowow()->query('INSERT INTO ?_account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (?, ?d, 1, UNIX_TIMESTAMP() + ?d) ON DUPLICATE KEY UPDATE `count` = `count` + 1, `unbanDate` = UNIX_TIMESTAMP() + ?d',
User::$ip, IP_BAN_TYPE_REGISTRATION_ATTEMPT, Cfg::get('ACC_FAILED_AUTH_BLOCK'), Cfg::get('ACC_FAILED_AUTH_BLOCK'));
Util::gainSiteReputation($userId, SITEREP_ACTION_REGISTER);

View file

@ -37,7 +37,7 @@ class AccountUpdatecommunitysettingsResponse extends TextResponse
return Lang::main('genericError');
// description - 0 modified rows is still success
if (!is_int(DB::Aowow()->qry('UPDATE ::account SET `description` = %s WHERE `id` = %i', $this->_post['desc'], User::$id)))
if (!is_int(DB::Aowow()->query('UPDATE ?_account SET `description` = ? WHERE `id` = ?d', $this->_post['desc'], User::$id)))
return Lang::main('genericError');
$this->success = true;

View file

@ -22,12 +22,12 @@ class AccountUpdateemailResponse extends TextResponse
private bool $success = false;
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
if (Cfg::get('ACC_AUTH_MODE') != AUTH_MODE_SELF)
(new TemplateResponse())->generateError();
parent::__construct($rawParam);
parent::__construct($pageParam);
}
protected function generate() : void
@ -48,21 +48,21 @@ class AccountUpdateemailResponse extends TextResponse
if (!$this->_post['newemail'])
return Lang::account('emailInvalid');
if (DB::Aowow()->selectCell('SELECT 1 FROM ::account WHERE `email` = %s AND `id` <> %i', $this->_post['newemail'], User::$id))
if (DB::Aowow()->selectCell('SELECT 1 FROM ?_account WHERE `email` = ? AND `id` <> ?d', $this->_post['newemail'], User::$id))
return Lang::account('mailInUse');
$status = DB::Aowow()->selectCell('SELECT `status` FROM ::account WHERE `statusTimer` > UNIX_TIMESTAMP() AND `id` = %i', User::$id);
$status = DB::Aowow()->selectCell('SELECT `status` FROM ?_account WHERE `statusTimer` > UNIX_TIMESTAMP() AND `id` = ?d', User::$id);
if ($status != ACC_STATUS_NONE && $status != ACC_STATUS_CHANGE_EMAIL)
return Lang::account('inputbox', 'error', 'isRecovering', [DateTime::formatTimeElapsedFloat(Cfg::get('ACC_RECOVERY_DECAY') * 1000)]);
return Lang::account('isRecovering', [Util::formatTime(Cfg::get('ACC_RECOVERY_DECAY') * 1000)]);
$oldEmail = DB::Aowow()->selectCell('SELECT `email` FROM ::account WHERE `id` = %i', User::$id);
$oldEmail = DB::Aowow()->selectCell('SELECT `email` FROM ?_account WHERE `id` = ?d', User::$id);
if ($this->_post['newemail'] == $oldEmail)
return Lang::account('newMailDiff');
$token = Util::createHash();
// store new mail in updateValue field, exchange when confirmation mail gets confirmed
if (!DB::Aowow()->qry('UPDATE ::account SET `updateValue` = %s, `status` = %i, `statusTimer` = UNIX_TIMESTAMP() + %i, `token` = %s WHERE `id` = %i',
if (!DB::Aowow()->query('UPDATE ?_account SET `updateValue` = ?, `status` = ?d, `statusTimer` = UNIX_TIMESTAMP() + ?d, `token` = ? WHERE `id` = ?d',
$this->_post['newemail'], ACC_STATUS_CHANGE_EMAIL, Cfg::get('ACC_RECOVERY_DECAY'), $token, User::$id))
return Lang::main('intError');

View file

@ -41,15 +41,15 @@ class AccountUpdategeneralsettingsResponse extends TextResponse
if ($this->_post['modelrace'] && !ChrRace::tryFrom($this->_post['modelrace']))
return Lang::main('genericError');
// js handles this as cookie, so saved as cookie; Q - also save in ::account table?
if (!DB::Aowow()->qry('REPLACE INTO ::account_cookies (`userId`, `name`, `data`) VALUES (%i, %s, %s)', User::$id, 'default_3dmodel', $this->_post['modelrace']. ',' . $this->_post['modelgender']))
// js handles this as cookie, so saved as cookie; Q - also save in ?_account table?
if (!DB::Aowow()->query('REPLACE INTO ?_account_cookies (`userId`, `name`, `data`) VALUES (?d, ?, ?)', User::$id, 'default_3dmodel', $this->_post['modelrace']. ',' . $this->_post['modelgender']))
return Lang::main('genericError');
if (!setcookie('default_3dmodel', $this->_post['modelrace']. ',' . $this->_post['modelgender'], 0, '/'))
return Lang::main('intError');
// int > number of edited rows > no changes is still success
if (!is_int(DB::Aowow()->qry('UPDATE ::account SET `debug` = %i WHERE `id` = %i', $this->_post['idsInLists'] ? 1 : 0, User::$id)))
if (!is_int(DB::Aowow()->query('UPDATE ?_account SET `debug` = ?d WHERE `id` = ?d', $this->_post['idsInLists'] ? 1 : 0, User::$id)))
return Lang::main('intError');
$this->success = true;

View file

@ -25,12 +25,12 @@ class AccountUpdatepasswordResponse extends TextResponse
private bool $success = false;
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
if (Cfg::get('ACC_AUTH_MODE') != AUTH_MODE_SELF)
(new TemplateResponse())->generateError();
parent::__construct($rawParam);
parent::__construct($pageParam);
}
protected function generate() : void
@ -48,14 +48,14 @@ class AccountUpdatepasswordResponse extends TextResponse
return Lang::main('intError');
if (!Util::validatePassword($this->_post['newPassword'], $e))
return $e == 1 ? Lang::account('errPassLength') : Lang::main('intError');
return Lang::account($e == 1 ? 'errPassLength' : 'errPassChars');
if ($this->_post['newPassword'] !== $this->_post['confirmPassword'])
return Lang::account('passMismatch');
$userData = DB::Aowow()->selectRow('SELECT `status`, `passHash`, `statusTimer` FROM ::account WHERE `id` = %i', User::$id);
$userData = DB::Aowow()->selectRow('SELECT `status`, `passHash`, `statusTimer` FROM ?_account WHERE `id` = ?d', User::$id);
if ($userData['status'] != ACC_STATUS_NONE && $userData['status'] != ACC_STATUS_CHANGE_PASS && $userData['statusTimer'] > time())
return Lang::account('inputbox', 'error', 'isRecovering', [DateTime::formatTimeElapsedFloat(Cfg::get('ACC_RECOVERY_DECAY') * 1000)]);
return Lang::account('isRecovering', [Util::formatTime(Cfg::get('ACC_RECOVERY_DECAY') * 1000)]);
if (!User::verifyCrypt($this->_post['currentPassword'], $userData['passHash']))
return Lang::account('wrongPass');
@ -66,17 +66,17 @@ class AccountUpdatepasswordResponse extends TextResponse
$token = Util::createHash();
// store new hash in updateValue field, exchange when confirmation mail gets confirmed
if (!DB::Aowow()->qry('UPDATE ::account SET `updateValue` = %s, `status` = %i, `statusTimer` = UNIX_TIMESTAMP() + %i, `token` = %s WHERE `id` = %i',
if (!DB::Aowow()->query('UPDATE ?_account SET `updateValue` = ?, `status` = ?d, `statusTimer` = UNIX_TIMESTAMP() + ?d, `token` = ? WHERE `id` = ?d',
User::hashCrypt($this->_post['newPassword']), ACC_STATUS_CHANGE_PASS, Cfg::get('ACC_RECOVERY_DECAY'), $token, User::$id))
return Lang::main('intError');
$email = DB::Aowow()->selectCell('SELECT `email` FROM ::account WHERE `id` = %i', User::$id);
$email = DB::Aowow()->selectCell('SELECT `email` FROM ?_account WHERE `id` = ?d', User::$id);
if (!Util::sendMail($email, 'update-password', [$token, $email], Cfg::get('ACC_RECOVERY_DECAY')))
return Lang::main('intError2', ['send mail']);
// logout all other active sessions
if ($this->_post['globalLogout'])
DB::Aowow()->qry('UPDATE ::account_sessions SET `status` = %i, `touched` = %i WHERE `userId` = %i AND `sessionId` <> ? AND `status` = %i', SESSION_FORCED_LOGOUT, time(), User::$id, session_id(), SESSION_ACTIVE);
DB::Aowow()->query('UPDATE ?_account_sessions SET `status` = ?d, `touched` = ?d WHERE `userId` = ?d AND `sessionId` <> ? AND `status` = ?d', SESSION_FORCED_LOGOUT, time(), User::$id, session_id(), SESSION_ACTIVE);
$this->success = true;
return Lang::account('updateMessage', 'personal', [User::$email]);

View file

@ -22,12 +22,12 @@ class AccountUpdateusernameResponse extends TextResponse
private bool $success = false;
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
if (Cfg::get('ACC_AUTH_MODE') != AUTH_MODE_SELF)
(new TemplateResponse())->generateError();
parent::__construct($rawParam);
parent::__construct($pageParam);
}
protected function generate() : void
@ -44,14 +44,14 @@ class AccountUpdateusernameResponse extends TextResponse
if (!$this->assertPOST('newUsername'))
return Lang::main('intError');
if (DB::Aowow()->selectCell('SELECT `renameCooldown` FROM ::account WHERE `id` = %i', User::$id) > time())
if (DB::Aowow()->selectCell('SELECT `renameCooldown` FROM ?_account WHERE `id` = ?d', User::$id) > time())
return Lang::main('intError'); // should have grabbed the error response..
// yes, including your current name. you don't want to change into your current name, right?
if (DB::Aowow()->selectCell('SELECT 1 FROM ::account WHERE LOWER(`username`) = LOWER(%s)', $this->_post['newUsername']))
if (DB::Aowow()->selectCell('SELECT 1 FROM ?_account WHERE LOWER(`username`) = LOWER(?)', $this->_post['newUsername']))
return Lang::account('nameInUse');
DB::Aowow()->qry('UPDATE ::account SET `username` = %s, `renameCooldown` = %i WHERE `id` = %i', $this->_post['newUsername'], time() + Cfg::get('acc_rename_decay'), User::$id);
DB::Aowow()->query('UPDATE ?_account SET `username` = ?, `renameCooldown` = ?d WHERE `id` = ?d', $this->_post['newUsername'], time() + Cfg::get('acc_rename_decay'), User::$id);
$this->success = true;
return Lang::account('updateMessage', 'username', [User::$username, $this->_post['newUsername']]);

View file

@ -46,11 +46,11 @@ class AccountWeightscalesResponse extends TextResponse
if (!$this->assertPOST('name', 'scale'))
return;
$nScales = DB::Aowow()->selectCell('SELECT COUNT(`id`) FROM ::account_weightscales WHERE `userId` = %i', User::$id);
$nScales = DB::Aowow()->selectCell('SELECT COUNT(`id`) FROM ?_account_weightscales WHERE `userId` = ?d', User::$id);
if ($nScales >= self::MAX_SCALES)
return;
if ($id = DB::Aowow()->qry('INSERT INTO ::account_weightscales (`userId`, `name`) VALUES (%i, %s)', User::$id, $this->_post['name']))
if ($id = DB::Aowow()->query('INSERT INTO ?_account_weightscales (`userId`, `name`) VALUES (?d, ?)', User::$id, $this->_post['name']))
if ($this->storeScaleData($id))
$this->result = $id;
}
@ -61,13 +61,13 @@ class AccountWeightscalesResponse extends TextResponse
return;
// not in DB or not owned by user
if (!DB::Aowow()->selectCell('SELECT 1 FROM ::account_weightscales WHERE `userId` = %i AND `id` = %i', User::$id, $this->_post['id']))
if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_account_weightscales WHERE `userId` = ?d AND `id` = ?d', User::$id, $this->_post['id']))
{
trigger_error('AccountWeightscalesResponse::updateWeights - scale #'.$this->_post['id'].' not in db or not owned by user #'.User::$id, E_USER_ERROR);
return;
}
DB::Aowow()->qry('UPDATE ::account_weightscales SET `name` = %s WHERE `id` = %i', $this->_post['name'], $this->_post['id']);
DB::Aowow()->query('UPDATE ?_account_weightscales SET `name` = ? WHERE `id` = ?d', $this->_post['name'], $this->_post['id']);
$this->storeScaleData($this->_post['id']);
// return edited id on success
@ -77,24 +77,20 @@ class AccountWeightscalesResponse extends TextResponse
private function deleteWeights() : void
{
if ($this->assertPOST('id'))
DB::Aowow()->qry('DELETE FROM ::account_weightscales WHERE `id` = %i AND `userId` = %i', $this->_post['id'], User::$id);
DB::Aowow()->query('DELETE FROM ?_account_weightscales WHERE `id` = ?d AND `userId` = ?d', $this->_post['id'], User::$id);
$this->result = '';
}
private function storeScaleData(int $scaleId) : bool
{
if (!is_int(DB::Aowow()->qry('DELETE FROM ::account_weightscale_data WHERE `id` = %i', $scaleId)))
if (!is_int(DB::Aowow()->query('DELETE FROM ?_account_weightscale_data WHERE `id` = ?d', $scaleId)))
return false;
// $x['val'] is known to be a positive int due to regex check
$scaleData = array_filter($this->_post['scale'], fn($x) => Stat::getWeightJson($x['field']) && $x['val'] > 0);
array_walk($scaleData, fn(&$x) => $x['id'] = $scaleId);
foreach ($scaleData as $sd)
if (is_null(DB::Aowow()->qry('INSERT INTO ::account_weightscale_data %v', $sd)))
return false;
foreach ($this->_post['scale'] as [$k, $v])
if (in_array($k, Util::$weightScales)) // $v is known to be a positive int due to regex check
if (!is_int(DB::Aowow()->query('INSERT INTO ?_account_weightscale_data VALUES (?d, ?, ?d)', $scaleId, $k, $v)))
return false;
return true;
}
@ -107,7 +103,7 @@ class AccountWeightscalesResponse extends TextResponse
protected static function checkScale(string $val) : array
{
if (preg_match('/^((\w+:\d+)(,\w+:\d+)*)$/', $val))
return array_map(fn($x) => array_combine(['field', 'val'], explode(':', $x)), explode(',', $val));
return array_map(fn($x) => explode(':', $x), explode(',', $val));
return [];
}

View file

@ -21,7 +21,7 @@ class AchievementBaseResponse extends TemplateResponse implements ICache
{
use TrDetailPage, TrCache;
protected int $cacheType = CACHE_TYPE_DETAIL_PAGE;
protected int $cacheType = CACHE_TYPE_PAGE;
protected string $template = 'achievement';
protected string $pageName = 'achievement';
@ -73,7 +73,7 @@ class AchievementBaseResponse extends TemplateResponse implements ICache
while ($curCat > 0)
{
$catPath[] = $curCat;
$curCat = DB::Aowow()->SelectCell('SELECT `parentCat` FROM ::achievementcategory WHERE `id` = %i', $curCat);
$curCat = DB::Aowow()->SelectCell('SELECT `parentCat` FROM ?_achievementcategory WHERE `id` = ?d', $curCat);
}
$this->breadcrumb = array_merge($this->breadcrumb, array_reverse($catPath));
@ -107,32 +107,15 @@ class AchievementBaseResponse extends TemplateResponse implements ICache
default => Lang::game('si', SIDE_BOTH) // 0, 3
};
// id
$infobox[] = Lang::achievement('id') . $this->typeId;
// icon
if ($_ = $this->subject->getField('iconId'))
{
$infobox[] = Util::ucFirst(Lang::game('icon')).Lang::main('colon').'[icondb='.$_.' name=true]';
$infobox[] = Util::ucFirst(lang::game('icon')).Lang::main('colon').'[icondb='.$_.' name=true]';
$this->extendGlobalIds(Type::ICON, $_);
}
// profiler relateed (note that this is part of the cache. I don't think this is important enough to calc for every view)
if (Cfg::get('PROFILER_ENABLE') && !($this->subject->getField('flags') & ACHIEVEMENT_FLAG_COUNTER))
{
$x = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ::profiler_completion_achievements WHERE `achievementId` = %i', $this->typeId);
$y = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ::profiler_profiles WHERE `custom` = 0 AND `stub` = 0');
$infobox[] = Lang::profiler('attainedBy', [round(($x ?: 0) * 100 / ($y ?: 1))]);
// completion row added by InfoboxMarkup
}
// original name
if (Lang::getLocale() != Locale::EN)
$infobox[] = Util::ucFirst(Lang::lang(Locale::EN->value) . Lang::main('colon')) . '[copy button=false]'.$this->subject->getField('name_loc0').'[/copy][/li]';
if ($infobox)
$this->infobox = new InfoboxMarkup($infobox, ['allow' => Markup::CLASS_STAFF, 'dbpage' => true], 'infobox-contents0', !($this->subject->getField('flags') & ACHIEVEMENT_FLAG_COUNTER));
$this->infobox = new InfoboxMarkup($infobox, ['allow' => Markup::CLASS_STAFF, 'dbpage' => true], 'infobox-contents0');
/**********/
@ -207,7 +190,7 @@ class AchievementBaseResponse extends TemplateResponse implements ICache
$this->rewards = [$rewItems, $rewTitles, $text];
// factionchange-equivalent
if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = %i, `alliance_id`, -`horde_id`) FROM player_factionchange_achievement WHERE `alliance_id` = %i OR `horde_id` = %i', $this->typeId, $this->typeId, $this->typeId))
if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = ?d, `alliance_id`, -`horde_id`) FROM player_factionchange_achievement WHERE `alliance_id` = ?d OR `horde_id` = ?d', $this->typeId, $this->typeId, $this->typeId))
{
$altAcv = new AchievementList(array(['id', abs($pendant)]));
if (!$altAcv->error)
@ -230,7 +213,7 @@ class AchievementBaseResponse extends TemplateResponse implements ICache
// serverside extra-Data (not sure why ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE is set, let a lone a couple hundred times)
if ($crtIds = array_column($this->subject->getCriteria(), 'id'))
$crtExtraData = DB::World()->selectAssoc('SELECT `criteria_id` AS ARRAY_KEY, `type` AS ARRAY_KEY2, `value1`, `value2`, `ScriptName` FROM achievement_criteria_data WHERE `type` <> %i AND `criteria_id` IN %in', ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE, $crtIds);
$crtExtraData = DB::World()->select('SELECT `criteria_id` AS ARRAY_KEY, `type` AS ARRAY_KEY2, `value1`, `value2`, `ScriptName` FROM achievement_criteria_data WHERE `type` <> ?d AND `criteria_id` IN (?a)', ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE, $crtIds);
else
$crtExtraData = [];
@ -261,7 +244,7 @@ class AchievementBaseResponse extends TemplateResponse implements ICache
case ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA:
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
$zoneId = DB::Aowow()->selectCell('SELECT `id` FROM ::zones WHERE `mapId` = %s', $obj);
$zoneId = DB::Aowow()->selectCell('SELECT `id` FROM ?_zones WHERE `mapId` = ?', $obj);
$crtIcon = new IconElement(Type::ZONE, $zoneId ?: 0, $crtName ?: ZoneList::getName($zoneId), size: IconElement::SIZE_SMALL, element: 'iconlist-icon');
break;
// link to area
@ -370,17 +353,8 @@ class AchievementBaseResponse extends TemplateResponse implements ICache
$extraData[] = '<a href="?event='.$we->id.'">'.$we->getField('name', true).'</a>';
break;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID:
$extraData[] = match((int)$xData['value1'])
{
0 => Lang::maps('EasternKingdoms'),
1 => Lang::maps('Kalimdor'),
530 => Lang::maps('Outland'),
571 => Lang::maps('Northrend'),
default => (function(int $mapId) {
$z = new ZoneList(array(['mapId', $mapId]));
return '<a href="?zone='.$z->id.'">'.$z->getField('name', true).'</a>';
})($xData['value1'])
};
if ($z = new ZoneList(array(['mapIdBak', $xData['value1']])))
$extraData[] = '<a href="?zone='.$z->id.'">'.$z->getField('name', true).'</a>';
break;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE:
$extraData[] = TitleList::makeLink($xData['value1']);
@ -423,7 +397,7 @@ class AchievementBaseResponse extends TemplateResponse implements ICache
}
// tab: criteria of
$refs = DB::Aowow()->SelectCol('SELECT `refAchievementId` FROM ::achievementcriteria WHERE `type` = %i AND `value1` = %i',
$refs = DB::Aowow()->SelectCol('SELECT `refAchievementId` FROM ?_achievementcriteria WHERE `type` = ?d AND `value1` = ?d',
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT,
$this->typeId
);
@ -463,7 +437,7 @@ class AchievementBaseResponse extends TemplateResponse implements ICache
{
if ($_ = $this->subject->getField('mailTemplate'))
{
$letter = DB::Aowow()->selectRow('SELECT * FROM ::mails WHERE `id` = %i', $_);
$letter = DB::Aowow()->selectRow('SELECT * FROM ?_mails WHERE `id` = ?d', $_);
if (!$letter)
return false;
@ -502,7 +476,7 @@ class AchievementBaseResponse extends TemplateResponse implements ICache
$avlb = [];
foreach (Profiler::getRealms() AS $rId => $rData)
if (!DB::Characters($rId)->selectCell('SELECT 1 FROM character_achievement WHERE `achievement` = %i', $pt->typeId))
if (!DB::Characters($rId)->selectCell('SELECT 1 FROM character_achievement WHERE `achievement` = ?d', $pt->typeId))
$avlb[] = Util::ucWords($rData['name']);
if (!$avlb)

View file

@ -11,7 +11,7 @@ class AchievementsBaseResponse extends TemplateResponse implements ICache
use TrListPage, TrCache;
protected int $type = Type::ACHIEVEMENT;
protected int $cacheType = CACHE_TYPE_LIST_PAGE;
protected int $cacheType = CACHE_TYPE_PAGE;
protected string $template = 'achievements';
protected string $pageName = 'achievements';
@ -46,22 +46,14 @@ class AchievementsBaseResponse extends TemplateResponse implements ICache
)
);
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
$this->getCategoryFromUrl($rawParam);
$this->getCategoryFromUrl($pageParam);
parent::__construct($rawParam);
if ($this->category)
$this->subCat = '='.implode('.', $this->category);
parent::__construct($pageParam);
$this->subCat = $pageParam !== '' ? '='.$pageParam : '';
$this->filter = new AchievementListFilter($this->_get['filter'] ?? '', ['parentCats' => $this->category]);
if ($this->filter->shouldReload)
{
$_SESSION['error']['fi'] = $this->filter::class;
$get = $this->filter->buildGETParam();
$this->forward('?' . $this->pageName . $this->subCat . ($get ? '&filter=' . $get : ''));
}
$this->filterError = $this->filter->error;
}
@ -69,7 +61,7 @@ class AchievementsBaseResponse extends TemplateResponse implements ICache
{
$this->h1 = Util::ucFirst(Lang::game('achievements'));
$conditions = [Listview::DEFAULT_SIZE];
$conditions = [];
if (!User::isInGroup(U_GROUP_EMPLOYEE))
$conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0];
@ -77,9 +69,13 @@ class AchievementsBaseResponse extends TemplateResponse implements ICache
if ($this->category)
$conditions[] = ['category', end($this->category)];
$this->filter->evalCriteria();
if ($fiCnd = $this->filter->getConditions())
$conditions[] = $fiCnd;
$this->filterError = $this->filter->error; // maybe the evalX() caused something
/*************/
/* Menu Path */
@ -120,10 +116,10 @@ class AchievementsBaseResponse extends TemplateResponse implements ICache
if (!$acvList->getMatches() && $this->category)
{
// ToDo - we also branch into here if the filter prohibits results. That should be skipped.
$conditions = [Listview::DEFAULT_SIZE];
$conditions = [];
if ($fiCnd)
$conditions[] = $fiCnd;
if ($catList = DB::Aowow()->SelectCol('SELECT `id` FROM ::achievementcategory WHERE `parentCat` IN %in OR `parentCat2` IN %in ', $this->category, $this->category))
if ($catList = DB::Aowow()->SelectCol('SELECT `id` FROM ?_achievementcategory WHERE `parentCat` IN (?a) OR `parentCat2` IN (?a) ', end($this->category), end($this->category)))
$conditions[] = ['category', $catList];
$acvList = new AchievementList($conditions, ['calcTotal' => true]);
@ -145,9 +141,9 @@ class AchievementsBaseResponse extends TemplateResponse implements ICache
$tabData['extraCols'] = '$fi_getExtraCols(fi_extraCols, 0, 0)';
// create note if search limit was exceeded
if ($acvList->getMatches() > Listview::DEFAULT_SIZE)
if ($acvList->getMatches() > Cfg::get('SQL_LIMIT_DEFAULT'))
{
$tabData['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_achievementsfound', $acvList->getMatches(), Listview::DEFAULT_SIZE);
$tabData['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_achievementsfound', $acvList->getMatches(), Cfg::get('SQL_LIMIT_DEFAULT'));
$tabData['_truncated'] = 1;
}
}

View file

@ -44,13 +44,13 @@ class AdminAnnouncementsResponse extends TemplateResponse
return;
}
if (!DB::Aowow()->selectCell('SELECT 1 FROM ::announcements WHERE `id` = %i', $this->_get['id']))
if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_announcements WHERE `id` = ?d', $this->_get['id']))
{
trigger_error('AdminAnnouncementsResponse::updateStatus - announcement does not exist');
return;
}
DB::Aowow()->qry('UPDATE ::announcements SET `status` = %i WHERE `id` = %i', $this->_get['status'], $this->_get['id']);
DB::Aowow()->query('UPDATE ?_announcements SET `status` = ?d WHERE `id` = ?d', $this->_get['status'], $this->_get['id']);
}
private function displayEditor() : void

View file

@ -33,13 +33,13 @@ class AdminCommentResponse extends TextResponse
$ok = false;
if ($this->_post['status']) // outdated, mark as deleted and clear other flags (sticky + outdated)
{
if ($ok = DB::Aowow()->qry('UPDATE ::comments SET `flags` = %i, `deleteUserId` = %i, `deleteDate` = %i WHERE `id` = %i', CC_FLAG_DELETED, User::$id, time(), $this->_post['id']))
if ($ok = DB::Aowow()->query('UPDATE ?_comments SET `flags` = ?d, `deleteUserId` = ?d, `deleteDate` = ?d WHERE `id` = ?d', CC_FLAG_DELETED, User::$id, time(), $this->_post['id']))
if ($rep = new Report(Report::MODE_COMMENT, Report::CO_OUT_OF_DATE, $this->_post['id']))
$rep->close(Report::STATUS_CLOSED_SOLVED);
}
else // up to date
{
if ($ok = DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` & ~%i WHERE `id` = %i', CC_FLAG_OUTDATED, $this->_post['id']))
if ($ok = DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` & ~?d WHERE `id` = ?d', CC_FLAG_OUTDATED, $this->_post['id']))
if ($rep = new Report(Report::MODE_COMMENT, Report::CO_OUT_OF_DATE, $this->_post['id']))
$rep->close(Report::STATUS_CLOSED_WONTFIX);
}

View file

@ -31,7 +31,7 @@ class AdminGuideResponse extends TextResponse
return;
}
$guide = DB::Aowow()->selectRow('SELECT `userId`, `status` FROM ::guides WHERE `id` = %i', $this->_post['id']);
$guide = DB::Aowow()->selectRow('SELECT `userId`, `status` FROM ?_guides WHERE `id` = ?d', $this->_post['id']);
if (!$guide)
{
trigger_error('AdminGuideResponse - guide #'.$this->_post['id'].' not found', E_USER_ERROR);
@ -63,16 +63,16 @@ class AdminGuideResponse extends TextResponse
private function update(int $id, int $status, ?string $msg = null) : bool
{
if ($status == GuideMgr::STATUS_APPROVED) // set display rev to latest
$ok = DB::Aowow()->qry('UPDATE ::guides SET `status` = %i, `rev` = (SELECT `rev` FROM ::articles WHERE `type` = %i AND `typeId` = %i ORDER BY `rev` DESC LIMIT 1), `approveUserId` = %i, `approveDate` = %i WHERE `id` = %i', $status, Type::GUIDE, $id, User::$id, time(), $id);
$ok = DB::Aowow()->query('UPDATE ?_guides SET `status` = ?d, `rev` = (SELECT `rev` FROM ?_articles WHERE `type` = ?d AND `typeId` = ?d ORDER BY `rev` DESC LIMIT 1), `approveUserId` = ?d, `approveDate` = ?d WHERE `id` = ?d', $status, Type::GUIDE, $id, User::$id, time(), $id);
else
$ok = DB::Aowow()->qry('UPDATE ::guides SET `status` = %i WHERE `id` = %i', $status, $id);
$ok = DB::Aowow()->query('UPDATE ?_guides SET `status` = ?d WHERE `id` = ?d', $status, $id);
if (!$ok)
return false;
DB::Aowow()->qry('INSERT INTO ::guides_changelog (`id`, `date`, `userId`, `status`) VALUES (%i, %i, %i, %i)', $id, time(), User::$id, $status);
DB::Aowow()->query('INSERT INTO ?_guides_changelog (`id`, `date`, `userId`, `status`) VALUES (?d, ?d, ?d, ?d)', $id, time(), User::$id, $status);
if ($msg)
DB::Aowow()->qry('INSERT INTO ::guides_changelog (`id`, `date`, `userId`, `msg`) VALUES (%i, %i, %i, %s)', $id, time(), User::$id, $msg);
DB::Aowow()->query('INSERT INTO ?_guides_changelog (`id`, `date`, `userId`, `msg`) VALUES (?d, ?d, ?d, ?)', $id, time(), User::$id, $msg);
return true;
}

View file

@ -30,7 +30,7 @@ class AdminGuidesResponse extends TemplateResponse
else
{
$data = $pending->getListviewData();
$latest = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, MAX(`rev`) FROM ::articles WHERE `type` = %i AND `typeId` IN %in GROUP BY `rev`', Type::GUIDE, $pending->getFoundIDs());
$latest = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, MAX(`rev`) FROM ?_articles WHERE `type` = ?d AND `typeId` IN (?a) GROUP BY `rev`', Type::GUIDE, $pending->getFoundIDs());
foreach ($latest as $id => $rev)
$data[$id]['rev'] = $rev;
}

View file

@ -52,7 +52,7 @@ class AdminScreenshotsResponse extends TemplateResponse
else if ($this->_get['user'])
{
if (mb_strlen($this->_get['user']) >= 3)
if ($uId = DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE LOWER(`username`) = LOWER(%s)', $this->_get['user']))
if ($uId = DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE LOWER(`username`) = LOWER(?)', $this->_get['user']))
$ssData = ScreenshotMgr::getScreenshots(userId: $uId, nFound: $nMatches);
}
else

View file

@ -2,6 +2,8 @@
namespace Aowow;
use GdImage;
if (!defined('AOWOW_REVISION'))
die('illegal access');
@ -25,7 +27,7 @@ class AdminScreenshotsActionApproveResponse extends TextResponse
ScreenshotMgr::init();
// create resized and thumb version of screenshot
$ssEntries = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `userIdOwner`, `date`, `type`, `typeId` FROM ::screenshots WHERE (`status` & %i) = 0 AND `id` IN %in', CC_FLAG_APPROVED, $this->_get['id']);
$ssEntries = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `userIdOwner`, `date`, `type`, `typeId` FROM ?_screenshots WHERE (`status` & ?d) = 0 AND `id` IN (?a)', CC_FLAG_APPROVED, $this->_get['id']);
foreach ($ssEntries as $id => $ssData)
{
if (!ScreenshotMgr::loadFile(ScreenshotMgr::PATH_PENDING, $id))
@ -42,14 +44,14 @@ class AdminScreenshotsActionApproveResponse extends TextResponse
continue;
// set as approved in DB
DB::Aowow()->qry('UPDATE ::screenshots SET `status` = %i, `userIdApprove` = %i WHERE `id` = %i', CC_FLAG_APPROVED, User::$id, $id);
DB::Aowow()->query('UPDATE ?_screenshots SET `status` = ?d, `userIdApprove` = ?d WHERE `id` = ?d', CC_FLAG_APPROVED, User::$id, $id);
// gain siterep
Util::gainSiteReputation($ssData['userIdOwner'], SITEREP_ACTION_SUBMIT_SCREENSHOT, ['id' => $id, 'what' => 1, 'date' => $ssData['date']]);
// flag DB entry as having screenshots
if ($tbl = Type::getClassAttrib($ssData['type'], 'dataTable'))
DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', $tbl, CUSTOM_HAS_SCREENSHOT, $ssData['typeId']);
DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_SCREENSHOT, $ssData['typeId']);
unset($ssEntries[$id]);
}

View file

@ -26,9 +26,9 @@ class AdminScreenshotsActionDeleteResponse extends TextResponse
foreach ($this->_get['id'] as $id)
{
// irrevocably purge files already flagged as deleted (should only exist as pending)
if (User::isInGroup(U_GROUP_ADMIN) && DB::Aowow()->selectCell('SELECT 1 FROM ::screenshots WHERE `status` & %i AND `id` = %i', CC_FLAG_DELETED, $id))
if (User::isInGroup(U_GROUP_ADMIN) && DB::Aowow()->selectCell('SELECT 1 FROM ?_screenshots WHERE `status` & ?d AND `id` = ?d', CC_FLAG_DELETED, $id))
{
DB::Aowow()->qry('DELETE FROM ::screenshots WHERE `id` = %i', $id);
DB::Aowow()->query('DELETE FROM ?_screenshots WHERE `id` = ?d', $id);
if (file_exists(sprintf(ScreenshotMgr::PATH_PENDING, $id)))
unlink(sprintf(ScreenshotMgr::PATH_PENDING, $id));
@ -47,16 +47,16 @@ class AdminScreenshotsActionDeleteResponse extends TextResponse
}
// flag as deleted if not aready
$oldEntries = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, GROUP_CONCAT(`typeId`) FROM ::screenshots WHERE `id` IN %in GROUP BY `type`', $this->_get['id']);
DB::Aowow()->qry('UPDATE ::screenshots SET `status` = %i, `userIdDelete` = %i WHERE `id` IN %in', CC_FLAG_DELETED, User::$id, $this->_get['id']);
$oldEntries = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, GROUP_CONCAT(`typeId`) FROM ?_screenshots WHERE `id` IN (?a) GROUP BY `type`', $this->_get['id']);
DB::Aowow()->query('UPDATE ?_screenshots SET `status` = ?d, `userIdDelete` = ?d WHERE `id` IN (?a)', CC_FLAG_DELETED, User::$id, $this->_get['id']);
// deflag db entry as having screenshots
foreach ($oldEntries as $type => $typeIds)
{
$typeIds = explode(',', $typeIds);
$toUnflag = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(BIT_OR(`status`) & %i, 1, 0) AS "hasMore" FROM ::screenshots WHERE `type` = %i AND `typeId` IN %in GROUP BY `typeId` HAVING `hasMore` = 0', CC_FLAG_APPROVED, $type, $typeIds);
$toUnflag = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(BIT_OR(`status`) & ?d, 1, 0) AS "hasMore" FROM ?_screenshots WHERE `type` = ?d AND `typeId` IN (?a) GROUP BY `typeId` HAVING `hasMore` = 0', CC_FLAG_APPROVED, $type, $typeIds);
if ($toUnflag && ($tbl = Type::getClassAttrib($type, 'dataTable')))
DB::Aowow()->qry('UPDATE %n SET cuFlags = cuFlags & ~%i WHERE id IN %in', $tbl, CUSTOM_HAS_SCREENSHOT, array_keys($toUnflag));
DB::Aowow()->query('UPDATE ?# SET cuFlags = cuFlags & ~?d WHERE id IN (?a)', $tbl, CUSTOM_HAS_SCREENSHOT, array_keys($toUnflag));
}
}
}

View file

@ -24,7 +24,7 @@ class AdminScreenshotsActionEditaltResponse extends TextResponse
if (!$this->assertGET('id'))
return;
DB::Aowow()->qry('UPDATE ::screenshots SET `caption` = %s WHERE `id` = %i',
DB::Aowow()->query('UPDATE ?_screenshots SET `caption` = ? WHERE `id` = ?d',
$this->handleCaption($this->_post['alt']),
$this->_get['id']
);

View file

@ -23,7 +23,7 @@ class AdminScreenshotsActionManageResponse extends TextResponse
if ($this->_get['type'] && $this->_get['typeid'])
$res = ScreenshotMgr::getScreenshots($this->_get['type'], $this->_get['typeid']);
else if ($this->_get['user'])
if ($uId = DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE LOWER(`username`) = LOWER(%s)', $this->_get['user']))
if ($uId = DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE LOWER(`username`) = LOWER(?)', $this->_get['user']))
$res = ScreenshotMgr::getScreenshots(userId: $uId);
$this->result = 'ssm_screenshotData = '.Util::toJSON($res);

View file

@ -24,7 +24,7 @@ class AdminScreenshotsActionRelocateResponse extends TextResponse
return;
}
[$type, $oldTypeId] = array_values(DB::Aowow()->selectRow('SELECT `type`, `typeId` FROM ::screenshots WHERE `id` = %i', $this->_get['id']));
[$type, $oldTypeId] = array_values(DB::Aowow()->selectRow('SELECT `type`, `typeId` FROM ?_screenshots WHERE `id` = ?d', $this->_get['id']));
$typeId = $this->_get['typeid'];
if (Type::validateIds($type, $typeId))
@ -32,15 +32,15 @@ class AdminScreenshotsActionRelocateResponse extends TextResponse
$tbl = Type::getClassAttrib($type, 'dataTable');
// move screenshot
DB::Aowow()->qry('UPDATE ::screenshots SET `typeId` = %i WHERE `id` = %i', $typeId, $this->_get['id']);
DB::Aowow()->query('UPDATE ?_screenshots SET `typeId` = ?d WHERE `id` = ?d', $typeId, $this->_get['id']);
// flag target as having screenshot
DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', $tbl, CUSTOM_HAS_SCREENSHOT, $typeId);
DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_SCREENSHOT, $typeId);
// deflag source for having had screenshots (maybe)
$ssInfo = DB::Aowow()->selectRow('SELECT IF(BIT_OR(~`status`) & %i, 1, 0) AS "hasMore" FROM ::screenshots WHERE `status`& %i AND `type` = %i AND `typeId` = %i', CC_FLAG_DELETED, CC_FLAG_APPROVED, $type, $oldTypeId);
$ssInfo = DB::Aowow()->selectRow('SELECT IF(BIT_OR(~`status`) & ?d, 1, 0) AS "hasMore" FROM ?_screenshots WHERE `status`& ?d AND `type` = ?d AND `typeId` = ?d', CC_FLAG_DELETED, CC_FLAG_APPROVED, $type, $oldTypeId);
if ($ssInfo || !$ssInfo['hasMore'])
DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` & ~%i WHERE `id` = %i', $tbl, CUSTOM_HAS_SCREENSHOT, $oldTypeId);
DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` & ~?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_SCREENSHOT, $oldTypeId);
}
else
trigger_error('AdminScreenshotsActionRelocateResponse - invalid typeId #'.$typeId.' for type #'.$type, E_USER_ERROR);

View file

@ -25,7 +25,7 @@ class AdminScreenshotsActionStickyResponse extends TextResponse
// this one is a bit strange: as far as i've seen, the only thing a 'sticky' screenshot does is show up in the infobox
// this also means, that only one screenshot per page should be sticky
// so, handle it one by one and the last one affecting one particular type/typId-key gets the cake
$ssEntries = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `userIdOwner`, `date`, `type`, `typeId`, `status` FROM ::screenshots WHERE (`status` & %i) = 0 AND `id` IN %in', CC_FLAG_DELETED, $this->_get['id']);
$ssEntries = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `userIdOwner`, `date`, `type`, `typeId`, `status` FROM ?_screenshots WHERE (`status` & ?d) = 0 AND `id` IN (?a)', CC_FLAG_DELETED, $this->_get['id']);
foreach ($ssEntries as $id => $ssData)
{
// approve yet unapproved screenshots
@ -47,21 +47,21 @@ class AdminScreenshotsActionStickyResponse extends TextResponse
continue;
// set as approved in DB
DB::Aowow()->qry('UPDATE ::screenshots SET `status` = %i, `userIdApprove` = %i WHERE `id` = %i', CC_FLAG_APPROVED, User::$id, $id);
DB::Aowow()->query('UPDATE ?_screenshots SET `status` = ?d, `userIdApprove` = ?d WHERE `id` = ?d', CC_FLAG_APPROVED, User::$id, $id);
// gain siterep
Util::gainSiteReputation($ssData['userIdOwner'], SITEREP_ACTION_SUBMIT_SCREENSHOT, ['id' => $id, 'what' => 1, 'date' => $ssData['date']]);
// flag DB entry as having screenshots
if ($tbl = Type::getClassAttrib($ssData['type'], 'dataTable'))
DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', $tbl, CUSTOM_HAS_SCREENSHOT, $ssData['typeId']);
DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_SCREENSHOT, $ssData['typeId']);
}
// reset all others
DB::Aowow()->qry('UPDATE ::screenshots a, ::screenshots b SET a.`status` = a.`status` & ~%i WHERE a.`type` = b.`type` AND a.`typeId` = b.`typeId` AND a.`id` <> b.`id` AND b.`id` = %i', CC_FLAG_STICKY, $id);
DB::Aowow()->query('UPDATE ?_screenshots a, ?_screenshots b SET a.`status` = a.`status` & ~?d WHERE a.`type` = b.`type` AND a.`typeId` = b.`typeId` AND a.`id` <> b.`id` AND b.`id` = ?d', CC_FLAG_STICKY, $id);
// toggle sticky status
DB::Aowow()->qry('UPDATE ::screenshots SET `status` = IF(`status` & %i, `status` & ~%i, `status` | %i) WHERE `id` = %i AND `status` & %i', CC_FLAG_STICKY, CC_FLAG_STICKY, CC_FLAG_STICKY, $id, CC_FLAG_APPROVED);
DB::Aowow()->query('UPDATE ?_screenshots SET `status` = IF(`status` & ?d, `status` & ~?d, `status` | ?d) WHERE `id` = ?d AND `status` & ?d', CC_FLAG_STICKY, CC_FLAG_STICKY, CC_FLAG_STICKY, $id, CC_FLAG_APPROVED);
unset($ssEntries[$id]);
}

View file

@ -2,6 +2,8 @@
namespace Aowow;
use Error;
if (!defined('AOWOW_REVISION'))
die('illegal access');
@ -45,7 +47,7 @@ class AdminSpawnoverrideResponse extends TextResponse
return;
}
DB::Aowow()->qry('REPLACE INTO ::spawns_override (`type`, `typeGuid`, `areaId`, `floor`, `revision`) VALUES (%i, %i, %i, %i, %i)', $type, $guid, $area, $floor, AOWOW_REVISION);
DB::Aowow()->query('REPLACE INTO ?_spawns_override (`type`, `typeGuid`, `areaId`, `floor`, `revision`) VALUES (?d, ?d, ?d, ?d, ?d)', $type, $guid, $area, $floor, AOWOW_REVISION);
$wPos = WorldPosition::getForGUID($type, $guid);
if (!$wPos)
@ -72,30 +74,39 @@ class AdminSpawnoverrideResponse extends TextResponse
// if creature try for waypoints
if ($type == Type::NPC)
{
if ($swp = DB::World()->selectAssoc('SELECT -w.`id` AS "entry", w.`point` AS "pointId", w.`position_x` AS "posX", w.`position_y` AS "posY" FROM creature_addon ca JOIN waypoint_data w ON w.`id` = ca.`path_id` WHERE ca.`guid` = %i AND ca.`path_id` <> 0', $guid))
{
foreach ($swp as $w)
{
if ($point = WorldPosition::toZonePos($wPos[$guid]['mapId'], $w['posX'], $w['posY'], $area, $floor))
{
$p = array(
'posX' => $point[0]['posX'],
'posY' => $point[0]['posY'],
'areaId' => $point[0]['areaId'],
'floor' => $point[0]['floor']
);
$jobs = array(
'SELECT -w.`id` AS "entry", w.`point` AS "pointId", w.`position_x` AS "posX", w.`position_y` AS "posY" FROM creature_addon ca JOIN waypoint_data w ON w.`id` = ca.`path_id` WHERE ca.`guid` = ?d AND ca.`path_id` <> 0',
'SELECT `entry`, `pointId`, `location_x` AS "posX", `location_y` AS "posY" FROM `script_waypoint` WHERE `entry` = ?d',
'SELECT `entry`, `pointId`, `position_x` AS "posX", `position_y` AS "posY" FROM `waypoints` WHERE `entry` = ?d'
);
DB::Aowow()->qry('UPDATE ::creature_waypoints SET %a WHERE `creatureOrPath` = %i AND `point` = %i', $p, $w['entry'], $w['pointId']);
foreach ($jobs as $idx => $job)
{
if ($swp = DB::World()->select($job, $idx ? $wPos[$guid]['id'] : $guid))
{
foreach ($swp as $w)
{
if ($point = WorldPosition::toZonePos($wPos[$guid]['mapId'], $w['posX'], $w['posY'], $area, $floor))
{
$p = array(
'posX' => $point[0]['posX'],
'posY' => $point[0]['posY'],
'areaId' => $point[0]['areaId'],
'floor' => $point[0]['floor']
);
DB::Aowow()->query('UPDATE ?_creature_waypoints SET ?a WHERE `creatureOrPath` = ?d AND `point` = ?d', $p, $w['entry'], $w['pointId']);
}
}
}
}
// also move linked vehicle accessories (on the very same position)
$updGUIDs = array_merge($updGUIDs, DB::Aowow()->selectCol('SELECT s2.`guid` FROM ::spawns s1 JOIN ::spawns s2 ON s1.`posX` = s2.`posX` AND s1.`posY` = s2.`posY` AND
s1.`areaId` = s2.`areaId` AND s1.`floor` = s2.`floor` AND s2.`guid` < 0 WHERE s1.`guid` = %i', $guid));
$updGUIDs = array_merge($updGUIDs, DB::Aowow()->selectCol('SELECT s2.`guid` FROM ?_spawns s1 JOIN ?_spawns s2 ON s1.`posX` = s2.`posX` AND s1.`posY` = s2.`posY` AND
s1.`areaId` = s2.`areaId` AND s1.`floor` = s2.`floor` AND s2.`guid` < 0 WHERE s1.`guid` = ?d', $guid));
}
if (DB::Aowow()->qry('UPDATE ::spawns SET %a WHERE `type` = %i AND `guid` IN %in', $newPos, $type, $updGUIDs))
if (DB::Aowow()->query('UPDATE ?_spawns SET ?a WHERE `type` = ?d AND `guid` IN (?a)', $newPos, $type, $updGUIDs))
$this->result = self::ERR_NONE;
else
$this->result = self::ERR_WRITE_DB;

View file

@ -52,7 +52,7 @@ class AdminVideosResponse extends TemplateResponse
else if ($this->_get['user'])
{
if (mb_strlen($this->_get['user']) >= 3)
if ($uId = DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE LOWER(`username`) = LOWER(%s)', $this->_get['user']))
if ($uId = DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE LOWER(`username`) = LOWER(?)', $this->_get['user']))
$viData = VideoMgr::getVideos(userId: $uId, nFound: $nMatches);
}
else

View file

@ -2,6 +2,8 @@
namespace Aowow;
use GdImage;
if (!defined('AOWOW_REVISION'))
die('illegal access');
@ -22,18 +24,18 @@ class AdminVideosActionApproveResponse extends TextResponse
return;
}
$viEntries = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `userIdOwner`, `date`, `type`, `typeId` FROM ::videos WHERE (`status` & %i) = 0 AND `id` IN %in', CC_FLAG_APPROVED, $this->_get['id']);
$viEntries = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `userIdOwner`, `date`, `type`, `typeId` FROM ?_videos WHERE (`status` & ?d) = 0 AND `id` IN (?a)', CC_FLAG_APPROVED, $this->_get['id']);
foreach ($viEntries as $id => $viData)
{
// set as approved in DB
DB::Aowow()->qry('UPDATE ::videos SET `status` = %i, `userIdApprove` = %i WHERE `id` = %i', CC_FLAG_APPROVED, User::$id, $id);
DB::Aowow()->query('UPDATE ?_videos SET `status` = ?d, `userIdApprove` = ?d WHERE `id` = ?d', CC_FLAG_APPROVED, User::$id, $id);
// gain siterep
Util::gainSiteReputation($viData['userIdOwner'], SITEREP_ACTION_SUGGEST_VIDEO, ['id' => $id, 'what' => 1, 'date' => $viData['date']]);
// flag DB entry as having videos
if ($tbl = Type::getClassAttrib($viData['type'], 'dataTable'))
DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', $tbl, CUSTOM_HAS_VIDEO, $viData['typeId']);
DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_VIDEO, $viData['typeId']);
unset($viEntries[$id]);
}

View file

@ -25,19 +25,19 @@ class AdminVideosActionDeleteResponse extends TextResponse
// irrevocably purge files already flagged as deleted (should only exist as pending)
if (User::isInGroup(U_GROUP_ADMIN))
DB::Aowow()->selectCell('SELECT 1 FROM ::videos WHERE `status` & %i AND `id` IN %in', CC_FLAG_DELETED, $this->_get['id']);
DB::Aowow()->selectCell('SELECT 1 FROM ?_videos WHERE `status` & ?d AND `id` IN (?a)', CC_FLAG_DELETED, $this->_get['id']);
// flag as deleted if not aready
$oldEntries = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, GROUP_CONCAT(`typeId`) FROM ::videos WHERE `id` IN %in GROUP BY `type`', $this->_get['id']);
DB::Aowow()->qry('UPDATE ::videos SET `status` = %i, `userIdDelete` = %i WHERE (`status` & %i) = 0 AND `id` IN %in', CC_FLAG_DELETED, User::$id, CC_FLAG_DELETED, $this->_get['id']);
$oldEntries = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, GROUP_CONCAT(`typeId`) FROM ?_videos WHERE `id` IN (?a) GROUP BY `type`', $this->_get['id']);
DB::Aowow()->query('UPDATE ?_videos SET `status` = ?d, `userIdDelete` = ?d WHERE (`status` & ?d) = 0 AND `id` IN (?a)', CC_FLAG_DELETED, User::$id, CC_FLAG_DELETED, $this->_get['id']);
// deflag db entry as having videos
foreach ($oldEntries as $type => $typeIds)
{
$typeIds = explode(',', $typeIds);
$toUnflag = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(BIT_OR(`status`) & %i, 1, 0) AS "hasMore" FROM ::videos WHERE `type` = %i AND `typeId` IN %in GROUP BY `typeId` HAVING `hasMore` = 0', CC_FLAG_APPROVED, $type, $typeIds);
$toUnflag = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(BIT_OR(`status`) & ?d, 1, 0) AS "hasMore" FROM ?_videos WHERE `type` = ?d AND `typeId` IN (?a) GROUP BY `typeId` HAVING `hasMore` = 0', CC_FLAG_APPROVED, $type, $typeIds);
if ($toUnflag && ($tbl = Type::getClassAttrib($type, 'dataTable')))
DB::Aowow()->qry('UPDATE %n SET cuFlags = cuFlags & ~%i WHERE id IN %in', $tbl, CUSTOM_HAS_VIDEO, array_keys($toUnflag));
DB::Aowow()->query('UPDATE ?# SET cuFlags = cuFlags & ~?d WHERE id IN (?a)', $tbl, CUSTOM_HAS_VIDEO, array_keys($toUnflag));
}
}
}

View file

@ -26,6 +26,6 @@ class AdminVideosActionEdittitleResponse extends TextResponse
$caption = $this->handleCaption($this->_post['title']);
DB::Aowow()->qry('UPDATE ::videos SET `caption` = %s WHERE `id` = %i', $caption, $this->_get['id'][0]);
DB::Aowow()->query('UPDATE ?_videos SET `caption` = ? WHERE `id` = ?d', $caption, $this->_get['id'][0]);
}
}

View file

@ -23,7 +23,7 @@ class AdminVideosActionManageResponse extends TextResponse
if ($this->_get['type'] && $this->_get['typeid'])
$res = VideoMgr::getVideos($this->_get['type'], $this->_get['typeid']);
else if ($this->_get['user'])
if ($uId = DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE LOWER(`username`) = LOWER(%s)', $this->_get['user']))
if ($uId = DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE LOWER(`username`) = LOWER(?)', $this->_get['user']))
$res = VideoMgr::getVideos(userId: $uId);
$this->result = 'vim_videoData = '.Util::toJSON($res);

View file

@ -25,7 +25,7 @@ class AdminVideosActionOrderResponse extends TextResponse
$id = $this->_get['id'][0];
$videos = DB::Aowow()->selectCol('SELECT a.`id` AS ARRAY_KEY, a.`pos` FROM ::videos a, ::videos b WHERE a.`type` = b.`type` AND a.`typeId` = b.`typeId` AND (a.`status` & %i) = 0 AND b.`id` = %i ORDER BY a.`pos` ASC', CC_FLAG_DELETED, $id);
$videos = DB::Aowow()->selectCol('SELECT a.`id` AS ARRAY_KEY, a.`pos` FROM ?_videos a, ?_videos b WHERE a.`type` = b.`type` AND a.`typeId` = b.`typeId` AND (a.`status` & ?d) = 0 AND b.`id` = ?d ORDER BY a.`pos` ASC', CC_FLAG_DELETED, $id);
if (!$videos || count($videos) == 1)
{
trigger_error('AdminVideosActionOrderResponse - not enough videos to sort', E_USER_WARNING);
@ -52,6 +52,6 @@ class AdminVideosActionOrderResponse extends TextResponse
$videos[$id] += $dir;
foreach ($videos as $id => $pos)
DB::Aowow()->qry('UPDATE ::videos SET `pos` = %i WHERE `id` = %i', $pos, $id);
DB::Aowow()->query('UPDATE ?_videos SET `pos` = ?d WHERE `id` = ?d', $pos, $id);
}
}

View file

@ -25,7 +25,7 @@ class AdminVideosActionRelocateResponse extends TextResponse
}
$id = $this->_get['id'][0];
[$type, $oldTypeId] = array_values(DB::Aowow()->selectRow('SELECT `type`, `typeId` FROM ::videos WHERE `id` = %i', $id));
[$type, $oldTypeId] = array_values(DB::Aowow()->selectRow('SELECT `type`, `typeId` FROM ?_videos WHERE `id` = ?d', $id));
$typeId = $this->_get['typeid'];
if (Type::validateIds($type, $typeId))
@ -33,15 +33,15 @@ class AdminVideosActionRelocateResponse extends TextResponse
$tbl = Type::getClassAttrib($type, 'dataTable');
// move video
DB::Aowow()->qry('UPDATE ::videos SET `typeId` = %i WHERE `id` = %i', $typeId, $id);
DB::Aowow()->query('UPDATE ?_videos SET `typeId` = ?d WHERE `id` = ?d', $typeId, $id);
// flag target as having video
DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', $tbl, CUSTOM_HAS_VIDEO, $typeId);
DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_VIDEO, $typeId);
// deflag source for having had videos (maybe)
$viInfo = DB::Aowow()->selectRow('SELECT IF(BIT_OR(~`status`) & %i, 1, 0) AS "hasMore" FROM ::videos WHERE `status`& %i AND `type` = %i AND `typeId` = %i', CC_FLAG_DELETED, CC_FLAG_APPROVED, $type, $oldTypeId);
$viInfo = DB::Aowow()->selectRow('SELECT IF(BIT_OR(~`status`) & ?d, 1, 0) AS "hasMore" FROM ?_videos WHERE `status`& ?d AND `type` = ?d AND `typeId` = ?d', CC_FLAG_DELETED, CC_FLAG_APPROVED, $type, $oldTypeId);
if ($viInfo || !$viInfo['hasMore'])
DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` & ~%i WHERE `id` = %i', $tbl, CUSTOM_HAS_VIDEO, $oldTypeId);
DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` & ~?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_VIDEO, $oldTypeId);
}
else
trigger_error('AdminVideosActionRelocateResponse - invalid typeId #'.$typeId.' for type #'.$type, E_USER_ERROR);

View file

@ -24,28 +24,28 @@ class AdminVideosActionStickyResponse extends TextResponse
// this one is a bit strange: as far as i've seen, the only thing a 'sticky' video does is show up in the infobox
// this also means, that only one video per page should be sticky
// so, handle it one by one and the last one affecting one particular type/typId-key gets the cake
$viEntries = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `userIdOwner`, `date`, `type`, `typeId`, `status` FROM ::videos WHERE (`status` & %i) = 0 AND `id` IN %in', CC_FLAG_DELETED, $this->_get['id']);
$viEntries = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `userIdOwner`, `date`, `type`, `typeId`, `status` FROM ?_videos WHERE (`status` & ?d) = 0 AND `id` IN (?a)', CC_FLAG_DELETED, $this->_get['id']);
foreach ($viEntries as $id => $viData)
{
// approve yet unapproved videos
if (!($viData['status'] & CC_FLAG_APPROVED))
{
// set as approved in DB
DB::Aowow()->qry('UPDATE ::videos SET `status` = %i, `userIdApprove` = %i WHERE `id` = %i', CC_FLAG_APPROVED, User::$id, $id);
DB::Aowow()->query('UPDATE ?_videos SET `status` = ?d, `userIdApprove` = ?d WHERE `id` = ?d', CC_FLAG_APPROVED, User::$id, $id);
// gain siterep
Util::gainSiteReputation($viData['userIdOwner'], SITEREP_ACTION_SUGGEST_VIDEO, ['id' => $id, 'what' => 1, 'date' => $viData['date']]);
// flag DB entry as having videos
if ($tbl = Type::getClassAttrib($viData['type'], 'dataTable'))
DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', $tbl, CUSTOM_HAS_VIDEO, $viData['typeId']);
DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_VIDEO, $viData['typeId']);
}
// reset all others
DB::Aowow()->qry('UPDATE ::videos a, ::videos b SET a.`status` = a.`status` & ~%i WHERE a.`type` = b.`type` AND a.`typeId` = b.`typeId` AND a.`id` <> b.`id` AND b.`id` = %i', CC_FLAG_STICKY, $id);
DB::Aowow()->query('UPDATE ?_videos a, ?_videos b SET a.`status` = a.`status` & ~?d WHERE a.`type` = b.`type` AND a.`typeId` = b.`typeId` AND a.`id` <> b.`id` AND b.`id` = ?d', CC_FLAG_STICKY, $id);
// toggle sticky status
DB::Aowow()->qry('UPDATE ::videos SET `status` = IF(`status` & %i, `status` & ~%i, `status` | %i) WHERE `id` = %i AND `status` & %i', CC_FLAG_STICKY, CC_FLAG_STICKY, CC_FLAG_STICKY, $id, CC_FLAG_APPROVED);
DB::Aowow()->query('UPDATE ?_videos SET `status` = IF(`status` & ?d, `status` & ~?d, `status` | ?d) WHERE `id` = ?d AND `status` & ?d', CC_FLAG_STICKY, CC_FLAG_STICKY, CC_FLAG_STICKY, $id, CC_FLAG_APPROVED);
unset($viEntries[$id]);
}

View file

@ -27,8 +27,8 @@ class AdminWeightpresetsResponse extends TemplateResponse
$head = $body = '';
$scales = DB::Aowow()->selectAssoc('SELECT `class` AS ARRAY_KEY, `id` AS ARRAY_KEY2, `name`, `icon` FROM ::account_weightscales WHERE `userId` = 0');
$weights = DB::Aowow()->selectCol('SELECT awd.`id` AS ARRAY_KEY, awd.`field` AS ARRAY_KEY2, awd.`val` FROM ::account_weightscale_data awd JOIN ::account_weightscales ad ON awd.`id` = ad.`id` WHERE ad.`userId` = 0');
$scales = DB::Aowow()->select('SELECT `class` AS ARRAY_KEY, `id` AS ARRAY_KEY2, `name`, `icon` FROM ?_account_weightscales WHERE `userId` = 0');
$weights = DB::Aowow()->selectCol('SELECT awd.`id` AS ARRAY_KEY, awd.`field` AS ARRAY_KEY2, awd.`val` FROM ?_account_weightscale_data awd JOIN ?_account_weightscales ad ON awd.`id` = ad.`id` WHERE ad.`userId` = 0');
foreach ($scales as $cl => $data)
{
$ul = '';

View file

@ -30,17 +30,17 @@ class AdminWeightpresetsActionSaveResponse extends TextResponse
}
// save to db
DB::Aowow()->qry('DELETE FROM ::account_weightscale_data WHERE `id` = %i', $this->_post['id']);
DB::Aowow()->qry('UPDATE ::account_weightscales SET `icon`= %s WHERE `id` = %i', $this->_post['__icon'], $this->_post['id']);
DB::Aowow()->query('DELETE FROM ?_account_weightscale_data WHERE `id` = ?d', $this->_post['id']);
DB::Aowow()->query('UPDATE ?_account_weightscales SET `icon`= ? WHERE `id` = ?d', $this->_post['__icon'], $this->_post['id']);
foreach (explode(',', $this->_post['scale']) as $s)
{
[$k, $v] = explode(':', $s);
if (!Stat::getWeightJson($k) || $v < 1)
if (!in_array($k, Util::$weightScales) || $v < 1)
continue;
if (DB::Aowow()->qry('INSERT INTO ::account_weightscale_data VALUES (%i, %s, %i)', $this->_post['id'], $k, $v) === null)
if (DB::Aowow()->query('INSERT INTO ?_account_weightscale_data VALUES (?d, ?, ?d)', $this->_post['id'], $k, $v) === null)
{
trigger_error('AdminWeightpresetsActionSaveResponse - failed to write to database', E_USER_ERROR);
$this->result = self::ERR_WRITE_DB;

View file

@ -10,7 +10,7 @@ class AreatriggerBaseResponse extends TemplateResponse implements ICache
{
use TrDetailPage, TrCache;
protected int $cacheType = CACHE_TYPE_DETAIL_PAGE;
protected int $cacheType = CACHE_TYPE_PAGE;
protected int $requiredUserGroup = U_GROUP_STAFF;
protected string $template = 'detail-page-generic';
@ -105,7 +105,7 @@ class AreatriggerBaseResponse extends TemplateResponse implements ICache
// tab: conditions
$cnd = new Conditions();
$cnd->getBySource(Conditions::SRC_AREATRIGGER_CLIENT, entry: $this->typeId)->prepare();
$cnd->getBySourceEntry($this->typeId, Conditions::SRC_AREATRIGGER_CLIENT)->prepare();
if ($tab = $cnd->toListviewTab())
{
$this->extendGlobalData($cnd->getJsGlobals());

View file

@ -11,7 +11,7 @@ class AreatriggersBaseResponse extends TemplateResponse implements ICache
use TrListPage, TrCache;
protected int $type = Type::AREATRIGGER;
protected int $cacheType = CACHE_TYPE_LIST_PAGE;
protected int $cacheType = CACHE_TYPE_PAGE;
protected int $requiredUserGroup = U_GROUP_STAFF;
protected string $template = 'areatriggers';
@ -23,22 +23,16 @@ class AreatriggersBaseResponse extends TemplateResponse implements ICache
protected array $expectedGET = ['filter' => ['filter' => FILTER_VALIDATE_REGEXP, 'options' => ['regexp' => Filter::PATTERN_PARAM]]];
protected array $validCats = [0, 1, 2, 3, 4, 5];
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
$this->getCategoryFromUrl($rawParam);
$this->getCategoryFromUrl($pageParam);
if (isset($this->category[0]))
$this->forward('?areatriggers&filter=ty='.$this->category[0]);
parent::__construct($rawParam);
parent::__construct($pageParam);
$this->filter = new AreaTriggerListFilter($this->_get['filter'] ?? '');
if ($this->filter->shouldReload)
{
$_SESSION['error']['fi'] = $this->filter::class;
$get = $this->filter->buildGETParam();
$this->forward('?' . $this->pageName . ($get ? '&filter=' . $get : ''));
}
$this->filterError = $this->filter->error;
}
@ -46,6 +40,8 @@ class AreatriggersBaseResponse extends TemplateResponse implements ICache
{
$this->h1 = Util::ucFirst(Lang::game('areatriggers'));
$this->filter->evalCriteria();
$fiForm = $this->filter->values;
@ -73,10 +69,12 @@ class AreatriggersBaseResponse extends TemplateResponse implements ICache
$this->redButtons[BUTTON_WOWHEAD] = false;
$conditions = [Listview::DEFAULT_SIZE];
$conditions = [];
if ($_ = $this->filter->getConditions())
$conditions[] = $_;
$this->filterError = $this->filter->error; // maybe the evalX() caused something
$tabData = [];
$trigger = new AreaTriggerList($conditions, ['calcTotal' => true]);
if (!$trigger->error)
@ -84,9 +82,9 @@ class AreatriggersBaseResponse extends TemplateResponse implements ICache
$tabData['data'] = $trigger->getListviewData();
// create note if search limit was exceeded; overwriting 'note' is intentional
if ($trigger->getMatches() > Listview::DEFAULT_SIZE)
if ($trigger->getMatches() > Cfg::get('SQL_LIMIT_DEFAULT'))
{
$tabData['note'] = sprintf(Util::$tryFilteringEntityString, $trigger->getMatches(), '"'.Lang::game('areatriggers').'"', Listview::DEFAULT_SIZE);
$tabData['note'] = sprintf(Util::$tryFilteringEntityString, $trigger->getMatches(), '"'.Lang::game('areatriggers').'"', Cfg::get('SQL_LIMIT_DEFAULT'));
$tabData['_truncated'] = 1;
}
}

View file

@ -46,26 +46,24 @@ class ArenateamBaseResponse extends TemplateResponse
// 3 possibilities
// 1) already synced to aowow
if ($subject = DB::Aowow()->selectRow('SELECT `id`, `realmGUID`, `stub` FROM ::profiler_arena_team WHERE `realm` = %i AND `nameUrl` = %s', $this->realmId, Profiler::urlize($this->subjectName)))
if ($subject = DB::Aowow()->selectRow('SELECT `id`, `realmGUID`, `cuFlags` FROM ?_profiler_arena_team WHERE `realm` = ?d AND `nameUrl` = ?', $this->realmId, Profiler::urlize($this->subjectName)))
{
$this->typeId = $subject['id'];
if ($subject['stub'])
if ($subject['cuFlags'] & PROFILER_CU_NEEDS_RESYNC)
$this->handleIncompleteData(Type::ARENA_TEAM, $subject['realmGUID']);
return;
}
// 2) not yet synced but exists on realm (wont work if we get passed an urlized name, but there is nothing we can do about it)
$subjects = DB::Characters($this->realmId)->selectAssoc('SELECT at.`arenaTeamId` AS "realmGUID", at.`name`, at.`type` FROM arena_team at WHERE at.`name` = %s', $this->subjectName);
if ($subject = array_find($subjects ?: [], fn($x) => Util::lower($x['name']) === Util::lower($this->subjectName)))
else if ($subject = DB::Characters($this->realmId)->selectRow('SELECT at.`arenaTeamId` AS "realmGUID", at.`name`, at.`type` FROM arena_team at WHERE at.`name` = ?', Util::ucFirst($this->subjectName)))
{
$subject['realm'] = $this->realmId;
$subject['stub'] = 1;
$subject['nameUrl'] = Profiler::urlize($subject['name']);
$subject['cuFlags'] = PROFILER_CU_NEEDS_RESYNC;
// create entry from realm with basic info
DB::Aowow()->qry('INSERT IGNORE INTO ::profiler_arena_team %v', $subject);
DB::Aowow()->query('INSERT IGNORE INTO ?_profiler_arena_team (?#) VALUES (?a)', array_keys($subject), array_values($subject));
$this->handleIncompleteData(Type::ARENA_TEAM, $subject['realmGUID']);
return;

View file

@ -13,9 +13,9 @@ class ArenaTeamResyncResponse extends TextResponse
'profile' => ['filter' => FILTER_CALLBACK, 'options' => [self::class, 'checkEmptySet']]
);
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
parent::__construct($rawParam);
parent::__construct($pageParam);
if (!Cfg::get('PROFILER_ENABLE'))
$this->generate404();
@ -32,12 +32,12 @@ class ArenaTeamResyncResponse extends TextResponse
if (!$this->assertGET('id'))
return;
if ($teams = DB::Aowow()->selectAssoc('SELECT `realm`, `realmGUID` FROM ::profiler_arena_team WHERE `id` IN %in', $this->_get['id']))
if ($teams = DB::Aowow()->select('SELECT `realm`, `realmGUID` FROM ?_profiler_arena_team WHERE `id` IN (?a)', $this->_get['id']))
foreach ($teams as $t)
Profiler::scheduleResync(Type::ARENA_TEAM, $t['realm'], $t['realmGUID']);
if ($this->_get['profile'])
if ($chars = DB::Aowow()->selectAssoc('SELECT `realm`, `realmGUID` FROM ::profiler_profiles p JOIN ::profiler_arena_team_member atm ON atm.`profileId` = p.`id` WHERE atm.`arenaTeamId` IN %in', $this->_get['id']))
if ($chars = DB::Aowow()->select('SELECT `realm`, `realmGUID` FROM ?_profiler_profiles p JOIN ?_profiler_arena_team_member atm ON atm.`profileId` = p.`id` WHERE atm.`arenaTeamId` IN (?a)', $this->_get['id']))
foreach ($chars as $c)
Profiler::scheduleResync(Type::PROFILE, $c['realm'], $c['realmGUID']);

View file

@ -12,9 +12,9 @@ class ArenaTeamStatusResponse extends TextResponse
'id' => ['filter' => FILTER_CALLBACK, 'options' => [self::class, 'checkIdList']]
);
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
parent::__construct($rawParam);
parent::__construct($pageParam);
if (!Cfg::get('PROFILER_ENABLE'))
$this->generate404();

View file

@ -29,14 +29,14 @@ class ArenateamsBaseResponse extends TemplateResponse implements IProfilerList
private int $sumSubjects = 0;
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
if (!Cfg::get('PROFILER_ENABLE'))
$this->generateError();
$this->getSubjectFromUrl($rawParam);
$this->getSubjectFromUrl($pageParam);
parent::__construct($rawParam);
parent::__construct($pageParam);
$realms = [];
foreach (Profiler::getRealms() as $idx => $r)
@ -51,16 +51,8 @@ class ArenateamsBaseResponse extends TemplateResponse implements IProfilerList
$realms[] = $idx;
}
if ($this->category)
$this->subCat = '='.implode('.', $this->category);
$this->subCat = $pageParam !== '' ? '='.$pageParam : '';
$this->filter = new ArenaTeamListFilter($this->_get['filter'] ?? '', ['realms' => $realms]);
if ($this->filter->shouldReload)
{
$_SESSION['error']['fi'] = $this->filter::class;
$get = $this->filter->buildGETParam();
$this->forward('?' . $this->pageName . $this->subCat . ($get ? '&filter=' . $get : ''));
}
$this->filterError = $this->filter->error;
}
@ -92,7 +84,7 @@ class ArenateamsBaseResponse extends TemplateResponse implements IProfilerList
/* Main Content */
/****************/
$conditions = [Listview::DEFAULT_SIZE];
$conditions = [];
if (!User::isInGroup(U_GROUP_EMPLOYEE))
$conditions[] = ['at.seasonGames', 0, '>'];
@ -131,12 +123,12 @@ class ArenateamsBaseResponse extends TemplateResponse implements IProfilerList
$tabData['data'] = $teams->getListviewData();
// create note if search limit was exceeded
if ($this->filter->query && $teams->getMatches() > Listview::DEFAULT_SIZE)
if ($this->filter->query && $teams->getMatches() > Cfg::get('SQL_LIMIT_DEFAULT'))
{
$tabData['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_arenateamsfound2', $this->sumSubjects, $teams->getMatches());
$tabData['_truncated'] = 1;
}
else if ($teams->getMatches() > Listview::DEFAULT_SIZE)
else if ($teams->getMatches() > Cfg::get('SQL_LIMIT_DEFAULT'))
$tabData['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_arenateamsfound', $this->sumSubjects, 0);
}

View file

@ -12,7 +12,7 @@ class ClassBaseResponse extends TemplateResponse implements ICache
private const TC_CLASS_IDS = [null, 8, 3, 1, 5, 4, 9, 6, 2, 7, null, 0]; // see TalentCalc.js
protected int $cacheType = CACHE_TYPE_DETAIL_PAGE;
protected int $cacheType = CACHE_TYPE_PAGE;
protected string $template = 'detail-page-generic';
protected string $pageName = 'class';
@ -103,20 +103,6 @@ class ClassBaseResponse extends TemplateResponse implements ICache
if ($specList)
$infobox[] = Lang::game('specs').'[ul][li]'.implode('[/li][li]', $specList).'[/li][/ul]';
// id
$infobox[] = Lang::chrClass('id') . $this->typeId;
// icon
if ($_ = $this->subject->getField('iconId'))
{
$infobox[] = Util::ucFirst(Lang::game('icon')).Lang::main('colon').'[icondb='.$_.' name=true]';
$this->extendGlobalIds(Type::ICON, $_);
}
// original name
if (Lang::getLocale() != Locale::EN)
$infobox[] = Util::ucFirst(Lang::lang(Locale::EN->value) . Lang::main('colon')) . '[copy button=false]'.$this->subject->getField('name_loc0').'[/copy][/li]';
if ($infobox)
$this->infobox = new InfoboxMarkup($infobox, ['allow' => Markup::CLASS_STAFF, 'dbpage' => true], 'infobox-contents0');
@ -126,6 +112,7 @@ class ClassBaseResponse extends TemplateResponse implements ICache
/****************/
$this->expansion = Util::$expansionString[$this->subject->getField('expansion')];
$this->headIcons = ['class_'.$cl->json()];
$this->redButtons = array(
BUTTON_LINKS => ['type' => $this->type, 'typeId' => $this->typeId],
BUTTON_WOWHEAD => true,
@ -133,9 +120,6 @@ class ClassBaseResponse extends TemplateResponse implements ICache
BUTTON_FORUM => false // todo (low): Cfg::get('BOARD_URL') + X
);
if ($_ = $this->subject->getField('iconString'))
$this->headIcons[] = $_;
/**************/
/* Extra Tabs */
@ -143,7 +127,7 @@ class ClassBaseResponse extends TemplateResponse implements ICache
$this->lvTabs = new Tabs(['parent' => "\$\$WH.ge('tabs-generic')"], 'tabsRelated', true);
// tab: spells (grouped)
// Tab: Spells (grouped)
// '$LANG.tab_armorproficiencies',
// '$LANG.tab_weaponskills',
// '$LANG.tab_glyphs',
@ -153,18 +137,19 @@ class ClassBaseResponse extends TemplateResponse implements ICache
['s.typeCat', [-13, -11, -2, 7]],
[['s.cuFlags', (SPELL_CU_TRIGGERED | CUSTOM_EXCLUDE_FOR_LISTVIEW), '&'], 0],
[
DB::OR,
'OR',
// Glyphs, Proficiencies
['s.reqClassMask', $cl->toMask(), '&'],
// Abilities / Talents
['s.skillLine1', $this->subject->getField('skills')],
[DB::AND, ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->subject->getField('skills')]]
['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->subject->getField('skills')]]
],
[ // last rank or unranked
DB::OR,
'OR',
['s.cuFlags', SPELL_CU_LAST_RANK, '&'],
['s.rankNo', 0]
]
],
Cfg::get('SQL_LIMIT_NONE')
);
$genSpells = new SpellList($conditions);
@ -184,10 +169,13 @@ class ClassBaseResponse extends TemplateResponse implements ICache
), SpellList::$brickFile));
}
// tab: items (grouped)
// Tab: Items (grouped)
$conditions = array(
['requiredClass', 0, '>'],
['requiredClass', $cl->toMask(), '&'],
['itemset', 0]
[['requiredClass', ChrClass::MASK_ALL, '&'], ChrClass::MASK_ALL, '!'],
['itemset', 0],
Cfg::get('SQL_LIMIT_NONE')
);
$items = new ItemList($conditions);
@ -212,7 +200,7 @@ class ClassBaseResponse extends TemplateResponse implements ICache
), ItemList::$brickFile));
}
// tab: quests
// Tab: Quests
$conditions = array(
['reqClassMask', $cl->toMask(), '&'],
[['reqClassMask', ChrClass::MASK_ALL, '&'], ChrClass::MASK_ALL, '!']
@ -229,7 +217,7 @@ class ClassBaseResponse extends TemplateResponse implements ICache
), QuestList::$brickFile));
}
// tab: itemsets
// Tab: Itemsets
$sets = new ItemsetList(array(['classMask', $cl->toMask(), '&']));
if (!$sets->error)
{
@ -243,7 +231,7 @@ class ClassBaseResponse extends TemplateResponse implements ICache
), ItemsetList::$brickFile));
}
// tab: trainers
// Tab: Trainer
$conditions = array(
['npcflag', NPC_FLAG_TRAINER | NPC_FLAG_CLASS_TRAINER, '&'],
['trainerType', 0], // trains class spells
@ -261,33 +249,11 @@ class ClassBaseResponse extends TemplateResponse implements ICache
), CreatureList::$brickFile));
}
// tab: races
// Tab: Races
$races = new CharRaceList(array(['classMask', $cl->toMask(), '&']));
if (!$races->error)
$this->lvTabs->addListviewTab(new Listview(['data' => $races->getListviewData()], CharRaceList::$brickFile));
// tab: criteria-of
$conditions = array(
DB::AND,
['ac.type', ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS],
['ac.value1', $this->typeId]
);
if ($extraCrt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` IN %in AND `value1` = %i', [ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE, ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE], $this->typeId))
$conditions = [DB::OR, $conditions, ['ac.id', $extraCrt]];
$crtOf = new AchievementList($conditions);
if (!$crtOf->error)
{
$this->extendGlobalData($crtOf->getJSGlobals());
$this->lvTabs->addListviewTab(new Listview(array(
'data' => $crtOf->getListviewData(),
'name' => '$LANG.tab_criteriaof',
'id' => 'criteria-of'
), AchievementList::$brickFile));
}
// tab: condition-for
$cnd = new Conditions();
$cnd->getByCondition(Type::CHR_CLASS, $this->typeId)->prepare();

View file

@ -11,18 +11,18 @@ class ClassesBaseResponse extends TemplateResponse implements ICache
use TrListPage, TrCache;
protected int $type = Type::CHR_CLASS;
protected int $cacheType = CACHE_TYPE_LIST_PAGE;
protected int $cacheType = CACHE_TYPE_PAGE;
protected string $template = 'list-page-generic';
protected string $pageName = 'classes';
protected ?int $activeTab = parent::TAB_DATABASE;
protected array $breadcrumb = [0, 12];
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
$this->getCategoryFromUrl($rawParam);
$this->getCategoryFromUrl($pageParam);
parent::__construct($rawParam);
parent::__construct($pageParam);
}
protected function generate() : void

View file

@ -29,7 +29,7 @@ class CommentAddreplyResponse extends TextResponse
if (!User::canReply())
$this->generate404(Lang::main('cannotComment'));
if (!$this->_post['commentId'] || !DB::Aowow()->selectCell('SELECT 1 FROM ::comments WHERE `id` = %i', $this->_post['commentId']))
if (!$this->_post['commentId'] || !DB::Aowow()->selectCell('SELECT 1 FROM ?_comments WHERE `id` = ?d', $this->_post['commentId']))
{
trigger_error('CommentAddreplyResponse - parent comment #'.$this->_post['commentId'].' does not exist', E_USER_ERROR);
$this->generate404(Lang::main('intError'));
@ -38,7 +38,7 @@ class CommentAddreplyResponse extends TextResponse
if (mb_strlen($this->_post['body']) < CommunityContent::REPLY_LENGTH_MIN || mb_strlen($this->_post['body']) > CommunityContent::REPLY_LENGTH_MAX)
$this->generate404(Lang::main('textLength', [mb_strlen($this->_post['body']), CommunityContent::REPLY_LENGTH_MIN, CommunityContent::REPLY_LENGTH_MAX]));
if (!DB::Aowow()->qry('INSERT INTO ::comments (`userId`, `roles`, `body`, `date`, `replyTo`) VALUES (%i, %i, %s, UNIX_TIMESTAMP(), %i)', User::$id, User::$groups, $this->_post['body'], $this->_post['commentId']))
if (!DB::Aowow()->query('INSERT INTO ?_comments (`userId`, `roles`, `body`, `date`, `replyTo`) VALUES (?d, ?d, ?, UNIX_TIMESTAMP(), ?d)', User::$id, User::$groups, $this->_post['body'], $this->_post['commentId']))
{
trigger_error('CommentAddreplyResponse - write to db failed', E_USER_ERROR);
$this->generate404(Lang::main('intError'));

View file

@ -30,7 +30,7 @@ class CommentAddResponse extends TextResponse
// we now have a valid return target
$idOrUrl = $this->_get['typeid'];
if ($this->_get['type'] == Type::GUIDE)
if ($_ = DB::Aowow()->selectCell('SELECT `url` FROM ::guides WHERE `id` = %i', $this->_get['typeid']))
if ($_ = DB::Aowow()->selectCell('SELECT `url` FROM ?_guides WHERE `id` = ?d', $this->_get['typeid']))
$idOrUrl = $_;
$this->redirectTo = '?'.Type::getFileString($this->_get['type']).'='.$idOrUrl.'#comments';
@ -57,16 +57,16 @@ class CommentAddResponse extends TextResponse
return;
}
if ($postId = DB::Aowow()->qry('INSERT INTO ::comments (`type`, `typeId`, `userId`, `roles`, `body`, `date`) VALUES (%i, %i, %i, %i, %s, UNIX_TIMESTAMP())', $this->_get['type'], $this->_get['typeid'], User::$id, User::$groups, $this->_post['commentbody']))
if ($postId = DB::Aowow()->query('INSERT INTO ?_comments (`type`, `typeId`, `userId`, `roles`, `body`, `date`) VALUES (?d, ?d, ?d, ?d, ?, UNIX_TIMESTAMP())', $this->_get['type'], $this->_get['typeid'], User::$id, User::$groups, $this->_post['commentbody']))
{
Util::gainSiteReputation(User::$id, SITEREP_ACTION_COMMENT, ['id' => $postId]);
// every comment starts with a rating of +1 and i guess the simplest thing to do is create a db-entry with the system as owner
DB::Aowow()->qry('INSERT INTO ::user_ratings (`type`, `entry`, `userId`, `value`) VALUES (%i, %i, 0, 1)', RATING_COMMENT, $postId);
DB::Aowow()->query('INSERT INTO ?_user_ratings (`type`, `entry`, `userId`, `value`) VALUES (?d, ?d, 0, 1)', RATING_COMMENT, $postId);
// flag target with hasComment
if ($tbl = Type::getClassAttrib($this->_get['type'], 'dataTable'))
DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', $tbl, CUSTOM_HAS_COMMENT, $this->_get['typeid']);
DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_COMMENT, $this->_get['typeid']);
return;
}

View file

@ -23,13 +23,16 @@ class CommentDeletereplyResponse extends TextResponse
$this->generate404(User::isInGroup(U_GROUP_STAFF) ? 'request malformed' : '');
}
$where = [['`id` = %i', $this->_post['id']]];
if (!User::isInGroup(U_GROUP_MODERATOR))
$where[] = ['`userId` = %i', User::$id];
// flag as deleted (unset sticky (can a reply even be sticky?)
$ok = DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` & ~?d | ?d, `deleteUserId` = ?d, `deleteDate` = UNIX_TIMESTAMP() WHERE `id` = ?d { AND `userId` = ?d }',
CC_FLAG_STICKY, CC_FLAG_DELETED,
User::$id,
$this->_post['id'],
User::isInGroup(U_GROUP_MODERATOR) ? DBSIMPLE_SKIP : User::$id
);
// flag as deleted
if (DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` | %i, `deleteUserId` = %i, `deleteDate` = UNIX_TIMESTAMP() WHERE %and', CC_FLAG_DELETED, User::$id, $where))
DB::Aowow()->qry('DELETE FROM ::user_ratings WHERE `type` = %i AND `entry` = %i', RATING_COMMENT, $this->_post['id']);
if ($ok)
DB::Aowow()->query('DELETE FROM ?_user_ratings WHERE `type` = ?d AND `entry` = ?d', RATING_COMMENT, $this->_post['id']);
else
{
trigger_error('CommentDeletereplyResponse - deleting reply #'.$this->_post['id'].' by user #'.User::$id.' from db failed', E_USER_ERROR);

View file

@ -24,21 +24,24 @@ class CommentDeleteResponse extends TextResponse
}
// in theory, there is a username passed alongside if executed from userpage... lets just use the current user (see user.js)
$where = [['`id` IN %in', $this->_post['id']]];
if (!User::isInGroup(U_GROUP_MODERATOR))
$where[] = ['`userId` = %i', User::$id];
$ok = DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` | ?d, `deleteUserId` = ?d, `deleteDate` = UNIX_TIMESTAMP() WHERE `id` IN (?a) { AND `userId` = ?d }',
CC_FLAG_DELETED,
User::$id,
$this->_post['id'],
User::isInGroup(U_GROUP_MODERATOR) ? DBSIMPLE_SKIP : User::$id
);
// flag as deleted; unflag subject: hasComment
if (DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` | %i, `deleteUserId` = %i, `deleteDate` = UNIX_TIMESTAMP() WHERE %and', CC_FLAG_DELETED, User::$id, $where))
// unflag subject: hasComment
if ($ok)
{
$coInfo = DB::Aowow()->selectAssoc(
'SELECT IF(BIT_OR(~b.`flags`) & %i, 1, 0) AS "0", b.`type` AS "1", b.`typeId` AS "2" FROM ::comments a JOIN ::comments b ON a.`type` = b.`type` AND a.`typeId` = b.`typeId` WHERE a.`id` IN %in GROUP BY b.`type`, b.`typeId`',
$coInfo = DB::Aowow()->select(
'SELECT IF(BIT_OR(~b.`flags`) & ?d, 1, 0) AS "0", b.`type` AS "1", b.`typeId` AS "2" FROM ?_comments a JOIN ?_comments b ON a.`type` = b.`type` AND a.`typeId` = b.`typeId` WHERE a.`id` IN (?a) GROUP BY b.`type`, b.`typeId`',
CC_FLAG_DELETED, $this->_post['id']
);
foreach ($coInfo as [$hasMore, $type, $typeId])
if (!$hasMore && ($tbl = Type::getClassAttrib($type, 'dataTable')))
DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` & ~%i WHERE `id` = %i', $tbl, CUSTOM_HAS_COMMENT, $typeId);
DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` & ~?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_COMMENT, $typeId);
return;
}

View file

@ -23,7 +23,7 @@ class CommentDetachreplyResponse extends TextResponse
$this->generate404(User::isInGroup(U_GROUP_STAFF) ? 'request malformed' : '');
}
DB::Aowow()->qry('UPDATE ::comments c1, ::comments c2 SET c1.`replyTo` = 0, c1.`type` = c2.`type`, c1.`typeId` = c2.`typeId` WHERE c1.`replyTo` = c2.`id` AND c1.`id` = %i', $this->_post['id']);
DB::Aowow()->query('UPDATE ?_comments c1, ?_comments c2 SET c1.`replyTo` = 0, c1.`type` = c2.`type`, c1.`typeId` = c2.`typeId` WHERE c1.`replyTo` = c2.`id` AND c1.`id` = ?d', $this->_post['id']);
}
}

View file

@ -26,7 +26,7 @@ class CommentDownvotereplyResponse extends TextResponse
if (!User::canDownvote())
$this->generate404(User::isInGroup(U_GROUP_STAFF) ? 'cannot downvote' : '');
$comment = DB::Aowow()->selectRow('SELECT `userId`, IF(`flags` & %i, 1, 0) AS "deleted" FROM ::comments WHERE `id` = %i', CC_FLAG_DELETED, $this->_post['id']);
$comment = DB::Aowow()->selectRow('SELECT `userId`, IF(`flags` & ?d, 1, 0) AS "deleted" FROM ?_comments WHERE `id` = ?d', CC_FLAG_DELETED, $this->_post['id']);
if (!$comment)
{
trigger_error('CommentDownvotereplyResponse - comment #'.$this->_post['id'].' not found in db', E_USER_ERROR);
@ -39,9 +39,15 @@ class CommentDownvotereplyResponse extends TextResponse
if ($comment['deleted'])
$this->generate404('LANG.votedeleted_tip');
if (is_null(DB::Aowow()->qry('INSERT INTO ::user_ratings (`type`, `entry`, `userId`, `value`) VALUES (%i, %i, %i, %i)',
RATING_COMMENT, $this->_post['id'], User::$id, User::canSupervote() ? -2 : -1
)))
$ok = DB::Aowow()->query(
'INSERT INTO ?_user_ratings (`type`, `entry`, `userId`, `value`) VALUES (?d, ?d, ?d, ?d)',
RATING_COMMENT,
$this->_post['id'],
User::$id,
User::canSupervote() ? -2 : -1
);
if (!$ok)
{
trigger_error('CommentDownvotereplyResponse - write to db failed', E_USER_ERROR);
$this->generate404(User::isInGroup(U_GROUP_STAFF) ? 'write to db failed' : '');

View file

@ -26,7 +26,7 @@ class CommentEditreplyResponse extends TextResponse
$this->generate404(User::isInGroup(U_GROUP_STAFF) ? 'request malformed' : '');
}
$ownerId = DB::Aowow()->selectCell('SELECT `userId` FROM ::comments WHERE `id` = %i AND `replyTo` = %i', $this->_post['replyId'], $this->_post['commentId']);
$ownerId = DB::Aowow()->selectCell('SELECT `userId` FROM ?_comments WHERE `id` = ?d AND `replyTo` = ?d', $this->_post['replyId'], $this->_post['commentId']);
if (!User::canReply() || (User::$id != $ownerId && !User::isInGroup(U_GROUP_MODERATOR)))
$this->generate404(Lang::main('cannotComment'));
@ -48,11 +48,8 @@ class CommentEditreplyResponse extends TextResponse
if (User::$id == $ownerId)
$update['roles'] = User::$groups;
$where = [['`id` = %i', $this->_post['replyId']], ['`replyTo` = %i', $this->_post['commentId']]];
if (!User::isInGroup(U_GROUP_MODERATOR))
$where[] = ['`userId` = %i', User::$id];
if (!DB::Aowow()->qry('UPDATE ::comments SET `editCount` = `editCount` + 1, %a WHERE %and', $update, $where))
if (!DB::Aowow()->query('UPDATE ?_comments SET `editCount` = `editCount` + 1, ?a WHERE `id` = ?d AND `replyTo` = ?d { AND `userId` = ?d }',
$update, $this->_post['replyId'], $this->_post['commentId'], User::isInGroup(U_GROUP_MODERATOR) ? DBSIMPLE_SKIP : User::$id))
{
trigger_error('CommentEditreplyResponse - write to db failed', E_USER_ERROR);
$this->generate404(Lang::main('intError'));

View file

@ -26,7 +26,7 @@ class CommentEditResponse extends TextResponse
return;
}
$ownerId = DB::Aowow()->selectCell('SELECT `userId` FROM ::comments WHERE `id` = %i', $this->_get['id']);
$ownerId = DB::Aowow()->selectCell('SELECT `userId` FROM ?_comments WHERE `id` = ?d', $this->_get['id']);
if (!User::canComment() || (User::$id != $ownerId && !User::isInGroup(U_GROUP_MODERATOR)))
{
@ -56,7 +56,7 @@ class CommentEditResponse extends TextResponse
$update['responseRoles'] = User::$groups;
}
DB::Aowow()->qry('UPDATE ::comments SET `editCount` = `editCount` + 1, %a WHERE `id` = %i', $update, $this->_get['id']);
DB::Aowow()->query('UPDATE ?_comments SET `editCount` = `editCount` + 1, ?a WHERE `id` = ?d', $update, $this->_get['id']);
}
}

View file

@ -23,7 +23,7 @@ class CommentFlagreplyResponse extends TextResponse
$this->generate404(User::isInGroup(U_GROUP_STAFF) ? 'request malformed' : '');
}
$replyOwner = DB::Aowow()->selectCell('SELECT `userId` FROM ::commments WHERE `id` = %i', $this->_post['id']);
$replyOwner = DB::Aowow()->selectCell('SELECT `userId` FROM ?_commments WHERE `id` = ?d', $this->_post['id']);
if (!$replyOwner)
{
trigger_error('CommentFlagreplyResponse - reply not found', E_USER_ERROR);
@ -38,7 +38,7 @@ class CommentFlagreplyResponse extends TextResponse
if (!$report->create('Report Reply Button Click'))
$this->generate404('LANG.ct_resp_error'.$report->getError());
else if (count($report->getSimilar()) >= CommunityContent::REPORT_THRESHOLD_AUTO_DELETE)
DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` | %i WHERE `id` = %i', CC_FLAG_DELETED, $this->_post['id']);
DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` | ?d WHERE `id` = ?d', CC_FLAG_DELETED, $this->_post['id']);
}
}

View file

@ -30,9 +30,9 @@ class CommentOutofdateResponse extends TextResponse
if (User::isInGroup(U_GROUP_MODERATOR)) // directly mark as outdated
{
if (!$this->_post['remove'])
$ok = DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` | %i WHERE `id` = %i', CC_FLAG_OUTDATED, $this->_post['id']);
$ok = DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` | ?d WHERE `id` = ?d', CC_FLAG_OUTDATED, $this->_post['id']);
else
$ok = DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` & ~%i WHERE `id` = %i', CC_FLAG_OUTDATED, $this->_post['id']);
$ok = DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` & ~?d WHERE `id` = ?d', CC_FLAG_OUTDATED, $this->_post['id']);
}
else // try to report as outdated
{
@ -41,7 +41,7 @@ class CommentOutofdateResponse extends TextResponse
$this->result = Lang::main('intError');
if (count($report->getSimilar()) >= CommunityContent::REPORT_THRESHOLD_AUTO_OUT_OF_DATE)
$ok = DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` | %i WHERE `id` = %i', CC_FLAG_OUTDATED, $this->_post['id']);
$ok = DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` | ?d WHERE `id` = ?d', CC_FLAG_OUTDATED, $this->_post['id']);
}
if (!$ok)

View file

@ -21,7 +21,7 @@ class CommentRatingResponse extends TextResponse
return;
}
if ($votes = DB::Aowow()->selectRow('SELECT 1 AS "success", SUM(IF(`value` > 0, `value`, 0)) AS "up", SUM(IF(`value` < 0, -`value`, 0)) AS "down" FROM ::user_ratings WHERE `type` = %i AND `entry` = %i AND `userId` <> 0 GROUP BY `entry`', RATING_COMMENT, $this->_get['id']))
if ($votes = DB::Aowow()->selectRow('SELECT 1 AS "success", SUM(IF(`value` > 0, `value`, 0)) AS "up", SUM(IF(`value` < 0, -`value`, 0)) AS "down" FROM ?_user_ratings WHERE `type` = ?d AND `entry` = ?d AND `userId` <> 0 GROUP BY `entry`', RATING_COMMENT, $this->_get['id']))
$this->result = Util::toJSON($votes);
else
$this->result = Util::toJSON(['success' => 1, 'up' => 0, 'down' => 0]);

View file

@ -25,9 +25,9 @@ class CommentStickyResponse extends TextResponse
}
if ($this->_post['sticky'])
DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` | %i WHERE `id` = %i', CC_FLAG_STICKY, $this->_post['id']);
DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` | ?d WHERE `id` = ?d', CC_FLAG_STICKY, $this->_post['id']);
else
DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` & ~%i WHERE `id` = %i', CC_FLAG_STICKY, $this->_post['id']);
DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` & ~?d WHERE `id` = ?d', CC_FLAG_STICKY, $this->_post['id']);
}
}

View file

@ -24,20 +24,19 @@ class CommentUndeleteResponse extends TextResponse
}
// in theory, there is a username passed alongside if executed from userpage... lets just use the current user (see user.js)
$where = [['`id` IN %in', $this->_post['id']]];
if (!User::isInGroup(U_GROUP_MODERATOR))
{
$where[] = ['`deleteUserId` = `userId'];
$where[] = ['`deleteUserId` = %i', User::$id];
}
$ok = DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` & ~?d WHERE `id` IN (?a) { AND `userId` = `deleteUserId` AND `deleteUserId` = ?d }',
CC_FLAG_DELETED,
$this->_post['id'],
User::isInGroup(U_GROUP_MODERATOR) ? DBSIMPLE_SKIP : User::$id
);
// unflag subject: hasComment
if (DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` & ~%i WHERE %and', CC_FLAG_DELETED, $where))
if ($ok)
{
$coInfo = DB::Aowow()->selectAssoc('SELECT `type` AS "0", `typeId` AS "1" FROM ::comments WHERE `id` IN %in GROUP BY `type`, `typeId`', $this->_post['id']);
$coInfo = DB::Aowow()->select('SELECT `type` AS "0", `typeId` AS "1" FROM ?_comments WHERE `id` IN (?a) GROUP BY `type`, `typeId`', $this->_post['id']);
foreach ($coInfo as [$type, $typeId])
if ($tbl = Type::getClassAttrib($type, 'dataTable'))
DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', $tbl, CUSTOM_HAS_COMMENT, $typeId);
DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_COMMENT, $typeId);
return;
}

View file

@ -26,7 +26,7 @@ class CommentUpvotereplyResponse extends TextResponse
if (!User::canUpvote())
$this->generate404(User::isInGroup(U_GROUP_STAFF) ? 'cannot upvote' : '');
$comment = DB::Aowow()->selectRow('SELECT `userId`, IF(`flags` & %i, 1, 0) AS "deleted" FROM ::comments WHERE `id` = %i', CC_FLAG_DELETED, $this->_post['id']);
$comment = DB::Aowow()->selectRow('SELECT `userId`, IF(`flags` & ?d, 1, 0) AS "deleted" FROM ?_comments WHERE `id` = ?d', CC_FLAG_DELETED, $this->_post['id']);
if (!$comment)
{
trigger_error('CommentUpvotereplyResponse - comment #'.$this->_post['id'].' not found in db', E_USER_ERROR);
@ -39,9 +39,15 @@ class CommentUpvotereplyResponse extends TextResponse
if ($comment['deleted'])
$this->generate404('LANG.votedeleted_tip');
if (is_null(DB::Aowow()->qry('INSERT INTO ::user_ratings (`type`, `entry`, `userId`, `value`) VALUES (%i, %i, %i, %i)',
RATING_COMMENT, $this->_post['id'], User::$id, User::canSupervote() ? 2 : 1
)))
$ok = DB::Aowow()->query(
'INSERT INTO ?_user_ratings (`type`, `entry`, `userId`, `value`) VALUES (?d, ?d, ?d, ?d)',
RATING_COMMENT,
$this->_post['id'],
User::$id,
User::canSupervote() ? 2 : 1
);
if (!$ok)
{
trigger_error('CommentUpvotereplyResponse - write to db failed', E_USER_ERROR);
$this->generate404(User::isInGroup(U_GROUP_STAFF) ? 'write to db failed' : '');

View file

@ -32,7 +32,7 @@ class CommentVoteResponse extends TextResponse
}
$target = DB::Aowow()->selectRow(
'SELECT c.`userId` AS "owner", ur.`value`, IF(c.`flags` & %i, 1, 0) AS "deleted" FROM ::comments c LEFT JOIN ::user_ratings ur ON ur.`type` = %i AND ur.`entry` = c.id AND ur.`userId` = %i WHERE c.id = %i',
'SELECT c.`userId` AS "owner", ur.`value`, IF(c.`flags` & ?d, 1, 0) AS "deleted" FROM ?_comments c LEFT JOIN ?_user_ratings ur ON ur.`type` = ?d AND ur.`entry` = c.id AND ur.`userId` = ?d WHERE c.id = ?d',
CC_FLAG_DELETED, RATING_COMMENT, User::$id, $this->_get['id']
);
if (!$target)
@ -62,9 +62,9 @@ class CommentVoteResponse extends TextResponse
$ok = false;
// old and new have same sign; undo vote (user may have gained/lost access to superVote in the meantime)
if ($target['value'] && ($target['value'] < 0) == ($val < 0))
$ok = DB::Aowow()->qry('DELETE FROM ::user_ratings WHERE `type` = %i AND `entry` = %i AND `userId` = %i', RATING_COMMENT, $this->_get['id'], User::$id);
$ok = DB::Aowow()->query('DELETE FROM ?_user_ratings WHERE `type` = ?d AND `entry` = ?d AND `userId` = ?d', RATING_COMMENT, $this->_get['id'], User::$id);
else // replace, because we may be overwriting an old, opposing vote
if ($ok = DB::Aowow()->qry('REPLACE INTO ::user_ratings (`type`, `entry`, `userId`, `value`) VALUES (%i, %i, %i, %i)', RATING_COMMENT, $this->_get['id'], User::$id, $val))
if ($ok = DB::Aowow()->query('REPLACE INTO ?_user_ratings (`type`, `entry`, `userId`, `value`) VALUES (?d, ?d, ?d, ?d)', RATING_COMMENT, $this->_get['id'], User::$id, $val))
User::decrementDailyVotes(); // do not refund retracted votes!
if ($ok)

View file

@ -34,9 +34,9 @@ class CompareBaseResponse extends TemplateResponse
private string $compareString = '';
public function __construct($rawParam)
public function __construct($pageParam)
{
parent::__construct($rawParam);
parent::__construct($pageParam);
// prefer GET over COOKIE
if ($this->_get['compare'])
@ -106,7 +106,7 @@ class CompareBaseResponse extends TemplateResponse
protected static function checkCompareString(string $val) : string
{
$val = urldecode($val);
if (preg_match('/[^-?\d\.:;]/', $val))
if (preg_match('/[^\d\.:;]/', $val))
return '';
return $val;

View file

@ -9,15 +9,15 @@ if (!defined('AOWOW_REVISION'))
class ContactusBaseResponse extends TextResponse
{
protected array $expectedPOST = array(
'mode' => ['filter' => FILTER_VALIDATE_INT ],
'reason' => ['filter' => FILTER_VALIDATE_INT ],
'ua' => ['filter' => FILTER_CALLBACK, 'options' => [self::class, 'checkTextLine'] ],
'appname' => ['filter' => FILTER_CALLBACK, 'options' => [self::class, 'checkTextLine'] ],
'page' => ['filter' => FILTER_VALIDATE_REGEXP, 'options' => ['regexp' => '/^[[:print:]]+$/']],
'desc' => ['filter' => FILTER_CALLBACK, 'options' => [self::class, 'checkTextBlob'] ],
'id' => ['filter' => FILTER_VALIDATE_INT ],
'relatedurl' => ['filter' => FILTER_VALIDATE_REGEXP, 'options' => ['regexp' => '/^[[:print:]]+$/']],
'email' => ['filter' => FILTER_SANITIZE_EMAIL ]
'mode' => ['filter' => FILTER_VALIDATE_INT ],
'reason' => ['filter' => FILTER_VALIDATE_INT ],
'ua' => ['filter' => FILTER_CALLBACK, 'options' => [self::class, 'checkTextLine']],
'appname' => ['filter' => FILTER_CALLBACK, 'options' => [self::class, 'checkTextLine']],
'page' => ['filter' => FILTER_SANITIZE_URL ],
'desc' => ['filter' => FILTER_CALLBACK, 'options' => [self::class, 'checkTextBlob']],
'id' => ['filter' => FILTER_VALIDATE_INT ],
'relatedurl' => ['filter' => FILTER_SANITIZE_URL ],
'email' => ['filter' => FILTER_SANITIZE_EMAIL ]
);
/* responses

View file

@ -32,7 +32,7 @@ class CookieBaseResponse extends TextResponse
{
if (!$this->param && $this->_get['purge'])
{
if (User::$id && DB::Aowow()->qry('UPDATE ::account_cookies SET `data` = "purged" WHERE `userId` = %i AND `name` LIKE "announcement-%"', User::$id) !== null)
if (User::$id && DB::Aowow()->query('UPDATE ?_account_cookies SET `data` = "purged" WHERE `userId` = ?d AND `name` LIKE "announcement-%"', User::$id) !== null)
$this->result = 0;
return;
@ -44,7 +44,7 @@ class CookieBaseResponse extends TextResponse
return;
}
if (DB::Aowow()->qry('REPLACE INTO ::account_cookies VALUES (%i, %s, %s)', User::$id, $this->param, $this->_get[$this->param]))
if (DB::Aowow()->query('REPLACE INTO ?_account_cookies VALUES (?d, ?, ?)', User::$id, $this->param, $this->_get[$this->param]))
$this->result = 0;
else
trigger_error('CookieBaseResponse - write to db failed', E_USER_ERROR);

View file

@ -11,7 +11,7 @@ class CurrenciesBaseResponse extends TemplateResponse implements ICache
use TrListPage, TrCache;
protected int $type = Type::CURRENCY;
protected int $cacheType = CACHE_TYPE_LIST_PAGE;
protected int $cacheType = CACHE_TYPE_PAGE;
protected string $template = 'list-page-generic';
protected string $pageName = 'currencies';
@ -20,11 +20,11 @@ class CurrenciesBaseResponse extends TemplateResponse implements ICache
protected array $validCats = [1, 2, 3, 22];
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
$this->getCategoryFromUrl($rawParam);
$this->getCategoryFromUrl($pageParam);
parent::__construct($rawParam);
parent::__construct($pageParam);
}
protected function generate() : void

View file

@ -10,7 +10,7 @@ class CurrencyBaseResponse extends TemplateResponse implements ICache
{
use TrDetailPage, TrCache;
protected int $cacheType = CACHE_TYPE_DETAIL_PAGE;
protected int $cacheType = CACHE_TYPE_PAGE;
protected string $template = 'detail-page-generic';
protected string $pageName = 'currency';
@ -72,20 +72,13 @@ class CurrencyBaseResponse extends TemplateResponse implements ICache
if ($_ = $this->subject->getField('cap'))
$infobox[] = Lang::currency('cap').Lang::nf($_);
// id
$infobox[] = Lang::currency('id') . $this->typeId;
// icon
if ($_ = $this->subject->getField('iconId'))
{
$infobox[] = Util::ucFirst(Lang::game('icon')).Lang::main('colon').'[icondb='.$_.' name=true]';
$infobox[] = Util::ucFirst(lang::game('icon')).Lang::main('colon').'[icondb='.$_.' name=true]';
$this->extendGlobalIds(Type::ICON, $_);
}
// original name
if (Lang::getLocale() != Locale::EN)
$infobox[] = Util::ucFirst(Lang::lang(Locale::EN->value) . Lang::main('colon')) . '[copy button=false]'.$this->subject->getField('name_loc0').'[/copy][/li]';
if ($infobox)
$this->infobox = new InfoboxMarkup($infobox, ['allow' => Markup::CLASS_STAFF, 'dbpage' => true], 'infobox-contents0');
@ -117,9 +110,9 @@ class CurrencyBaseResponse extends TemplateResponse implements ICache
if ($this->typeId != CURRENCY_HONOR_POINTS && $this->typeId != CURRENCY_ARENA_POINTS)
{
// tabs: this currency is contained in..
$lootTabs = new LootByItem($_relItemId);
$lootTabs = new Loot();
if ($lootTabs->getByItem())
if ($lootTabs->getByItem($_relItemId))
{
$this->extendGlobalData($lootTabs->jsGlobals);
@ -128,15 +121,6 @@ class CurrencyBaseResponse extends TemplateResponse implements ICache
if ($template == 'npc' || $template == 'object')
$this->addDataLoader('zones');
if ($template != 'quest')
{
foreach ($tabData['data'] as &$row)
if (!empty($row['stack']))
$row['currency'] = [[$this->typeId, $row['stack'][0]]];
$tabData['extraCols'][] = '$Listview.extraCols.currency';
}
$this->lvTabs->addListviewTab(new Listview($tabData, $template));
}
}
@ -198,10 +182,10 @@ class CurrencyBaseResponse extends TemplateResponse implements ICache
}
}
// tab: created by (spell) [for items its handled in LootByItem]
// tab: created by (spell) [for items its handled in Loot::getByContainer()]
if ($this->typeId == CURRENCY_HONOR_POINTS)
{
$createdBy = new SpellList(array(['effect1Id', SPELL_EFFECT_ADD_HONOR], ['effect2Id', SPELL_EFFECT_ADD_HONOR], ['effect3Id', SPELL_EFFECT_ADD_HONOR], DB::OR));
$createdBy = new SpellList(array(['effect1Id', SPELL_EFFECT_ADD_HONOR], ['effect2Id', SPELL_EFFECT_ADD_HONOR], ['effect3Id', SPELL_EFFECT_ADD_HONOR], 'OR'));
if (!$createdBy->error)
{
$this->extendGlobalData($createdBy->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED));
@ -237,8 +221,8 @@ class CurrencyBaseResponse extends TemplateResponse implements ICache
if (!$n && !is_null(ItemListFilter::getCriteriaIndex(158, $_relItemId)))
$n = '?items&filter=cr=158;crs='.$_relItemId.';crv=0';
$xCosts = DB::Aowow()->selectCol('SELECT `id` FROM ::itemextendedcost WHERE '.$w);
$boughtBy = $xCosts ? DB::World()->selectCol('SELECT `item` FROM npc_vendor WHERE `extendedCost` IN %in UNION SELECT `item` FROM game_event_npc_vendor WHERE `extendedCost` IN %in', $xCosts, $xCosts) : [];
$xCosts = DB::Aowow()->selectCol('SELECT `id` FROM ?_itemextendedcost WHERE '.$w);
$boughtBy = $xCosts ? DB::World()->selectCol('SELECT `item` FROM npc_vendor WHERE `extendedCost` IN (?a) UNION SELECT `item` FROM game_event_npc_vendor WHERE `extendedCost` IN (?a)', $xCosts, $xCosts) : [];
if ($boughtBy)
{
$boughtBy = new ItemList(array(['id', $boughtBy]));

View file

@ -9,7 +9,7 @@ if (!defined('AOWOW_REVISION'))
class DataBaseResponse extends TextResponse
{
protected array $expectedGET = array(
'locale' => ['filter' => FILTER_CALLBACK, 'options' => [self::class, 'checkLocale' ]],
'locale' => ['filter' => FILTER_CALLBACK, 'options' => [Locale::class, 'tryFrom'] ],
't' => ['filter' => FILTER_CALLBACK, 'options' => [self::class, 'checkTextLine' ]],
'catg' => ['filter' => FILTER_VALIDATE_INT ],
'skill' => ['filter' => FILTER_CALLBACK, 'options' => [self::class, 'checkSkill' ]],
@ -17,9 +17,9 @@ class DataBaseResponse extends TextResponse
'callback' => ['filter' => FILTER_CALLBACK, 'options' => [self::class, 'checkCallback' ]]
);
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
parent::__construct($rawParam);
parent::__construct($pageParam);
if ($this->_get['locale']?->validate())
Lang::load($this->_get['locale']);
@ -31,7 +31,7 @@ class DataBaseResponse extends TextResponse
foreach ($this->params as $set)
{
// requires valid token to hinder automated access
if ($set != 'item-scaling' && $set != 'spell-scaling' && (!$this->_get['t'] || empty($_SESSION['dataKey']) || $this->_get['t'] != $_SESSION['dataKey']))
if ($set != 'item-scaling' && (!$this->_get['t'] || empty($_SESSION['dataKey']) || $this->_get['t'] != $_SESSION['dataKey']))
{
trigger_error('DataBaseResponse::generate - session data key empty or expired', E_USER_ERROR);
continue;
@ -54,7 +54,6 @@ class DataBaseResponse extends TextResponse
'quick-excludes',
'weight-presets',
'item-scaling',
'spell-scaling',
'realms',
'statistics' => $this->loadAgnosticFile($set),
// localized

View file

@ -10,7 +10,7 @@ class EmoteBaseResponse extends TemplateResponse implements ICache
{
use TrDetailPage, TrCache;
protected int $cacheType = CACHE_TYPE_DETAIL_PAGE;
protected int $cacheType = CACHE_TYPE_PAGE;
protected string $template = 'detail-page-generic';
protected string $pageName = 'emote';
@ -94,9 +94,6 @@ class EmoteBaseResponse extends TemplateResponse implements ICache
}
}
// id
$infobox[] = Lang::emote('id') . $this->typeId;
if ($infobox)
$this->infobox = new InfoboxMarkup($infobox, ['allow' => Markup::CLASS_STAFF, 'dbpage' => true], 'infobox-contents0');
@ -109,7 +106,7 @@ class EmoteBaseResponse extends TemplateResponse implements ICache
if ($this->subject->getField('cuFlags') & EMOTE_CU_MISSING_CMD)
$text .= Lang::emote('noCommand').'[br][br]';
else if ($aliasses = DB::Aowow()->selectCol('SELECT `command` FROM ::emotes_aliasses WHERE `id` = %i AND `locales` & %i', $this->typeId, 1 << Lang::getLocale()->value))
else if ($aliasses = DB::Aowow()->selectCol('SELECT `command` FROM ?_emotes_aliasses WHERE `id` = ?d AND `locales` & ?d', $this->typeId, 1 << Lang::getLocale()->value))
{
$text .= '[h3]'.Lang::emote('aliases').'[/h3][ul]';
foreach ($aliasses as $a)
@ -184,12 +181,13 @@ class EmoteBaseResponse extends TemplateResponse implements ICache
}
// tab: sound
$ems = DB::Aowow()->selectAssoc(
$ems = DB::Aowow()->select(
'SELECT `soundId` AS ARRAY_KEY, BIT_OR(1 << (`raceId` - 1)) AS "raceMask", BIT_OR(1 << (`gender` - 1)) AS "gender"
FROM ::emotes_sounds
WHERE %if', $this->typeId < 0, '-`emoteId` = %i OR', $this->subject->getField('parentEmote'), '%end `emoteId` = %i
FROM ?_emotes_sounds
WHERE `emoteId` = ?d { OR -`emoteId` = ?d }
GROUP BY `soundId`',
$this->typeId,
$this->typeId < 0 ? $this->subject->getField('parentEmote') : DBSIMPLE_SKIP
);
if ($ems)

View file

@ -10,7 +10,7 @@ class EmotesBaseResponse extends TemplateResponse implements ICache
{
use TrListPage, TrCache;
protected int $cacheType = CACHE_TYPE_LIST_PAGE;
protected int $cacheType = CACHE_TYPE_PAGE;
protected int $type = Type::EMOTE;
protected string $template = 'list-page-generic';
@ -18,11 +18,11 @@ class EmotesBaseResponse extends TemplateResponse implements ICache
protected ?int $activeTab = parent::TAB_DATABASE;
protected array $breadcrumb = [0, 100];
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
$this->getCategoryFromUrl($rawParam);
$this->getCategoryFromUrl($pageParam);
parent::__construct($rawParam);
parent::__construct($pageParam);
}
protected function generate() : void
@ -41,7 +41,7 @@ class EmotesBaseResponse extends TemplateResponse implements ICache
/* Main Content */
/****************/
$cnd = []; // don't limit, for we have no filter or category
$cnd = [Cfg::get('SQL_LIMIT_NONE')];
if (!User::isInGroup(U_GROUP_STAFF))
$cnd[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0];

View file

@ -10,7 +10,7 @@ class EnchantmentBaseResponse extends TemplateResponse implements ICache
{
use TrDetailPage, TrCache;
protected int $cacheType = CACHE_TYPE_DETAIL_PAGE;
protected int $cacheType = CACHE_TYPE_PAGE;
protected string $template = 'enchantment';
protected string $pageName = 'enchantment';
@ -85,13 +85,6 @@ class EnchantmentBaseResponse extends TemplateResponse implements ICache
$infobox[] = $foo;
}
// id
$infobox[] = Lang::enchantment('id') . $this->typeId;
// original name
if (Lang::getLocale() != Locale::EN)
$infobox[] = Util::ucFirst(Lang::lang(Locale::EN->value) . Lang::main('colon')) . '[copy button=false]'.$this->subject->getField('name_loc0').'[/copy][/li]';
if ($infobox)
$this->infobox = new InfoboxMarkup($infobox, ['allow' => Markup::CLASS_STAFF, 'dbpage' => true], 'infobox-contents0');
@ -194,10 +187,10 @@ class EnchantmentBaseResponse extends TemplateResponse implements ICache
// used by spell
// used by useItem
$cnd = array(
DB::OR,
[DB::AND, ['effect1Id', SpellList::EFFECTS_ENCHANTMENT], ['effect1MiscValue', $this->typeId]],
[DB::AND, ['effect2Id', SpellList::EFFECTS_ENCHANTMENT], ['effect2MiscValue', $this->typeId]],
[DB::AND, ['effect3Id', SpellList::EFFECTS_ENCHANTMENT], ['effect3MiscValue', $this->typeId]],
'OR',
['AND', ['effect1Id', SpellList::EFFECTS_ENCHANTMENT], ['effect1MiscValue', $this->typeId]],
['AND', ['effect2Id', SpellList::EFFECTS_ENCHANTMENT], ['effect2MiscValue', $this->typeId]],
['AND', ['effect3Id', SpellList::EFFECTS_ENCHANTMENT], ['effect3MiscValue', $this->typeId]],
);
$spellList = new SpellList($cnd);
if (!$spellList->error)
@ -207,12 +200,12 @@ class EnchantmentBaseResponse extends TemplateResponse implements ICache
$spellIds = $spellList->getFoundIDs();
$conditions = array(
DB::OR,
[DB::AND, ['spellTrigger1', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId1', $spellIds]],
[DB::AND, ['spellTrigger2', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId2', $spellIds]],
[DB::AND, ['spellTrigger3', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId3', $spellIds]],
[DB::AND, ['spellTrigger4', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId4', $spellIds]],
[DB::AND, ['spellTrigger5', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId5', $spellIds]]
'OR',
['AND', ['spellTrigger1', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId1', $spellIds]],
['AND', ['spellTrigger2', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId2', $spellIds]],
['AND', ['spellTrigger3', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId3', $spellIds]],
['AND', ['spellTrigger4', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId4', $spellIds]],
['AND', ['spellTrigger5', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId5', $spellIds]]
);
$ubItems = new ItemList($conditions);
@ -259,19 +252,19 @@ class EnchantmentBaseResponse extends TemplateResponse implements ICache
}
// used by randomAttrItem
$ire = DB::Aowow()->selectAssoc(
'SELECT *, ABS(`id`) AS ARRAY_KEY FROM ::itemrandomenchant WHERE `enchantId1` = %i OR `enchantId2` = %i OR `enchantId3` = %i OR `enchantId4` = %i OR `enchantId5` = %i',
$ire = DB::Aowow()->select(
'SELECT *, ABS(`id`) AS ARRAY_KEY FROM ?_itemrandomenchant WHERE `enchantId1` = ?d OR `enchantId2` = ?d OR `enchantId3` = ?d OR `enchantId4` = ?d OR `enchantId5` = ?d',
$this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId
);
if ($ire)
{
if ($iet = DB::World()->selectAssoc('SELECT `entry` AS ARRAY_KEY, `ench`, `chance` FROM item_enchantment_template WHERE `ench` IN %in', array_keys($ire)))
if ($iet = DB::World()->select('SELECT `entry` AS ARRAY_KEY, `ench`, `chance` FROM item_enchantment_template WHERE `ench` IN (?a)', array_keys($ire)))
{
$randIds = []; // transform back to signed format
foreach ($iet as $tplId => $data)
$randIds[$ire[$data['ench']]['id'] > 0 ? $tplId : -$tplId] = $ire[$data['ench']]['id'];
$randItems = new ItemList(array(['randomEnchant', array_keys($randIds)]));
$randItems = new ItemList(array(Cfg::get('SQL_LIMIT_NONE'), ['randomEnchant', array_keys($randIds)]));
if (!$randItems->error)
{
$data = $randItems->getListviewData();

View file

@ -11,7 +11,7 @@ class EnchantmentsBaseResponse extends TemplateResponse implements ICache
use TrListPage, TrCache;
protected int $type = Type::ENCHANTMENT;
protected int $cacheType = CACHE_TYPE_LIST_PAGE;
protected int $cacheType = CACHE_TYPE_PAGE;
protected string $template = 'enchantments';
protected string $pageName = 'enchantments';
@ -24,25 +24,17 @@ class EnchantmentsBaseResponse extends TemplateResponse implements ICache
);
protected array $validCats = [1, 2, 3, 4, 5, 6, 7, 8];
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
$this->getCategoryFromUrl($rawParam);
$this->getCategoryFromUrl($pageParam);
parent::__construct($rawParam);
parent::__construct($pageParam);
if ($this->category)
$this->forward('?enchantments&filter=ty='.$this->category[0]);
if ($this->category)
$this->subCat = '='.implode('.', $this->category);
$this->subCat = $pageParam !== '' ? '='.$pageParam : '';
$this->filter = new EnchantmentListFilter($this->_get['filter'] ?? '', ['parentCats' => $this->category]);
if ($this->filter->shouldReload)
{
$_SESSION['error']['fi'] = $this->filter::class;
$get = $this->filter->buildGETParam();
$this->forward('?' . $this->pageName . $this->subCat . ($get ? '&filter=' . $get : ''));
}
$this->filterError = $this->filter->error;
}
@ -50,13 +42,18 @@ class EnchantmentsBaseResponse extends TemplateResponse implements ICache
{
$this->h1 = Util::ucFirst(Lang::game('enchantments'));
$conditions = [Listview::DEFAULT_SIZE];
$this->filter->evalCriteria();
$conditions = [];
if (!User::isInGroup(U_GROUP_EMPLOYEE))
$conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0];
if ($_ = $this->filter->getConditions())
$conditions[] = $_;
$this->filterError = $this->filter->error; // maybe the evalX() caused something
/**************/
/* Page Title */
@ -114,9 +111,9 @@ class EnchantmentsBaseResponse extends TemplateResponse implements ICache
if (!$ench->hasSetFields('skillLine'))
$tabData['hiddenCols'] = ['skill'];
if ($ench->getMatches() > Listview::DEFAULT_SIZE)
if ($ench->getMatches() > Cfg::get('SQL_LIMIT_DEFAULT'))
{
$tabData['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_enchantmentsfound', $ench->getMatches(), Listview::DEFAULT_SIZE);
$tabData['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_enchantmentsfound', $ench->getMatches(), Cfg::get('SQL_LIMIT_DEFAULT'));
$tabData['_truncated'] = 1;
}

View file

@ -10,7 +10,7 @@ class EventBaseResponse extends TemplateResponse implements ICache
{
use TrDetailPage, TrCache;
protected int $cacheType = CACHE_TYPE_DETAIL_PAGE;
protected int $cacheType = CACHE_TYPE_PAGE;
protected string $template = 'detail-page-generic';
protected string $pageName = 'event';
@ -88,23 +88,9 @@ class EventBaseResponse extends TemplateResponse implements ICache
$infobox[] = Lang::npc('rank', 3).Lang::main('colon').'[npc='.$_.']';
}
// id
$infobox[] = Lang::event('id') . $this->typeId;
// display holiday id to staff
if ($_holidayId && User::isInGroup(U_GROUP_STAFF))
$infobox[] = 'Holiday ID'.Lang::main('colon').$_holidayId;
// icon
if ($_ = $this->subject->getField('iconId'))
{
$infobox[] = Util::ucFirst(Lang::game('icon')).Lang::main('colon').'[icondb='.$_.' name=true]';
$this->extendGlobalIds(Type::ICON, $_);
}
// original name
if (Lang::getLocale() != Locale::EN)
$infobox[] = Util::ucFirst(Lang::lang(Locale::EN->value) . Lang::main('colon')) . '[copy button=false]'.$this->subject->getField('name_loc0').'[/copy][/li]';
// display internal id to staff
if (User::isInGroup(U_GROUP_STAFF))
$infobox[] = 'Event-Id'.Lang::main('colon').$this->typeId;
if ($infobox)
$this->infobox = new InfoboxMarkup($infobox, ['allow' => Markup::CLASS_STAFF, 'dbpage' => true], 'infobox-contents0');
@ -114,7 +100,7 @@ class EventBaseResponse extends TemplateResponse implements ICache
/* Main Content */
/****************/
// no entry in ::articles? use default HolidayDescription
// no entry in ?_articles? use default HolidayDescription
if ($_holidayId && empty($this->article))
$this->article = new Markup($this->subject->getField('description', true), ['dbpage' => true]);
@ -137,7 +123,7 @@ class EventBaseResponse extends TemplateResponse implements ICache
$this->lvTabs = new Tabs(['parent' => "\$\$WH.ge('tabs-generic')"], 'tabsRelated', true);
// tab: npcs
if ($npcIds = DB::World()->selectCol('SELECT `id` AS ARRAY_KEY, IF(ec.`eventEntry` > 0, 1, 0) AS "added" FROM creature c, game_event_creature ec WHERE ec.`guid` = c.`guid` AND ABS(ec.`eventEntry`) = %i', $this->typeId))
if ($npcIds = DB::World()->selectCol('SELECT `id` AS ARRAY_KEY, IF(ec.`eventEntry` > 0, 1, 0) AS "added" FROM creature c, game_event_creature ec WHERE ec.`guid` = c.`guid` AND ABS(ec.`eventEntry`) = ?d', $this->typeId))
{
$creatures = new CreatureList(array(['id', array_keys($npcIds)]));
if (!$creatures->error)
@ -157,7 +143,7 @@ class EventBaseResponse extends TemplateResponse implements ICache
}
// tab: objects
if ($objectIds = DB::World()->selectCol('SELECT `id` AS ARRAY_KEY, IF(eg.`eventEntry` > 0, 1, 0) AS "added" FROM gameobject g, game_event_gameobject eg WHERE eg.`guid` = g.`guid` AND ABS(eg.`eventEntry`) = %i', $this->typeId))
if ($objectIds = DB::World()->selectCol('SELECT `id` AS ARRAY_KEY, IF(eg.`eventEntry` > 0, 1, 0) AS "added" FROM gameobject g, game_event_gameobject eg WHERE eg.`guid` = g.`guid` AND ABS(eg.`eventEntry`) = ?d', $this->typeId))
{
$objects = new GameObjectList(array(['id', array_keys($objectIds)]));
if (!$objects->error)
@ -177,7 +163,6 @@ class EventBaseResponse extends TemplateResponse implements ICache
}
// tab: achievements
$exclAcvs = [];
if ($_ = $this->subject->getField('achievementCatOrId'))
{
$condition = $_ > 0 ? [['category', $_]] : [['id', -$_]];
@ -191,9 +176,6 @@ class EventBaseResponse extends TemplateResponse implements ICache
'visibleCols' => ['category']
);
// don't reuse for criteria-of tab
$exclAcvs = array_keys($tabData['data']);
if ($_holidayId && AchievementListFilter::getCriteriaIndex(11, $_holidayId))
$tabData['note'] = sprintf(Util::$filterResultString, '?achievements&filter=cr=11;crs='.$_holidayId.';crv=0');
@ -204,54 +186,37 @@ class EventBaseResponse extends TemplateResponse implements ICache
$itemCnd = [];
if ($_holidayId)
{
// tab: criteria-of
if ($extraCrt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` = %i AND `value1` = %i', ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY, $_holidayId))
$itemCnd = array(
'OR',
['eventId', $this->typeId], // direct requirement on item
);
// tab: quests (by table, go & creature)
$quests = new QuestList(array(['eventId', $this->typeId]));
if (!$quests->error)
{
$condition = array(['ac.id', $extraCrt]);
if ($exclAcvs)
$condition[] = ['a.id', $exclAcvs, '!'];
$this->extendGlobalData($quests->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_REWARDS));
$crtOf = new AchievementList($condition);
if (!$crtOf->error)
{
$this->extendGlobalData($crtOf->getJSGlobals());
$tabData = ['data'=> $quests->getListviewData()];
$this->lvTabs->addListviewTab(new Listview(array(
'data' => $crtOf->getListviewData(),
'name' => '$LANG.tab_criteriaof',
'id' => 'criteria-of'
), AchievementList::$brickFile));
}
if (QuestListFilter::getCriteriaIndex(33, $_holidayId))
$tabData['note'] = sprintf(Util::$filterResultString, '?quests&filter=cr=33;crs='.$_holidayId.';crv=0');
$this->lvTabs->addListviewTab(new Listview($tabData, QuestList::$brickFile));
$questItems = [];
foreach (array_column($quests->rewards, Type::ITEM) as $arr)
$questItems = array_merge($questItems, array_keys($arr));
foreach (array_column($quests->choices, Type::ITEM) as $arr)
$questItems = array_merge($questItems, array_keys($arr));
foreach (array_column($quests->requires, Type::ITEM) as $arr)
$questItems = array_merge($questItems, $arr);
if ($questItems)
$itemCnd[] = ['id', $questItems];
}
$itemCnd[] = ['eventId', $this->typeId]; // direct requirement on item
}
// tab: quests (by table, go & creature)
$quests = new QuestList(array(['eventId', $this->typeId]));
if (!$quests->error)
{
$this->extendGlobalData($quests->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_REWARDS));
$tabData = ['data'=> $quests->getListviewData()];
if (QuestListFilter::getCriteriaIndex(33, $_holidayId))
$tabData['note'] = sprintf(Util::$filterResultString, '?quests&filter=cr=33;crs='.$_holidayId.';crv=0');
$this->lvTabs->addListviewTab(new Listview($tabData, QuestList::$brickFile));
$questItems = [];
foreach (array_column($quests->rewards, Type::ITEM) as $arr)
$questItems = array_merge($questItems, array_keys($arr));
foreach (array_column($quests->choices, Type::ITEM) as $arr)
$questItems = array_merge($questItems, array_keys($arr));
foreach (array_column($quests->requires, Type::ITEM) as $arr)
$questItems = array_merge($questItems, $arr);
if ($questItems)
$itemCnd[] = ['id', $questItems];
}
// items from creature
@ -260,9 +225,9 @@ class EventBaseResponse extends TemplateResponse implements ICache
// vendor
$cIds = $creatures->getFoundIDs();
if ($sells = DB::World()->selectCol(
'SELECT `item` FROM npc_vendor nv WHERE `entry` IN %in UNION
SELECT nv1.`item` FROM npc_vendor nv1 JOIN npc_vendor nv2 ON -nv1.`entry` = nv2.`item` WHERE nv2.`entry` IN %in UNION
SELECT `item` FROM game_event_npc_vendor genv JOIN creature c ON genv.`guid` = c.`guid` WHERE c.`id` IN %in',
'SELECT `item` FROM npc_vendor nv WHERE `entry` IN (?a) UNION
SELECT nv1.`item` FROM npc_vendor nv1 JOIN npc_vendor nv2 ON -nv1.`entry` = nv2.`item` WHERE nv2.`entry` IN (?a) UNION
SELECT `item` FROM game_event_npc_vendor genv JOIN creature c ON genv.`guid` = c.`guid` WHERE c.`id` IN (?a)',
$cIds, $cIds, $cIds
))
$itemCnd[] = ['id', $sells];
@ -272,7 +237,6 @@ class EventBaseResponse extends TemplateResponse implements ICache
// not checking for loot ... cant distinguish between eventLoot and fillerCrapLoot
if ($itemCnd)
{
array_unshift($itemCnd, DB::OR);
$eventItems = new ItemList($itemCnd);
if (!$eventItems->error)
{
@ -288,7 +252,7 @@ class EventBaseResponse extends TemplateResponse implements ICache
}
// tab: see also (event conditions)
if ($rel = DB::World()->selectCol('SELECT IF(`eventEntry` = `prerequisite_event`, NULL, IF(`eventEntry` = %i, `prerequisite_event`, -`eventEntry`)) FROM game_event_prerequisite WHERE `prerequisite_event` = %i OR `eventEntry` = %i', $this->typeId, $this->typeId, $this->typeId))
if ($rel = DB::World()->selectCol('SELECT IF(`eventEntry` = `prerequisite_event`, NULL, IF(`eventEntry` = ?d, `prerequisite_event`, -`eventEntry`)) FROM game_event_prerequisite WHERE `prerequisite_event` = ?d OR `eventEntry` = ?d', $this->typeId, $this->typeId, $this->typeId))
{
if (array_filter($rel, fn($x) => $x === null))
trigger_error('game_event_prerequisite: this event has itself as prerequisite', E_USER_WARNING);
@ -356,7 +320,7 @@ class EventBaseResponse extends TemplateResponse implements ICache
// interval
if ($rec > 0)
$infobox[] = Lang::event('interval').DateTime::formatTimeElapsed($rec * 1000);
$infobox[] = Lang::event('interval').Util::formatTime($rec * 1000);
// in progress
if ($start < time() && $end > time())

View file

@ -11,7 +11,7 @@ class EventsBaseResponse extends TemplateResponse implements ICache
use TrListPage, TrCache;
protected int $type = Type::WORLDEVENT;
protected int $cacheType = CACHE_TYPE_LIST_PAGE;
protected int $cacheType = CACHE_TYPE_PAGE;
protected string $template = 'list-page-generic';
protected string $pageName = 'events';
@ -20,11 +20,11 @@ class EventsBaseResponse extends TemplateResponse implements ICache
protected array $validCats = [0, 1, 2, 3];
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
$this->getCategoryFromUrl($rawParam);
$this->getCategoryFromUrl($pageParam);
parent::__construct($rawParam);
parent::__construct($pageParam);
}
protected function generate() : void
@ -55,7 +55,7 @@ class EventsBaseResponse extends TemplateResponse implements ICache
$this->redButtons[BUTTON_WOWHEAD] = true;
$condition = [Listview::DEFAULT_SIZE];
$condition = [];
if (!User::isInGroup(U_GROUP_EMPLOYEE))
$condition[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0];

View file

@ -10,7 +10,7 @@ class FactionBaseResponse extends TemplateResponse implements ICache
{
use TrDetailPage, TrCache;
protected int $cacheType = CACHE_TYPE_DETAIL_PAGE;
protected int $cacheType = CACHE_TYPE_PAGE;
protected string $template = 'detail-page-generic';
protected string $pageName = 'faction';
@ -96,25 +96,8 @@ class FactionBaseResponse extends TemplateResponse implements ICache
if ($_ = $this->subject->getField('side'))
$infobox[] = Lang::main('side').'[span class=icon-'.($_ == SIDE_ALLIANCE ? 'alliance' : 'horde').']'.Lang::game('si', $_).'[/span]';
// id
$infobox[] = Lang::faction('id') . $this->typeId;
// profiler relateed (note that this is part of the cache. I don't think this is important enough to calc for every view)
if (Cfg::get('PROFILER_ENABLE') && !($this->subject->getField('cuFlags') & CUSTOM_EXCLUDE_FOR_LISTVIEW))
{
$x = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ::profiler_completion_reputation WHERE `exalted` = 1 AND `factionId` = %i', $this->typeId);
$y = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ::profiler_profiles WHERE `custom` = 0 AND `stub` = 0');
$infobox[] = Lang::profiler('attainedBy', [round(($x ?: 0) * 100 / ($y ?: 1))]);
// completion row added by InfoboxMarkup
}
// original name
if (Lang::getLocale() != Locale::EN)
$infobox[] = Util::ucFirst(Lang::lang(Locale::EN->value) . Lang::main('colon')) . '[copy button=false]'.$this->subject->getField('name_loc0').'[/copy][/li]';
if ($infobox) // unsure if this should be tracked (needs data dump in User::getCompletion())
$this->infobox = new InfoboxMarkup($infobox, ['allow' => Markup::CLASS_STAFF, 'dbpage' => true], 'infobox-contents0', 0);
if ($infobox)
$this->infobox = new InfoboxMarkup($infobox, ['allow' => Markup::CLASS_STAFF, 'dbpage' => true], 'infobox-contents0');
/****************/
@ -132,7 +115,7 @@ class FactionBaseResponse extends TemplateResponse implements ICache
CONCAT_WS(" ", faction1, faction2, faction3, faction4) AS faction,
CONCAT_WS(" ", rate_1, rate_2, rate_3, rate_4) AS rate,
CONCAT_WS(" ", rank_1, rank_2, rank_3, rank_4) AS rank
FROM reputation_spillover_template WHERE faction = %i', $this->typeId);
FROM reputation_spillover_template WHERE faction = ?d', $this->typeId);
*/
@ -142,7 +125,7 @@ class FactionBaseResponse extends TemplateResponse implements ICache
);
if ($p = $this->subject->getField('parentFactionId')) // linked via parent
$conditions[] = [DB::OR, ['id', $p], ['parentFactionId', $p]];
$conditions[] = ['OR', ['id', $p], ['parentFactionId', $p]];
else // self as parent
$conditions[] = ['parentFactionId', $this->typeId];
@ -162,7 +145,7 @@ class FactionBaseResponse extends TemplateResponse implements ICache
);
// reward rates (ultimately this should be calculated into each reward display)
if ($rates = DB::World()->selectRow('SELECT `quest_rate`, `quest_daily_rate`, `quest_weekly_rate`, `quest_monthly_rate`, `quest_repeatable_rate`, `creature_rate`, `spell_rate` FROM reputation_reward_rate WHERE `faction` = %i', $this->typeId))
if ($rates = DB::World()->selectRow('SELECT `quest_rate`, `quest_daily_rate`, `quest_weekly_rate`, `quest_monthly_rate`, `quest_repeatable_rate`, `creature_rate`, `spell_rate` FROM reputation_reward_rate WHERE `faction` = ?d', $this->typeId))
{
$buff = '';
foreach ($rates as $k => $v)
@ -191,7 +174,7 @@ class FactionBaseResponse extends TemplateResponse implements ICache
}
// factionchange-equivalent
if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = %i, `alliance_id`, -`horde_id`) FROM player_factionchange_reputations WHERE `alliance_id` = %i OR `horde_id` = %i', $this->typeId, $this->typeId, $this->typeId))
if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = ?d, `alliance_id`, -`horde_id`) FROM player_factionchange_reputations WHERE `alliance_id` = ?d OR `horde_id` = ?d', $this->typeId, $this->typeId, $this->typeId))
{
$altFac = new FactionList(array(['id', abs($pendant)]));
if (!$altFac->error)
@ -213,7 +196,7 @@ class FactionBaseResponse extends TemplateResponse implements ICache
$this->lvTabs = new Tabs(['parent' => "\$\$WH.ge('tabs-generic')"], 'tabsRelated', true);
// tab: items
$items = new ItemList(array(Listview::DEFAULT_SIZE, ['requiredFaction', $this->typeId]), ['calcTotal' => true]);
$items = new ItemList(array(['requiredFaction', $this->typeId]), ['calcTotal' => true]);
if (!$items->error)
{
$this->extendGlobalData($items->getJSGlobals(GLOBALINFO_SELF));
@ -224,9 +207,8 @@ class FactionBaseResponse extends TemplateResponse implements ICache
'sort' => ['standing', 'name']
);
if ($items->getMatches() > Listview::DEFAULT_SIZE)
if (!is_null(ItemListFilter::getCriteriaIndex(17, $this->typeId)))
$tabData['note'] = sprintf(Util::$filterResultString, '?items&filter=cr=17;crs='.$this->typeId.';crv=0');
if ($items->getMatches() > Cfg::get('SQL_LIMIT_DEFAULT'))
$tabData['note'] = sprintf(Util::$filterResultString, '?items&filter=cr=17;crs='.$this->typeId.';crv=0');
$this->lvTabs->addListviewTab(new Listview($tabData, ItemList::$brickFile, 'itemStandingCol'));
}
@ -237,16 +219,16 @@ class FactionBaseResponse extends TemplateResponse implements ICache
{
// inherit siblings/children from $spillover
$cRep = DB::World()->selectCol('SELECT DISTINCT `creature_id` AS ARRAY_KEY, `qty` FROM (
SELECT `creature_id`, `RewOnKillRepValue1` as "qty" FROM creature_onkill_reputation WHERE `RewOnKillRepValue1` > 0 AND (`RewOnKillRepFaction1` = %i OR (`RewOnKillRepFaction1` IN %in AND `IsTeamAward1` <> 0) ) UNION
SELECT `creature_id`, `RewOnKillRepValue2` as "qty" FROM creature_onkill_reputation WHERE `RewOnKillRepValue2` > 0 AND (`RewOnKillRepFaction2` = %i OR (`RewOnKillRepFaction2` IN %in AND `IsTeamAward2` <> 0) )
SELECT `creature_id`, `RewOnKillRepValue1` as "qty" FROM creature_onkill_reputation WHERE `RewOnKillRepValue1` > 0 AND (`RewOnKillRepFaction1` = ?d { OR (`RewOnKillRepFaction1` IN (?a) AND `IsTeamAward1` <> 0) } ) UNION
SELECT `creature_id`, `RewOnKillRepValue2` as "qty" FROM creature_onkill_reputation WHERE `RewOnKillRepValue2` > 0 AND (`RewOnKillRepFaction2` = ?d { OR (`RewOnKillRepFaction2` IN (?a) AND `IsTeamAward2` <> 0) } )
) x',
$this->typeId, $spillover->getFoundIDs() ?: [0],
$this->typeId, $spillover->getFoundIDs() ?: [0]
$this->typeId, $spillover->getFoundIDs() ?: DBSIMPLE_SKIP,
$this->typeId, $spillover->getFoundIDs() ?: DBSIMPLE_SKIP
);
if ($cRep)
{
$killCreatures = new CreatureList(array(Listview::DEFAULT_SIZE, ['id', array_keys($cRep)]), ['calcTotal' => true]);
$killCreatures = new CreatureList(array(['id', array_keys($cRep)]), ['calcTotal' => true]);
if (!$killCreatures->error)
{
$data = $killCreatures->getListviewData();
@ -259,9 +241,8 @@ class FactionBaseResponse extends TemplateResponse implements ICache
'sort' => ['-reputation', 'name']
);
if ($killCreatures->getMatches() > Listview::DEFAULT_SIZE)
if (!is_null(CreatureListFilter::getCriteriaIndex(42, $this->typeId)))
$tabData['note'] = sprintf(Util::$filterResultString, '?npcs&filter=cr=42;crs='.$this->typeId.';crv=0');
if ($killCreatures->getMatches() > Cfg::get('SQL_LIMIT_DEFAULT'))
$tabData['note'] = sprintf(Util::$filterResultString, '?npcs&filter=cr=42;crs='.$this->typeId.';crv=0');
$this->addDataLoader('zones');
$this->lvTabs->addListviewTab(new Listview($tabData, CreatureList::$brickFile, 'npcRepCol'));
@ -272,7 +253,7 @@ class FactionBaseResponse extends TemplateResponse implements ICache
// tab: members
if ($_ = $this->subject->getField('templateIds'))
{
$members = new CreatureList(array(Listview::DEFAULT_SIZE, ['faction', $_]), ['calcTotal' => true]);
$members = new CreatureList(array(['faction', $_]), ['calcTotal' => true]);
if (!$members->error)
{
$tabData = array(
@ -281,9 +262,8 @@ class FactionBaseResponse extends TemplateResponse implements ICache
'name' => '$LANG.tab_members'
);
if ($members->getMatches() > Listview::DEFAULT_SIZE)
if (!is_null(CreatureListFilter::getCriteriaIndex(3, $this->typeId)))
$tabData['note'] = sprintf(Util::$filterResultString, '?npcs&filter=cr=3;crs='.$this->typeId.';crv=0');
if ($members->getMatches() > Cfg::get('SQL_LIMIT_DEFAULT'))
$tabData['note'] = sprintf(Util::$filterResultString, '?npcs&filter=cr=3;crs='.$this->typeId.';crv=0');
$this->addDataLoader('zones');
$this->lvTabs->addListviewTab(new Listview($tabData, CreatureList::$brickFile));
@ -303,13 +283,12 @@ class FactionBaseResponse extends TemplateResponse implements ICache
// tab: quests
$conditions = array(
DB::OR,
Listview::DEFAULT_SIZE,
[DB::AND, ['rewardFactionId1', $this->typeId], ['rewardFactionValue1', 0, '>']],
[DB::AND, ['rewardFactionId2', $this->typeId], ['rewardFactionValue2', 0, '>']],
[DB::AND, ['rewardFactionId3', $this->typeId], ['rewardFactionValue3', 0, '>']],
[DB::AND, ['rewardFactionId4', $this->typeId], ['rewardFactionValue4', 0, '>']],
[DB::AND, ['rewardFactionId5', $this->typeId], ['rewardFactionValue5', 0, '>']]
['AND', ['rewardFactionId1', $this->typeId], ['rewardFactionValue1', 0, '>']],
['AND', ['rewardFactionId2', $this->typeId], ['rewardFactionValue2', 0, '>']],
['AND', ['rewardFactionId3', $this->typeId], ['rewardFactionValue3', 0, '>']],
['AND', ['rewardFactionId4', $this->typeId], ['rewardFactionValue4', 0, '>']],
['AND', ['rewardFactionId5', $this->typeId], ['rewardFactionValue5', 0, '>']],
'OR'
);
$quests = new QuestList($conditions, ['calcTotal' => true]);
if (!$quests->error)
@ -321,9 +300,8 @@ class FactionBaseResponse extends TemplateResponse implements ICache
'extraCols' => '$_'
);
if ($quests->getMatches() > Listview::DEFAULT_SIZE)
if (!is_null(QuestListFilter::getCriteriaIndex(1, $this->typeId)))
$tabData['note'] = sprintf(Util::$filterResultString, '?quests&filter=cr=1;crs='.$this->typeId.';crv=0');
if ($quests->getMatches() > Cfg::get('SQL_LIMIT_DEFAULT'))
$tabData['note'] = sprintf(Util::$filterResultString, '?quests&filter=cr=1;crs='.$this->typeId.';crv=0');
$this->lvTabs->addListviewTab(new Listview($tabData, QuestList::$brickFile, 'questRepCol'));
}

View file

@ -11,7 +11,7 @@ class FactionsBaseResponse extends TemplateResponse implements ICache
use TrListPage, TrCache;
protected int $type = Type::FACTION;
protected int $cacheType = CACHE_TYPE_LIST_PAGE;
protected int $cacheType = CACHE_TYPE_PAGE;
protected string $template = 'list-page-generic';
protected string $pageName = 'factions';
@ -25,11 +25,11 @@ class FactionsBaseResponse extends TemplateResponse implements ICache
0 => true
);
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
$this->getCategoryFromUrl($rawParam);
$this->getCategoryFromUrl($pageParam);
parent::__construct($rawParam);
parent::__construct($pageParam);
}
protected function generate() : void
@ -71,7 +71,7 @@ class FactionsBaseResponse extends TemplateResponse implements ICache
$this->redButtons[BUTTON_WOWHEAD] = true;
$conditions = [Listview::DEFAULT_SIZE];
$conditions = [];
if (!User::isInGroup(U_GROUP_EMPLOYEE)) // unlisted factions
$conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0];
@ -81,11 +81,11 @@ class FactionsBaseResponse extends TemplateResponse implements ICache
else if (isset($this->category[0]))
{
if ($this->category[0])
$subs = DB::Aowow()->selectCol('SELECT `id` FROM ::factions WHERE `parentFactionId` = %i', $this->category[0]);
$subs = DB::Aowow()->selectCol('SELECT `id` FROM ?_factions WHERE `parentFactionId` = ?d', $this->category[0]);
else
$subs = [0];
$conditions[] = [DB::OR, ['parentFactionId', $subs], ['id', $subs]];
$conditions[] = ['OR', ['parentFactionId', $subs], ['id', $subs]];
}
$data = [];

View file

@ -13,11 +13,11 @@ class FaqBaseResponse extends TemplateResponse
protected ?int $activeTab = parent::TAB_MORE;
protected array $breadcrumb = [2, 3];
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
parent::__construct($rawParam);
parent::__construct($pageParam);
if ($rawParam)
if ($pageParam)
$this->generateError();
}

View file

@ -12,35 +12,21 @@ class FilterBaseResponse extends TextResponse
private string $page = '';
private ?Filter $filter = null;
public function __construct(string $rawParam)
public function __construct(string $pageParam)
{
if (!$rawParam)
if (!$pageParam)
return;
parent::__construct($rawParam);
parent::__construct($pageParam);
$catg = $page = null;
if (strstr($rawParam, '='))
[$page, $catg] = explode('=', $rawParam);
$catg = null;
if (strstr($pageParam, '='))
[$this->page, $catg] = explode('=', $pageParam);
else
$page = $rawParam;
if (!$page || preg_match('/[^a-z\-]/i', $page))
return;
$this->page = strtolower($page);
$this->page = $pageParam;
if ($catg !== null)
{
// category is a string for profiler (region.realm) but not passed through here
foreach (explode('.', $catg) as $c)
{
if (preg_match('/\D/', $c))
break;
$this->catg[] = intval($c);
}
}
$this->catg = explode('.', $catg);
$opts = ['parentCats' => $this->catg];
@ -52,22 +38,14 @@ class FilterBaseResponse extends TextResponse
};
// yes, the whole _POST! .. should the input fields be exposed and static so they can be evaluated via BaseResponse::initRequestData() ?
if (!$this->filter = Type::newFilter($fileStr, $_POST, $opts))
trigger_error('Filter::__construct - tried to init filter from bogus GET data', E_USER_WARNING);
$this->filter = Type::newFilter($fileStr, $_POST, $opts);
}
protected function generate() : void
{
// could not build filter from $this->page > go to front page
if (!$this->filter)
{
$this->redirectTo = '.';
return;
}
$url = '?'.$this->page;
$this->filter->mergeCat($this->catg);
$this->filter?->mergeCat($this->catg);
if ($this->catg)
$url .= '='.implode('.', $this->catg);
@ -75,7 +53,7 @@ class FilterBaseResponse extends TextResponse
if ($x = $this->filter?->buildGETParam())
$url .= '&filter='.$x;
if ($this->filter->error)
if ($this->filter?->error)
$_SESSION['error']['fi'] = $this->filter::class;
// do get request

View file

@ -21,9 +21,8 @@ class GotocommentBaseResponse extends TextResponse
return;
}
// the reputation-history listview only creates go-to-comment links. So either upvoting replies does not grant reputation, or.... bug.?
$comment = DB::Aowow()->selectRow('SELECT IFNULL(c2.`id`, c1.`id`) AS "id", IFNULL(c2.`type`, c1.`type`) AS "type", IFNULL(c2.`typeId`, c1.`typeId`) AS "typeId" FROM ::comments c1 LEFT JOIN ::comments c2 ON c1.`replyTo` = c2.`id` WHERE c1.`id` = %i', $this->_get['id']);
// type <> 0 AND typeId <> 0 AND replyTo = 0 for comments
$comment = DB::Aowow()->selectRow('SELECT `id`, `type`, `typeId` FROM ?_comments WHERE `replyTo` = 0 AND `id` = ?d', $this->_get['id']);
if (!$comment)
{
trigger_error('GotocommentBaseResponse - comment #'.$this->_get['id'].' not found', E_USER_ERROR);
@ -37,8 +36,6 @@ class GotocommentBaseResponse extends TextResponse
}
$this->redirectTo = sprintf('?%s=%d#comments:id=%d', Type::getFileString($comment['type']), $comment['typeId'], $comment['id']);
if ($comment['id'] != $this->_get['id']) // i am reply
$this->redirectTo .= ':reply='.$this->_get['id'];
}
}

View file

@ -22,7 +22,7 @@ class GotoreplyBaseResponse extends TextResponse
}
// type = typeId = 0 AND replyTo <> 0 for replies
$reply = DB::Aowow()->selectRow('SELECT c.`id`, r.`id` AS "reply", c.`type`, c.`typeId` FROM ::comments r JOIN ::comments c ON r.`replyTo` = c.`id` WHERE r.`id` = %i', $this->_get['id']);
$reply = DB::Aowow()->selectRow('SELECT c.`id`, r.`id` AS "reply", c.`type`, c.`typeId` FROM ?_comments r JOIN ?_comments c ON r.`replyTo` = c.`id` WHERE r.`id` = ?d', $this->_get['id']);
if (!$reply)
{
trigger_error('GotoreplyBaseResponse - reply #'.$this->_get['id'].' not found', E_USER_ERROR);

Some files were not shown because too many files have changed in this diff Show more