->join('log l',"l.reftype = 'un-banish' AND l.refid = b.entryid") ->get('log__un-banish b',null,"b.reason, l.initiator, l.timestamp, 1 as action"); if (!empty($Unbanishes)){ $Banishes = array_merge($Banishes,$Unbanishes); usort($Banishes, function($a, $b){ $a = strtotime($a['timestamp']); $b = strtotime($b['timestamp']); return $a > $b ? -1 : ($a < $b ? 1 : 0); }); unset($Unbanishes); } $displayInitiator = Permission::sufficient('staff'); foreach ($Banishes as $b){ $initiator = $displayInitiator ? Users::get($b['initiator']) : null; $b['reason'] = htmlspecialchars($b['reason']); echo "<li class=".strtolower($Actions[$b['action']])."><blockquote>{$b['reason']}</blockquote> - ".(isset($initiator)?$initiator->getProfileLink().' ':'').Time::tag($b['timestamp'])."</li>"; } } ?></ul> </section> </div> <div id="settings"><?php if ($sameUser || Permission::sufficient('staff')){ ?> <section class="guide-settings"> <h2><?=$sameUser? Users::PROFILE_SECTION_PRIVACY_LEVEL['staff']:''?>Color Guide</h2> <form action="/preference/set/cg_itemsperpage"> <label> <span>Appearances per page</span> <input type="number" min="7" max="20" name="value" value="<?=UserPrefs::get('cg_itemsperpage', $User->id)?>" step="1"<?=!$sameUser?' disabled':''?>>
static function getOverdueSubmissionList() { global $Database; $Query = $Database->rawQuery("SELECT reserved_by, COUNT(*) as cnt FROM (\n\t\t\t\tSELECT reserved_by FROM reservations\n\t\t\t\tWHERE deviation_id IS NOT NULL AND lock = false\n\t\t\t\tUNION ALL\n\t\t\t\tSELECT reserved_by FROM requests\n\t\t\t\tWHERE deviation_id IS NOT NULL AND lock = false\n\t\t\t) t\n\t\t\tGROUP BY reserved_by\n\t\t\tHAVING COUNT(*) >= 5\n\t\t\tORDER BY cnt DESC;"); if (empty($Query)) { return; } $HTML = "<table>"; foreach ($Query as $row) { $link = Users::get($row['reserved_by'])->getProfileLink(User::LINKFORMAT_FULL); $count = "<strong style='color:rgb(" . min(round($row['cnt'] / 10 * 255), 255) . ",0,0)'>{$row['cnt']}</strong>"; $HTML .= "<tr><td>{$link}</td><td>{$count}</td></tr>"; } return "{$HTML}</table>"; }
<?php use App\CoreUtils; use App\Models\User; use App\Users; /** @var $title string */ ?> <div id="content"> <h1><?php echo $title; ?> </h1> <p>Originally made by <?php echo Users::get('dasprid', 'name', 'name, avatar_url')->getProfileLink(User::LINKFORMAT_FULL); ?> </p> <?php echo CoreUtils::notice('info', "<p><span class='typcn typcn-info-large'></span> This is a tool which helps you to find an original {$color}, given two different background {$color}s and the resulting blended {$color}, when the original {$color} is blended over it.</p><p><strong>Shift+Click</strong> an input to open a dialog where you can enter RGB values</p><a class='btn typcn typcn-arrow-back' href='/cg'>Back to {$Color} Guide</a>", true); ?> <div id="blend-wrap"> <form autocomplete="off"> <table> <thead> <tr> <th>Background</th> <th>Blended <?php echo $color; ?> </th> </tr>
Response::done(array('preview' => $Image->preview, 'title' => $Image->title)); } $insert = array('preview' => $Image->preview, 'fullsize' => $Image->fullsize); $season = Episodes::validateSeason(Episodes::ALLOW_MOVIES); $episode = Episodes::validateEpisode(); $epdata = Episodes::getActual($season, $episode, Episodes::ALLOW_MOVIES); if (empty($epdata)) { Response::fail("The specified episode (S{$season}E{$episode}) does not exist"); } $insert['season'] = $epdata->season; $insert['episode'] = $epdata->episode; $ByID = $currentUser->id; if (Permission::sufficient('developer')) { $username = Posts::validatePostAs(); if (isset($username)) { $PostAs = Users::get($username, 'name', 'id,role'); if (empty($PostAs)) { Response::fail('The user you wanted to post as does not exist'); } if ($type === 'reservation' && !Permission::sufficient('member', $PostAs->role) && !isset($_POST['allow_nonmember'])) { Response::fail('The user you wanted to post as is not a club member, do you want to post as them anyway?', array('canforce' => true)); } $ByID = $PostAs->id; } } $insert[$type === 'reservation' ? 'reserved_by' : 'requested_by'] = $ByID; Posts::checkPostDetails($type, $insert); $PostID = $Database->insert("{$type}s", $insert, 'id'); if (!$PostID) { Response::dbError(); }
/** * Render log page <tbody> content * * @param $LogItems * * @return string */ static function getTbody($LogItems) { global $Database; $HTML = ''; if (count($LogItems) > 0) { foreach ($LogItems as $item) { if (!empty($item['initiator'])) { $inituser = Users::get($item['initiator'], 'id'); if (empty($inituser)) { $inituser = '******'; } else { $inituser = $inituser->getProfileLink(); } $ip = in_array($item['ip'], array('::1', '127.0.0.1')) ? "localhost" : $item['ip']; if ($item['ip'] === $_SERVER['REMOTE_ADDR']) { $ip .= ' <span class="self">(from your IP)</span>'; } } else { $inituser = null; $ip = '<a class="server-init" title="Search for all entries by Web server"><span class="typcn typcn-zoom"></span> Web server</a>'; } $event = Logs::$LOG_DESCRIPTION[$item['reftype']] ?? $item['reftype']; if (isset($item['refid'])) { $event = '<span class="expand-section typcn typcn-plus">' . $event . '</span>'; } $ts = Time::tag($item['timestamp'], Time::TAG_EXTENDED); if (!empty($inituser)) { $ip = "{$inituser}<br>{$ip}"; } $HTML .= <<<HTML \t\t<tr> \t\t\t<td class='entryid'>{$item['entryid']}</td> \t\t\t<td class='timestamp'>{$ts}</td> \t\t\t<td class='ip'>{$ip}</td> \t\t\t<td class='reftype'>{$event}</td> \t\t</tr> HTML; } } else { $HTML = '<tr><td colspan="4"><div class="notice info align-center"><label>No log items found</label></td></tr>'; } return $HTML; }
<? if (isset($browser['browser_name'])){ ?> <div class="browser-<?php echo CoreUtils::browserNameToClass($browser['browser_name']); ?> "></div> <? } ?> <h1><?php echo rtrim(($browser['browser_name'] ?? 'Unknown browser') . ' ' . ($browser['browser_ver'] ?? '')); ?> </h1> <p><?php echo !empty($browser['platform']) ? "on {$browser['platform']}" : 'Unknown platform'; ?> </p> <?php echo !empty($Session) ? CoreUtils::notice('warn', "You're debugging session #{$Session['id']} (belongs to " . Users::get($Session['user'])->getProfileLink() . ")") : ''; ?> <?php echo CoreUtils::notice('info', 'Browser recognition testing page', "The following page is used to make sure that the site's browser detection script works as it should. If you're seeing a browser and/or operating system that's different from what you're currently using, please <a class='send-feedback'>let us know.</a>"); ?> <section> <h2>Your User Agent string</h2> <p><code><?php echo !empty($browser['user_agent']) ? CoreUtils::escapeHTML($browser['user_agent']) : '<empty>'; ?> </code></p> </section> </div>
<p id="notes"><?=Appearances::getNotesHTML($Appearance, NOWRAP, NOTE_TEXT_ONLY)?></p> </section> <? } if (!empty($Appearance['cm_favme'])){ $preview = Appearances::getCMPreviewURL($Appearance); ?> <section class="approved-cutie-mark"> <h2>Recommended cutie mark vector</h2> <?=Permission::sufficient('staff')&&!isset($Appearance['cm_dir'])?CoreUtils::notice('fail','Missing CM orientation, falling back to <strong>Tail-Head</strong>. Please edit the appaearance and provide an orientation!'):''?> <a id="pony-cm" href="http://fav.me/<?=$Appearance['cm_favme']?>" style="background-image:url('<?=Appearances::getCMPreviewSVGURL($Appearance['id'])?>')"> <div class="img cm-dir-<?=$Appearance['cm_dir']===CM_DIR_HEAD_TO_TAIL?'ht':'th'?>" style="background-image:url('<?=CoreUtils::aposEncode($preview)?>')"></div> </a> <p class="aside">This is only an illustration, the body shape & colors are <strong>not</strong> guaranteed to reflect the actual design.</p> <p>The image above links to the vector made by <?php $Vector = DeviantArt::getCachedSubmission($Appearance['cm_favme']); echo Users::get($Vector['author'],'name','name, avatar_url')->getProfileLink(User::LINKFORMAT_FULL); ?> and shows which way the cutie mark should be facing.</p> </section> <? } ?> <section class="color-list"> <h2 class="admin">Color groups</h2> <div class="admin"> <button class="darkblue typcn typcn-arrow-unsorted reorder-cgs">Re-order groups</button> <button class="green typcn typcn-plus create-cg">Create group</button> </div> <? if ($placehold = Appearances::getPendingPlaceholderFor($Appearance)) echo $placehold; else { ?> <ul id="colors" class="colors"><?php $CGs = ColorGroups::get($Appearance['id']); $AllColors = ColorGroups::getColorsForEach($CGs);
/** * Check authentication cookie and set global */ static function authenticate() { global $Database, $signedIn, $currentUser, $Color, $color; CSRFProtection::detect(); if (!POST_REQUEST && isset($_GET['CSRF_TOKEN'])) { HTTP::redirect(CSRFProtection::removeParamFromURL($_SERVER['REQUEST_URI'])); } if (!Cookie::exists('access')) { return; } $authKey = Cookie::get('access'); if (!empty($authKey)) { if (!preg_match(new RegExp('^[a-f\\d]+$', 'iu'), $authKey)) { $oldAuthKey = $authKey; $authKey = bin2hex($authKey); $Database->where('token', sha1($oldAuthKey))->update('sessions', array('token' => sha1($authKey))); Cookie::set('access', $authKey, time() + Time::$IN_SECONDS['year'], Cookie::HTTPONLY); } $currentUser = Users::get(sha1($authKey), 'token'); } if (!empty($currentUser)) { if ($currentUser->role === 'ban') { $Database->where('id', $currentUser->id)->delete('sessions'); } else { if (strtotime($currentUser->Session['expires']) < time()) { $tokenvalid = false; try { DeviantArt::getToken($currentUser->Session['refresh'], 'refresh_token'); $tokenvalid = true; } catch (CURLRequestException $e) { $Database->where('id', $currentUser->Session['id'])->delete('sessions'); trigger_error("Session refresh failed for {$currentUser->name} ({$currentUser->id}) | {$e->getMessage()} (HTTP {$e->getCode()})", E_USER_WARNING); } } else { $tokenvalid = true; } if ($tokenvalid) { $signedIn = true; if (time() - strtotime($currentUser->Session['lastvisit']) > Time::$IN_SECONDS['minute']) { $lastVisitTS = date('c'); if ($Database->where('id', $currentUser->Session['id'])->update('sessions', array('lastvisit' => $lastVisitTS))) { $currentUser->Session['lastvisit'] = $lastVisitTS; } } $_PrefersColour = array('Pirill-Poveniy' => true, 'itv-canterlot' => true); if (isset($_PrefersColour[$currentUser->name])) { $Color = 'Colour'; $color = 'colour'; } } } } else { Cookie::delete('access', Cookie::HTTPONLY); } }
$by = null; } else { switch (strtolower(CoreUtils::trim($_GET['by']))) { case 'me': case 'you': $initiator = $currentUser->id; $by = 'you'; break; case 'web server': $initiator = 0; $by = 'Web server'; break; default: $by = Users::validateName('by', null, true); if (isset($by)) { $by = Users::get($by, 'name', 'id,name'); $initiator = $by->id; $by = $initiator === $currentUser->id ? 'me' : $by->name; } } } $title = ''; function process_filter(&$q = null) { global $Database, $type, $by, $initiator, $title; if (isset($type)) { $Database->where('reftype', $type); if (isset($q)) { $q[] = "type={$type}"; $title .= Logs::$LOG_DESCRIPTION[$type] . ' entries '; }
if ($signedIn) { $un = $currentUser->name; } else { $MSG = 'Sign in to view your settings'; } } else { if (preg_match($USERNAME_REGEX, $data, $_match)) { $un = $_match[1]; } } if (!isset($un)) { if (!isset($MSG)) { $MSG = 'Invalid username'; } } else { $User = Users::get($un, 'name'); } if (empty($User)) { if (isset($User) && $User === false) { $MSG = "User does not exist"; $SubMSG = "Check the name for typos and try again"; } if (!isset($MSG)) { $MSG = 'Local user data missing'; if (!$signedIn) { $exists = 'exists on DeviantArt'; if (isset($un)) { $exists = "<a href='http://{$un}.deviantart.com/'>{$exists}</a>"; } $SubMSG = "If this user {$exists}, sign in to import their details."; }
break; case "s": if (!empty($LinkedPost)) { if (!$LinkedPost->isFinished) { $ThumbImage = $LinkedPost->preview; } else { $finishdeviation = DeviantArt::getCachedSubmission($LinkedPost->deviation_id); if (!empty($finishdeviation['preview'])) { $ThumbImage = $finishdeviation['preview']; } } $Title = $LinkedPost->label; if ($LinkedPost->isRequest) { $Description = 'A request'; } else { $_user = Users::get($LinkedPost->reserved_by, 'id', 'name'); $Description = 'A reservation' . (!empty($_user->name) ? " by {$_user->name}" : ''); } $Description .= ' on the MLP-VectorClub\'s website'; } break; } if ($ThumbImage[0] === '/') { $ThumbImage = ABSPATH . ltrim($ThumbImage, '/'); } $Title = CoreUtils::escapeHTML($Title); ?> <!DOCTYPE html> <html lang="en"> <head> <title><?php
static function getHTML($Notifications, $wrap = true) { global $Database; $HTML = $wrap ? '<ul class="notif-list">' : ''; foreach ($Notifications as $n) { $data = !empty($n['data']) ? JSON::decode($n['data']) : null; if (preg_match(new RegExp('^post-'), $n['type'])) { /** @var $Post Post */ $Post = $Database->where('id', $data['id'])->getOne("{$data['type']}s"); $Episode = Episodes::getActual($Post->season, $Post->episode, Episodes::ALLOW_MOVIES); $EpID = $Episode->formatTitle(AS_ARRAY, 'id'); $url = $Post->toLink($Episode); } switch ($n['type']) { case "post-finished": $HTML .= self::_getNotifElem("Your <a href='{$url}'>request</a> under {$EpID} has been fulfilled", $n); break; case "post-approved": $HTML .= self::_getNotifElem("A <a href='{$url}'>post</a> you reserved under {$EpID} has been added to the club gallery", $n); break; case "post-passon": $userlink = Users::get($data['user'])->getProfileLink(); $HTML .= self::_getNotifElem("{$userlink} is interested in finishing a <a href='{$url}'>post</a> you reserved under {$EpID}. Would you like to pass the reservation to them?", $n); break; case "post-passdeny": case "post-passallow": case "post-passfree": case "post-passdel": case "post-passsnatch": case "post-passperm": $userlink = Users::get($data['by'])->getProfileLink(); $passaction = str_replace('post-pass', '', $n['type']); switch ($passaction) { case "allow": $HTML .= self::_getNotifElem("Reservation transfer status: {$userlink} <strong class='color-lightgreen'>transferred</strong> the reservation of <a href='{$url}'>this post</a> under {$EpID} to you!", $n); break; case "deny": $HTML .= self::_getNotifElem("Reservation transfer status: {$userlink} <strong class='color-lightred'>denied</strong> transferring the reservation of <a href='{$url}'>this post</a> under {$EpID} to you.", $n); break; case 'free': case 'del': case 'snatch': case 'perm': $message = Posts::TRANSFER_ATTEMPT_CLEAR_REASONS[$passaction]; $message = str_replace('post', "<a href='{$url}'>post</a>", $message); switch ($passaction) { case 'del': $message .= " by {$userlink}"; break; case "perm": $message = str_replace('the previous reserver', $userlink, $message); break; } $HTML .= self::_getNotifElem("Reservation transfer status: {$message}", $n); break; } break; default: $HTML .= "<li><code>Notification({$n['type']})#{$n['id']}</code> <span class='nobr'>– Missing handler</span></li>"; } } return $HTML . ($wrap ? '</ul>' : ''); }
/** * List ltem generator function for request & reservation generators * * @param Post $Post * @param bool $view_only Only show the "View" button * @param bool $cachebust_url Append a random string to the image URL to force a re-fetch * * @return string */ static function getLi(Post $Post, bool $view_only = false, bool $cachebust_url = false) : string { $finished = !empty($Post->deviation_id); $isRequest = $Post->isRequest; $type = $isRequest ? 'request' : 'reservation'; $ID = "{$type}-{$Post->id}"; $alt = !empty($Post->label) ? CoreUtils::aposEncode($Post->label) : ''; $postlink = (new Episode($Post))->formatURL() . "#{$ID}"; $ImageLink = $view_only ? $postlink : $Post->fullsize; $cachebust = $cachebust_url ? '?t=' . time() : ''; $Image = "<div class='image screencap'><a href='{$ImageLink}'><img src='{$Post->preview}{$cachebust}' alt='{$alt}'></a></div>"; $post_label = self::_getPostLabel($Post); $permalink = "<a href='{$postlink}'>" . Time::tag($Post->posted) . '</a>'; $posted_at = '<em class="post-date">'; if ($isRequest) { global $signedIn, $currentUser; $isRequester = $signedIn && $Post->requested_by === $currentUser->id; $isReserver = $signedIn && $Post->reserved_by === $currentUser->id; $overdue = Permission::sufficient('member') && $Post->isOverdue(); $posted_at .= "Requested {$permalink}"; if ($signedIn && (Permission::sufficient('staff') || $isRequester || $isReserver)) { $posted_at .= ' by ' . ($isRequester ? "<a href='/@{$currentUser->name}'>You</a>" : Users::get($Post->requested_by)->getProfileLink()); } } else { $overdue = false; $posted_at .= "Reserved {$permalink}"; } $posted_at .= "</em>"; $hide_reserved_status = !isset($Post->reserved_by) || $overdue && !$isReserver; if (!empty($Post->reserved_by)) { $Post->Reserver = Users::get($Post->reserved_by); $reserved_by = $overdue && !$isReserver ? ' by ' . $Post->Reserver->getProfileLink() : ''; $reserved_at = $isRequest && !empty($Post->reserved_at) && !($hide_reserved_status && Permission::insufficient('staff')) ? "<em class='reserve-date'>Reserved <strong>" . Time::tag($Post->reserved_at) . "</strong>{$reserved_by}</em>" : ''; if ($finished) { $approved = !empty($Post->lock); $Deviation = DeviantArt::getCachedSubmission($Post->deviation_id, 'fav.me', true); if (empty($Deviation)) { $ImageLink = $view_only ? $postlink : "http://fav.me/{$Post->deviation_id}"; $Image = "<div class='image deviation error'><a href='{$ImageLink}'>Preview unavailable<br><small>Click to view</small></a></div>"; } else { $alt = CoreUtils::aposEncode($Deviation['title']); $ImageLink = $view_only ? $postlink : "http://fav.me/{$Deviation['id']}"; $Image = "<div class='image deviation'><a href='{$ImageLink}'><img src='{$Deviation['preview']}{$cachebust}' alt='{$alt}'>"; if ($approved) { $Image .= "<span class='typcn typcn-tick' title='This submission has been accepted into the group gallery'></span>"; } $Image .= "</a></div>"; } if (Permission::sufficient('staff')) { $finished_at = !empty($Post->finished_at) ? "<em class='finish-date'>Finished <strong>" . Time::tag($Post->finished_at) . "</strong></em>" : ''; $locked_at = ''; if ($approved) { global $Database; $LogEntry = $Database->rawQuerySingle("SELECT l.timestamp\n\t\t\t\t\t\t\tFROM log__post_lock pl\n\t\t\t\t\t\t\tLEFT JOIN log l ON l.reftype = 'post_lock' && l.refid = pl.entryid\n\t\t\t\t\t\t\tWHERE type = ? && id = ?\n\t\t\t\t\t\t\tORDER BY pl.entryid ASC\n\t\t\t\t\t\t\tLIMIT 1", array($type, $Post->id)); $locked_at = $approved ? "<em class='approve-date'>Approved <strong>" . Time::tag(strtotime($LogEntry['timestamp'])) . "</strong></em>" : ''; } $Image .= $post_label . $posted_at . $reserved_at . $finished_at . $locked_at; if (!empty($Post->fullsize)) { $Image .= "<a href='{$Post->fullsize}' class='original color-green' target='_blank'><span class='typcn typcn-link'></span> Original image</a>"; } } } else { $Image .= $post_label . $posted_at . $reserved_at; } } else { $Image .= $post_label . $posted_at; } if ($overdue && (Permission::sufficient('staff') || $isReserver)) { $Image .= self::CONTESTABLE; } if ($hide_reserved_status) { $Post->Reserver = false; } return "<li id='{$ID}'>{$Image}" . self::_getPostActions($Post, $isRequest, $view_only ? $postlink : false) . '</li>'; }
</div> <div class="main"> <div> <h1><?php echo CoreUtils::escapeHTML($heading); ?> </h1> <p>Vector Requests & Reservations</p> <?php if (Permission::sufficient('staff')) { ?> <p class="addedby"><em><?php echo $CurrentEpisode->isMovie ? 'Movie' : 'Episode'; ?> added by <?php echo Users::get($CurrentEpisode->posted_by)->getProfileLink() . ' ' . Time::tag($CurrentEpisode->posted); ?> </em></p> <?php } ?> </div> </div> <div class="next-ep"><?php if (!empty($NextEpisode)) { $NextEpisodeTitle = $NextEpisode->formatTitle(AS_ARRAY, null, false); ?> <div> <a href="<?php echo $NextEpisode->formatURL(); ?>