You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
186 lines
4.3 KiB
PHP
186 lines
4.3 KiB
PHP
<?php
|
|
require_once 'utils/utils.php';
|
|
|
|
class TagType {
|
|
private function __construct() {}
|
|
const USER_TAG = 0;
|
|
const RESERVED_TAG = 1;
|
|
const WARNING_TAG = 2;
|
|
}
|
|
|
|
class CommunityTag implements JsonSerializable {
|
|
public function __construct(
|
|
string $text,
|
|
int $tag_type = TagType::USER_TAG,
|
|
string $description = ""
|
|
) {
|
|
$this->text = $text;
|
|
$this->type = $tag_type;
|
|
$this->description =
|
|
empty($description) ? "Tag: $text" : $description;
|
|
}
|
|
|
|
public readonly int $type;
|
|
|
|
public readonly string $text;
|
|
|
|
public readonly string $description;
|
|
|
|
/**
|
|
* Returns a lowercase representation of the tag for purposes of de-duping.
|
|
*/
|
|
public function __toString(): string {
|
|
return strtolower($this->text);
|
|
}
|
|
|
|
/**
|
|
* Returns a lowercase representation of the tag for use in display.
|
|
*/
|
|
public function get_text(): string {
|
|
return strtolower($this->text);
|
|
}
|
|
|
|
public function jsonSerialize(): mixed {
|
|
// Only used for passing to DOM
|
|
$details = get_object_vars($this);
|
|
$details['text'] = html_sanitize($this->get_text());
|
|
$details['description'] = html_sanitize($details['description']);
|
|
$details['type'] = $this->get_tag_type();
|
|
return $details;
|
|
}
|
|
|
|
private static function preprocess_tag(?string $tag) {
|
|
$tag = trim($tag);
|
|
|
|
if (strlen($tag) == 0) {
|
|
return $tag;
|
|
}
|
|
|
|
$tag = html_sanitize(html_entity_decode($tag));
|
|
|
|
if ($tag[0] == '#') {
|
|
return substr($tag, 1);
|
|
}
|
|
|
|
return $tag;
|
|
}
|
|
|
|
/**
|
|
* @param string[] $tag_array
|
|
* @return \CommunityTag[]
|
|
*/
|
|
private static function from_tag_array(array $tag_array) {
|
|
$tags = array_map(function(?string $tag) {
|
|
return CommunityTag::preprocess_tag($tag);
|
|
}, $tag_array);
|
|
|
|
$tags = array_filter(
|
|
$tags, function(?string $tag) {
|
|
return strlen($tag) != 0;
|
|
}
|
|
);
|
|
|
|
return array_map(function(string $tag) {
|
|
return new CommunityTag($tag);
|
|
}, $tags);
|
|
}
|
|
|
|
/**
|
|
* Returns the user tags given, without any reserved tags.
|
|
* @param string[] $tags
|
|
* @param bool $remove_redundant Removes duplicate and obvious tags.
|
|
* @return \CommunityTag[]
|
|
*/
|
|
public static function from_user_tags(
|
|
array $tags, bool $remove_redundant = false
|
|
): array {
|
|
$tags_user = array_filter(
|
|
$tags,
|
|
function($tag) {
|
|
return !CommunityTag::is_reserved_tag($tag);
|
|
}
|
|
);
|
|
|
|
$tags_built = CommunityTag::from_tag_array($tags_user);
|
|
|
|
if ($remove_redundant) {
|
|
$tags_built = CommunityTag::dedupe_tags($tags_built);
|
|
$tags_built = array_filter($tags_built, function(\CommunityTag $tag) {
|
|
$text = strtolower($tag->text);
|
|
return !in_array($text, CommunityTag::REDUNDANT_TAGS);
|
|
});
|
|
}
|
|
|
|
return $tags_built;
|
|
}
|
|
|
|
/**
|
|
* @param string[] $details_array Array of string tags.
|
|
* @return \CommunityTag[]
|
|
*/
|
|
public static function from_details_array(array $details_array): array {
|
|
return CommunityTag::from_user_tags($details_array);
|
|
}
|
|
|
|
/**
|
|
* @param \CommunityTag[] $tags
|
|
* @return \CommunityTag[]
|
|
*/
|
|
public static function dedupe_tags(array $tags) {
|
|
return array_unique($tags);
|
|
}
|
|
|
|
public function get_tag_classname(): string {
|
|
$tag_type = $this->get_tag_type();
|
|
$classname = "room-label-$tag_type";
|
|
if (CommunityTag::is_showcased_tag($this->text)) {
|
|
$classname .= " room-label-showcased";
|
|
}
|
|
return $classname;
|
|
}
|
|
|
|
public function get_tag_type(): string {
|
|
return match($this->type) {
|
|
TagType::USER_TAG => 'user',
|
|
TagType::RESERVED_TAG => 'reserved',
|
|
TagType::WARNING_TAG => 'warning'
|
|
};
|
|
}
|
|
/**
|
|
* @var string[] RESERVED_TAGS
|
|
* Array of derived tags unavailable for manual tagging.
|
|
*/
|
|
private const RESERVED_TAGS = [
|
|
"official",
|
|
"nsfw",
|
|
"new",
|
|
"modded",
|
|
"not modded",
|
|
"read-only",
|
|
"uploads off",
|
|
"we're here"
|
|
];
|
|
|
|
private const SHOWCASED_TAGS = ["official", "new", "we're here"];
|
|
|
|
private const REDUNDANT_TAGS = ["session"];
|
|
|
|
public const NSFW_KEYWORDS = ["nsfw", "porn", "erotic", "18+"];
|
|
|
|
public const CHECK_MARK = "✅";
|
|
|
|
public const WARNING_ICON = "⚠️";
|
|
|
|
/**
|
|
* Checks whether the given manual tag can be accepted.
|
|
*/
|
|
public static function is_reserved_tag(string $tag): bool {
|
|
return in_array(strtolower($tag), CommunityTag::RESERVED_TAGS);
|
|
}
|
|
|
|
public static function is_showcased_tag(string $tag): bool {
|
|
return in_array(strtolower($tag), CommunityTag::SHOWCASED_TAGS);
|
|
}
|
|
}
|
|
?>
|