/* ---------- Tags and trending (shared by the site and the admin) ---------- */ if (!defined('CONTENT_STOPWORDS')) { define('CONTENT_STOPWORDS', [ 'about','above','after','again','against','also','another','around','because','been','before','being', 'below','between','both','could','does','doing','down','during','each','even','ever','every','from', 'have','here','hers','herself','into','itself','just','like','made','make','many','more','most','much', 'must','never','only','other','ours','over','same','should','since','some','such','take','than','that', 'their','theirs','them','then','there','these','they','this','those','through','under','until','upon', 'very','were','what','when','where','which','while','will','with','within','would','your','yours','work', 'works','year','years','still','about','page','click','read','more','view','show','shows','first','last', ]); } /** Split a comma list of tags: trimmed, no '#', no empties, no case-insensitive duplicates. */ function content_tag_list(string $raw): array { $out = []; $seen = []; foreach (explode(',', $raw) as $t) { $t = trim(ltrim(trim($t), '#')); if ($t === '') { continue; } $k = mb_strtolower($t); if (isset($seen[$k])) { continue; } $seen[$k] = true; $out[] = $t; } return $out; } /** Words that best describe a post: title counts 3x, subtitle 2x, body 1x. */ function content_detect_tags(string $title, string $subtitle, string $html, int $want): array { $counts = []; $add = function (string $text, int $weight) use (&$counts): void { preg_match_all('/\p{L}{4,}/u', $text, $m); foreach ($m[0] as $word) { if (in_array($word, CONTENT_STOPWORDS, true)) { continue; } $counts[$word] = ($counts[$word] ?? 0) + $weight; } }; $add(mb_strtolower($title), 3); $add(mb_strtolower($subtitle), 2); $add(mb_strtolower(strip_tags($html)), 1); arsort($counts); $out = []; foreach (array_keys($counts) as $word) { $out[] = mb_convert_case($word, MB_CASE_TITLE, 'UTF-8'); if (count($out) >= $want) { break; } } return $out; } /** * Final tag string for a post: the tags the editor typed come first (max 3). * If fewer than 2 were typed, detected words fill up to 3 total. Returns "a, b, c" or ''. */ function content_tags_build(array $manual, string $title, string $subtitle, string $html): string { $tags = array_slice(content_tag_list(implode(',', $manual)), 0, 3); if (count($tags) < 2) { $have = array_map('mb_strtolower', $tags); foreach (content_detect_tags($title, $subtitle, $html, 6) as $cand) { if (count($tags) >= 3) { break; } if (!in_array(mb_strtolower($cand), $have, true)) { $tags[] = $cand; $have[] = mb_strtolower($cand); } } } return implode(', ', $tags); } /** Trending: views and likes, with a time decay so new posts can rise. Works on a content row. */ function content_trend_score(array $r): float { $views = (float)($r['views'] ?? 0); $likes = (float)($r['like'] ?? 0); $ts = strtotime((string)($r['date'] ?? '')) ?: time(); $days = max(0.0, (time() - $ts) / 86400); return ($views + 3 * $likes + 1) / pow($days + 2, 1.5); } Create account WEAREICERS

Welcome back

Sign in to continue

Continue with Google Continue with Discord Continue with Facebook
OR
Phone numbers: include the country code, e.g. +1 555 123 4567.
Include the country code. You can use it to sign in later.
You must be 18 or older to create an account. We only use this to check your age and don't store it.
At least 6 characters.

Don't have an account? Sign up Already have an account? Sign in