function testTag() { $now = strtotime('2016-12-03T12:03:56Z'); $result = Time::tag($now, false, Time::TAG_ALLOW_DYNTIME, $now); self::assertEquals("<time datetime='2016-12-03T12:03:56Z' title='3rd Dec 2016, 12:03:56 pm GMT'>a few seconds ago</time>", $result); $result = Time::tag($now, Time::TAG_EXTENDED, Time::TAG_ALLOW_DYNTIME, $now); self::assertEquals("<time datetime='2016-12-03T12:03:56Z'>3rd Dec 2016, 12:03:56 pm GMT</time><span class='dynt-el'>a few seconds ago</span>", $result); $result = Time::tag($now, Time::TAG_EXTENDED, Time::TAG_NO_DYNTIME, $now); self::assertEquals("<time datetime='2016-12-03T12:03:56Z' class='nodt'>3rd Dec 2016, 12:03:56 pm GMT</time>", $result); $result = Time::tag($now, Time::TAG_EXTENDED, Time::TAG_STATIC_DYNTIME, $now); self::assertEquals("<time datetime='2016-12-03T12:03:56Z' class='no-dynt-el'>3rd Dec 2016, 12:03:56 pm GMT</time>", $result); }
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':''?>> <?php if ($sameUser){ ?> <button class="save typcn typcn-tick green" disabled>Save</button>
/** * Returns the HTML of the GIT informaiiton in the website's footer * * @param bool $appendSeparator * * @return string */ static function getFooterGitInfo(bool $appendSeparator = true) : string { $commit_info = "Running <strong><a href='" . GITHUB_URL . "' title='Visit the GitHub repository'>MLPVC-RR</a>"; $commit_id = rtrim(shell_exec('git rev-parse --short=4 HEAD')); if (!empty($commit_id)) { $commit_time = Time::tag(date('c', strtotime(shell_exec('git log -1 --date=short --pretty=format:%ci')))); $commit_info .= "@<a href='" . GITHUB_URL . "/commit/{$commit_id}' title='See exactly what was changed and why'>{$commit_id}</a></strong> created {$commit_time}"; } else { $commit_info .= "</strong> (version information unavailable)"; } if ($appendSeparator) { $commit_info .= ' | '; } return $commit_info; }
/** * 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 ($reserved_by === $currentUser->id) { Response::fail("You've already reserved this {$type}"); } if ($Post->isOverdue()) { $message = "This post was reserved " . Time::tag($Post->reserved_at) . " so anyone's free to reserve it now."; $checkIfUserCanReserve($message, $data, 'overdue'); Response::fail($message, $data); } Users::reservationLimitExceeded(); if (!$Post->isTransferable()) { Response::fail("This {$type} was reserved recently, please allow up to 5 days before asking for a transfer"); } $ReserverLink = Users::get($reserved_by, 'id', 'name')->getProfileLink(); $PreviousAttempts = Posts::getTransferAttempts($Post, $type, $currentUser->id, $reserved_by); if (!empty($PreviousAttempts[0]) && empty($PreviousAttempts[0]['read_at'])) { Response::fail("You already expressed your interest in this post to {$ReserverLink} " . Time::tag($PreviousAttempts[0]['sent_at']) . ', please wait for them to respond.'); } $notifSent = Notifications::send($Post->reserved_by, 'post-passon', array('type' => $type, 'id' => $Post->id, 'user' => $currentUser->id)); Response::success("A notification has been sent to {$ReserverLink}, please wait for them to react.<br>If they don't visit the site often, it'd be a good idea to send them a note asking him to consider your inquiry."); } $isUserReserver = $Post->reserved_by === $currentUser->id; if (!empty($Post->reserved_by)) { switch ($action) { case 'reserve': if ($isUserReserver) { Response::fail("You've already reserved this {$type}", array('li' => Posts::getLi($Post))); } if ($Post->isOverdue()) { $overdue = array('reserved_by' => $Post->reserved_by, 'reserved_at' => $Post->reserved_at); $Post->reserved_by = null; break;
/** * Render episode voting HTML * * @param Episode $Episode * * @return string */ static function getSidebarVoting(Episode $Episode) : string { $thing = $Episode->isMovie ? 'movie' : 'episode'; if (!$Episode->aired) { return "<p>Voting will start " . Time::tag($Episode->willair) . ", after the {$thing} had aired.</p>"; } global $Database, $signedIn, $currentUser; $HTML = ''; if (empty($Episode->score)) { $Episode->updateScore(); } $Score = preg_replace(new RegExp('^(\\d+)\\.0+$'), '$1', number_format($Episode->score, 1)); $ScorePercent = round($Score / 5 * 1000) / 10; $HTML .= '<p>' . (!empty($Score) ? "This {$thing} is rated {$Score}/5 (<a class='detail'>Details</a>)" : 'Nopony voted yet.') . '</p>'; if ($Score > 0) { $HTML .= "<img src='/muffin-rating?w={$ScorePercent}' id='muffins' alt='muffin rating svg'>"; } $UserVote = Episodes::getUserVote($Episode); if (empty($UserVote)) { $HTML .= "<br><p>What did <em>you</em> think about the {$thing}?</p>"; if ($signedIn) { $HTML .= "<button class='blue rate typcn typcn-star'>Cast your vote</button>"; } else { $HTML .= "<p><em>Sign in above to cast your vote!</em></p>"; } } else { $HTML .= "<p>Your rating: " . CoreUtils::makePlural('muffin', $UserVote['vote'], PREPEND_NUMBER) . '</p>'; } return $HTML; }
static function getPendingReservationsHTML($UserID, $sameUser, &$YouHave = null) { global $Database, $currentUser; $YouHave = $sameUser ? 'You have' : 'This user has'; $PrivateSection = $sameUser ? Users::PROFILE_SECTION_PRIVACY_LEVEL['staff'] : ''; $cols = "id, season, episode, preview, label, posted, reserved_by"; $PendingReservations = $Database->where('reserved_by', $UserID)->where('deviation_id IS NULL')->get('reservations', null, $cols); $PendingRequestReservations = $Database->where('reserved_by', $UserID)->where('deviation_id IS NULL')->get('requests', null, "{$cols}, reserved_at, true as requested_by"); $TotalPending = count($PendingReservations) + count($PendingRequestReservations); $hasPending = $TotalPending > 0; $HTML = ''; if (Permission::sufficient('staff') || $sameUser) { $pendingCountReadable = $hasPending > 0 ? "<strong>{$TotalPending}</strong>" : 'no'; $posts = CoreUtils::makePlural('reservation', $TotalPending); $gamble = $TotalPending < 4 && $sameUser ? ' <button id="suggestion" class="btn orange typcn typcn-lightbulb">Suggestion</button>' : ''; $HTML .= <<<HTML <section class='pending-reservations'> <h2>{$PrivateSection}Pending reservations{$gamble}</h2> \t\t\t\t<span>{$YouHave} {$pendingCountReadable} pending {$posts} HTML; if ($hasPending) { $HTML .= " which ha" . ($TotalPending !== 1 ? 've' : 's') . "n't been marked as finished yet"; } $HTML .= "."; if ($sameUser) { $HTML .= " Please keep in mind that the global limit is 4 at any given time. If you reach the limit, you can't reserve any more images until you finish or cancel some of your pending reservations."; } $HTML .= "</span>"; if ($hasPending) { /** @var $Posts Post[] */ $Posts = array_merge(Posts::getReservationsSection($PendingReservations, RETURN_ARRANGED)['unfinished'], array_filter(array_values(Posts::getRequestsSection($PendingRequestReservations, RETURN_ARRANGED)['unfinished']))); usort($Posts, function (Post $a, Post $b) { $a = strtotime($a->posted); $b = strtotime($b->posted); return -($a < $b ? -1 : ($a === $b ? 0 : 1)); }); $LIST = ''; foreach ($Posts as $Post) { unset($_); $postLink = $Post->toLink($_); $postAnchor = $Post->toAnchor(null, $_); $label = !empty($Post->label) ? "<span class='label'>{$Post->label}</span>" : ''; $is_request = isset($Post->rq); $reservation_time_known = !empty($Post->reserved_at); $posted = Time::tag($is_request && $reservation_time_known ? $Post->reserved_at : $Post->posted); $PostedAction = $is_request && !$reservation_time_known ? 'Posted' : 'Reserved'; $contestable = $Post->isOverdue() ? Posts::CONTESTABLE : ''; $LIST .= <<<HTML <li> <div class='image screencap'> \t<a href='{$postLink}'><img src='{$Post->preview}'></a> </div> {$label} <em>{$PostedAction} under {$postAnchor} {$posted}</em>{$contestable} <div> \t<a href='{$postLink}' class='btn blue typcn typcn-arrow-forward'>View</a> \t<button class='red typcn typcn-user-delete cancel'>Cancel</button> </div> </li> HTML; } $HTML .= "<ul>{$LIST}</ul>"; } $HTML .= "</section>"; } return $HTML; }
private static function _getNotifElem($html, $n) { if (empty(self::$ACTIONABLE_NOTIF_OPTIONS[$n['type']])) { $actions = "<span class='mark-read variant-green typcn typcn-tick' title='Mark read' data-id='{$n['id']}'></span>"; } else { $actions = ''; foreach (self::$ACTIONABLE_NOTIF_OPTIONS[$n['type']] as $value => $opt) { $actions .= "<span class='mark-read variant-{$opt['color']} typcn typcn-{$opt['icon']}' title='{$opt['label']}' data-id='{$n['id']}' data-value='{$value}'></span>"; } } return "<li>{$html} <span class='nobr'>– " . Time::tag(strtotime($n['sent_at'])) . "{$actions}</span></li>"; }
/** * List ltem generator function for reservation suggestions * This function assumes that the post it's being used for is not reserved or it can be contested. * * @param Request $Request * * @return string */ static function getSuggestionLi(Request $Request) : string { $escapedLabel = CoreUtils::aposEncode($Request->label); $label = self::_getPostLabel($Request); $time_ago = Time::tag($Request->posted); $reserve = self::getPostReserveButton($Request, null, false); return <<<HTML <li id="request-{$Request->id}"> \t<div class="image screencap"> \t\t<a href="{$Request->fullsize}" target="_blank"> \t\t\t<img src="{$Request->fullsize}" alt="{$escapedLabel}"> \t\t</a> \t</div> \t{$label} \t<em class="post-date">Requested <a href="{$Request->toLink()}">{$time_ago}</a> under {$Request->toAnchor()}</em> \t{$reserve} </li> HTML; }
/** * Returns the markup for the time of last update displayed under an appaerance * * @param int $PonyID * @param bool $wrap * * @return string */ static function getUpdatesHTML($PonyID, $wrap = WRAP) { global $Database; $update = Updates::get($PonyID, MOST_RECENT); if (!empty($update)) { $update = "Last updated " . Time::tag($update['timestamp']); } else { if (!Permission::sufficient('staff')) { return ''; } $update = ''; } return $wrap ? "<div class='update'>{$update}</div>" : $update; }
</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(); ?>