/** * @param array $Appearances * @param bool $wrap * * @return string */ static function getHTML($Appearances, $wrap = WRAP) { global $CGDb, $_MSG, $Search; $HTML = ''; if (!empty($Appearances)) { foreach ($Appearances as $Appearance) { $Appearance['label'] = CoreUtils::escapeHTML($Appearance['label']); $img = self::getSpriteHTML($Appearance); $updates = self::getUpdatesHTML($Appearance['id']); $notes = self::getNotesHTML($Appearance); $tags = $Appearance['id'] ? self::getTagsHTML($Appearance['id'], true, $Search) : ''; $colors = self::getColorsHTML($Appearance); $eqgp = $Appearance['ishuman'] ? 'eqg/' : ''; $RenderPath = FSPATH . "cg_render/{$Appearance['id']}.png"; $FileModTime = '?t=' . (file_exists($RenderPath) ? filemtime($RenderPath) : time()); $Actions = "<a class='btn typcn typcn-image darkblue' title='View as PNG' href='/cg/{$eqgp}v/{$Appearance['id']}.png{$FileModTime}' target='_blank'></a>" . "<button class='getswatch typcn typcn-brush teal' title='Download swatch file'></button>"; if (Permission::sufficient('staff')) { $Actions .= "<button class='edit typcn typcn-pencil blue' title='Edit'></button>" . ($Appearance['id'] !== 0 ? "<button class='delete typcn typcn-trash red' title='Delete'></button>" : ''); } $safelabel = self::getSafeLabel($Appearance); $HTML .= "<li id='p{$Appearance['id']}'>{$img}<div><strong><a href='/cg/v/{$Appearance['id']}-{$safelabel}'>{$Appearance['label']}</a>{$Actions}</strong>{$updates}{$notes}{$tags}{$colors}</div></li>"; } } else { if (empty($_MSG)) { $_MSG = "No appearances to show"; } $HTML .= "<div class='notice info align-center'><label>{$_MSG}</label></div>"; } return $wrap ? "<ul id='list' class='appearance-list'>{$HTML}</ul>" : $HTML; }
public function processLabel() : string { $label = preg_replace(new RegExp('(?:(f)ull[-\\s](b)od(?:y|ied)(\\sversion)?)', 'i'), '<strong class="color-darkblue">$1ull $2ody</strong>$3', CoreUtils::escapeHTML($this->label)); $label = preg_replace(new RegExp('(?:(f)ace[-\\s](o)nly(\\sversion)?)', 'i'), '<strong class="color-darkblue">$1ace $2nly</strong>$3', $label); $label = preg_replace(new RegExp('(?:(f)ull\\s(s)cene?)', 'i'), '<strong class="color-darkblue">$1ull $2cene</strong>$3', $label); $label = preg_replace(new RegExp('(?:(e)ntire\\s(s)cene?)', 'i'), '<strong class="color-darkblue">$1ntire $2cene</strong>$3', $label); return $label; }
function testEscapeHTML() { $result = CoreUtils::escapeHTML("<script>alert('XSS')</script>"); self::assertEquals("<script>alert('XSS')</script>", $result); $result = CoreUtils::escapeHTML('<'); self::assertEquals("<", $result); $result = CoreUtils::escapeHTML('>'); self::assertEquals(">", $result); }
/** * Get HTML for a color group * * @param int|array $GroupID * @param array|null $AllColors * @param bool $wrap * @param bool $colon * @param bool $colorNames * @param bool $force_extra_info * * @return string */ static function getHTML($GroupID, $AllColors = null, bool $wrap = true, bool $colon = true, bool $colorNames = false, bool $force_extra_info = false) : string { global $CGDb; if (is_array($GroupID)) { $Group = $GroupID; } else { $Group = $CGDb->where('groupid', $GroupID)->getOne('colorgroups'); } $label = CoreUtils::escapeHTML($Group['label']) . ($colon ? ': ' : ''); $HTML = "<span class='cat'>{$label}" . ($colorNames && Permission::sufficient('staff') ? '<span class="admin"><button class="blue typcn typcn-pencil edit-cg"></button><button class="red typcn typcn-trash delete-cg"></button></span>' : '') . "</span>"; if (!isset($AllColors)) { $Colors = self::getColors($Group['groupid']); } else { $Colors = $AllColors[$Group['groupid']] ?? null; } if (!empty($Colors)) { $extraInfo = $force_extra_info || !UserPrefs::get('cg_hideclrinfo'); foreach ($Colors as $i => $c) { $title = CoreUtils::aposEncode($c['label']); $color = ''; if (!empty($c['hex'])) { $color = $c['hex']; $title .= "' style='background-color:{$color}' class='valid-color"; } $append = "<span title='{$title}'>{$color}</span>"; if ($colorNames) { $append = "<div class='color-line" . (!$extraInfo || empty($color) ? ' no-detail' : '') . "'>{$append}<span><span class='label'>{$c['label']}"; if ($extraInfo && !empty($color)) { $rgb = CoreUtils::hex2Rgb($color); $rgb = 'rgb(' . implode(',', $rgb) . ')'; $append .= "</span><span class='ext'>{$color} • {$rgb}"; } $append .= '</span></div>'; } $HTML .= $append; } } return $wrap ? "<li id='cg{$Group['groupid']}'>{$HTML}</li>" : $HTML; }
/** * Turns an 'episode' database row into a readable title * * @param bool $returnArray Whether to return as an array instead of string * @param string $arrayKey * @param bool $append_num Append overall # to ID * * @return string|array */ public function formatTitle($returnArray = false, $arrayKey = null, $append_num = true) { if ($returnArray === AS_ARRAY) { $arr = array('id' => $this->getID(array('append_num' => $append_num)), 'season' => $this->season ?? null, 'episode' => $this->episode ?? null, 'title' => isset($this->title) ? CoreUtils::escapeHTML($this->title) : null); if (!empty($arrayKey)) { return isset($arr[$arrayKey]) ? $arr[$arrayKey] : null; } else { return $arr; } } if ($this->isMovie) { return $this->title; } return $this->getID(array('pad' => true)) . ': ' . $this->title; }
/** * Returns the HTML code of the navigation in the header * * @param bool $disabled * * @return string */ static function getNavigationHTML($disabled = false) { if (!empty($GLOBALS['NavHTML'])) { return $GLOBALS['NavHTML']; } global $do; // Navigation items if (!$disabled) { $NavItems = array('latest' => array('/', 'Latest episode'), 'eps' => array('/episodes', 'Episodes')); if ($do === 'episodes') { global $Episodes, $Pagination; if (isset($Episodes)) { $NavItems['eps'][1] .= " - Page {$Pagination->page}"; } } global $CurrentEpisode; if (($do === 'episode' || $do === 's' || $do === 'movie') && !empty($CurrentEpisode)) { if ($CurrentEpisode->isMovie) { $NavItems['eps'][1] = 'Movies'; } if ($CurrentEpisode->isLatest()) { $NavItems['latest'][0] = $_SERVER['REQUEST_URI']; } else { $NavItems['eps']['subitem'] = CoreUtils::cutoff($GLOBALS['heading'], Episodes::TITLE_CUTOFF); } } global $Color, $EQG; $NavItems['colorguide'] = array("/cg" . (!empty($EQG) ? '/eqg' : ''), (!empty($EQG) ? 'EQG ' : '') . "{$Color} Guide"); if ($do === 'colorguide') { global $Tags, $Changes, $Ponies, $Pagination, $Appearance, $Map; if (!empty($Appearance)) { $NavItems['colorguide']['subitem'] = (isset($Map) ? "Sprite {$Color}s - " : '') . CoreUtils::escapeHTML($Appearance['label']); } else { if (isset($Ponies)) { $NavItems['colorguide'][1] .= " - Page {$Pagination->page}"; } else { if ($GLOBALS['data'] === 'full') { $NavItems['colorguide']['subitem'] = 'Full List'; } else { if (isset($Tags)) { $pagePrefix = 'Tags'; } else { if (isset($Changes)) { $pagePrefix = "Major {$Color} Changes"; } } $NavItems['colorguide']['subitem'] = (isset($pagePrefix) ? "{$pagePrefix} - " : '') . "Page {$Pagination->page}"; } } } } if ($GLOBALS['signedIn']) { $NavItems['u'] = array("/@{$GLOBALS['currentUser']->name}", 'Account'); } if ($do === 'user' || Permission::sufficient('staff')) { global $User, $sameUser; $NavItems['users'] = array('/users', 'Users', Permission::sufficient('staff')); if (!empty($User) && empty($sameUser)) { $NavItems['users']['subitem'] = $User->name; } } if (Permission::sufficient('staff')) { $NavItems['admin'] = array('/admin', 'Admin'); global $task; if ($task === 'logs') { global $Pagination; $NavItems['admin']['subitem'] = "Logs - Page {$Pagination->page}"; } } $NavItems[] = array('/about', 'About'); } else { $NavItems = array(array(true, 'HTTP 503', false, 'subitem' => 'Service Temporarily Unavailable')); } $GLOBALS['NavHTML'] = ''; foreach ($NavItems as $item) { $sublink = ''; if (isset($item['subitem'])) { list($class, $sublink) = self::_processHeaderLink(array(true, $item['subitem'])); $sublink = " › {$sublink}"; $link = self::_processHeaderLink($item, HTML_ONLY); } else { if (isset($item[2]) && !$item[2]) { continue; } else { list($class, $link) = self::_processHeaderLink($item); } } $GLOBALS['NavHTML'] .= "<li{$class}>{$link}{$sublink}</li>"; } $GLOBALS['NavHTML'] .= '<li><a href="http://mlp-vectorclub.deviantart.com/" target="_blank">MLP-VectorClub</a></li>'; return $GLOBALS['NavHTML']; }
/** * Format log entry details * * @param array $MainEntry Main log entry * @param array $data Data to process (sub-log entry) * * @return array */ static function formatEntryDetails($MainEntry, $data) { global $Database, $CGDb; $details = array(); $reftype = $MainEntry['reftype']; switch ($reftype) { case "rolechange": /** @var $target User */ $target = $Database->where('id', $data['target'])->getOne('users'); $details = array(array('Target user', $target->getProfileLink()), array('Old group', Permission::ROLES_ASSOC[$data['oldrole']]), array('New group', Permission::ROLES_ASSOC[$data['newrole']])); break; case "episodes": $details[] = array('Action', self::$ACTIONS[$data['action']]); $details[] = array('Name', (new Episode($data))->formatTitle()); if ($data['season'] === 0) { $details[] = array('Overall', "#{$data['episode']}"); } if (!empty($data['airs'])) { $details[] = array('Air date', Time::tag($data['airs'], Time::TAG_EXTENDED, Time::TAG_STATIC_DYNTIME)); } $details[] = array('Two parts', !empty($data['twoparter'])); break; case "episode_modify": $link = $data['target']; $EpData = Episodes::parseID($data['target']); if (!empty($EpData)) { $Episode = Episodes::getActual($EpData['season'], $EpData['episode'], Episodes::ALLOW_MOVIES); if (!empty($Episode)) { $link = "<a href='" . $Episode->formatURL() . "'>" . $Episode->formatTitle(AS_ARRAY, 'id') . "</a>"; } } $details[] = array('Episode', $link); if (empty($Episode)) { $details[] = array('Still exists', false); } unset($data['entryid'], $data['target']); $newOld = self::_arrangeNewOld($data); if (!empty($newOld['airs'])) { $newOld['airs']['old'] = Time::tag($newOld['airs']['old'], Time::TAG_EXTENDED, Time::TAG_STATIC_DYNTIME); $newOld['airs']['new'] = Time::tag($newOld['airs']['new'], Time::TAG_EXTENDED, Time::TAG_STATIC_DYNTIME); } if (isset($newOld['title']['old']) && isset($newOld['title']['new'])) { $details[] = array('Title', self::charDiff($newOld['title']['old'], $newOld['title']['new'])); unset($newOld['title']); } foreach ($newOld as $thing => $ver) { $details[] = array("Old {$thing}", $ver['old']); $details[] = array("New {$thing}", $ver['new']); } break; case "userfetch": $details[] = array('User', Users::get($data['userid'])->getProfileLink()); break; case "banish": case "un-banish": $details[] = array('User', Users::get($data['target'])->getProfileLink()); $details[] = array('Reason', CoreUtils::escapeHTML($data['reason'])); break; case "post_lock": $Post = $Database->where('id', $data['id'])->getOne("{$data['type']}s"); self::_genericPostInfo($Post, $data, $details); break; case "color_modify": $details[] = array('Appearance', self::_getAppearanceLink($data['ponyid'])); $details[] = array('Reason', CoreUtils::escapeHTML($data['reason'])); break; case "req_delete": $details[] = array('Request ID', $data['id']); $typeNames = array('chr' => 'Character', 'obj' => 'Object', 'bg' => 'Background'); $details[] = array('Description', CoreUtils::escapeHTML($data['label'])); $details[] = array('Type', $typeNames[$data['type']]); $IDstr = "S{$data['season']}E{$data['episode']}"; $details[] = array('Episode', "<a href='/episode/{$IDstr}'>{$IDstr}</a>"); $details[] = array('Posted', Time::tag($data['posted'], Time::TAG_EXTENDED, Time::TAG_STATIC_DYNTIME)); if (!empty($data['requested_by'])) { $details[] = array('Requested by', Users::get($data['requested_by'])->getProfileLink()); } if (!empty($data['reserved_by'])) { $details[] = array('Reserved by', Users::get($data['reserved_by'])->getProfileLink()); } $details[] = array('Finished', !empty($data['deviation_id'])); if (!empty($data['deviation_id'])) { $details[] = array('Deviation', self::_link("http://fav.me/{$data['deviation_id']}")); $details[] = array('Approved', $data['lock']); } break; case "img_update": $Post = $Database->where('id', $data['id'])->getOne("{$data['thing']}s"); $data['type'] = $data['thing']; self::_genericPostInfo($Post, $data, $details); $details[] = array('Old image', "<a href='{$data['oldfullsize']}' target='_blank'>Full size</a><div><img src='{$data['oldpreview']}'></div>"); $details[] = array('New image', "<a href='{$data['newfullsize']}' target='_blank'>Full size</a><div><img src='{$data['newpreview']}'></div>"); break; case "res_overtake": $Post = $Database->where('id', $data['id'])->getOne("{$data['type']}s"); self::_genericPostInfo($Post, $data, $details); $details[] = array('Previous reserver', Users::get($data['reserved_by'])->getProfileLink()); $details[] = array('Previously reserved at', Time::tag($data['reserved_at'], Time::TAG_EXTENDED, Time::TAG_STATIC_DYNTIME)); $diff_text = ''; $diff = Time::difference(strtotime($MainEntry['timestamp']), strtotime($data['reserved_at'])); foreach (array_keys(Time::$IN_SECONDS) as $unit) { if (empty($diff[$unit])) { continue; } $diff_text .= CoreUtils::makePlural($unit, $diff[$unit], PREPEND_NUMBER) . ' '; } $details[] = array('In progress for', rtrim($diff_text)); break; case "appearances": $details[] = array('Action', self::$ACTIONS[$data['action']]); $PonyGuide = empty($data['ishuman']); $details[] = array('Guide', $PonyGuide ? 'Pony' : 'EQG'); $details[] = array('ID', self::_getAppearanceLink($data['id'])); $details[] = array('Label', $data['label']); if (!empty($data['order'])) { $details[] = array('Ordering index', $data['order']); } if (!empty($data['notes'])) { $details[] = array('Notes', '<div>' . nl2br($data['notes']) . '</div>'); } if (!empty($data['cm_favme'])) { $details[] = array('CM Submission', self::_link("http://fav.me/{$data['cm_favme']}")); $details[] = array('CM Orientation', CGUtils::$CM_DIR[$data['cm_dir']]); if (!empty($data['cm_preview'])) { $details[] = array('Custom CM Preview', "<img src='" . CoreUtils::aposEncode($data['cm_preview']) . "'>"); } } if (!empty($data['usetemplate'])) { $details[] = array('Template applied', true); } $details[] = array('Private', !empty($data['private'])); if (!empty($data['added'])) { $details[] = array('Added', Time::tag($data['added'], Time::TAG_EXTENDED, Time::TAG_STATIC_DYNTIME)); } break; case "res_transfer": $Post = $Database->where('id', $data['id'])->getOne("{$data['type']}s"); self::_genericPostInfo($Post, $data, $details); $details[] = array('New reserver', Users::get($data['to'])->getProfileLink()); break; case "cg_modify": $details[] = array('Appearance', self::_getAppearanceLink($data['ponyid'])); $CG = $CGDb->where('groupid', $data['groupid'])->getOne('colorgroups'); if (empty($CG)) { $details[] = array('Color group ID', '#' . $data['groupid']); $details[] = array('Still exists', false); } else { $details[] = array('Group', "{$CG['label']} (#{$data['groupid']})"); } if (isset($data['newlabel'])) { $details[] = array('Label', self::charDiff($data['oldlabel'] ?? '', $data['newlabel'])); } if (isset($data['newcolors'])) { $details[] = array('Colors', self::charDiff($data['oldcolors'] ?? '', $data['newcolors'], 'block')); } break; case "cgs": $details[] = array('Action', self::$ACTIONS[$data['action']]); $details[] = array('Color group ID', '#' . $data['groupid']); $details[] = array('Label', $data['label']); $details[] = array('Appearance', self::_getAppearanceLink($data['ponyid'])); if (isset($data['order'])) { $details[] = array('Ordering index', $data['order']); } break; case "cg_order": $details[] = array('Appearance', self::_getAppearanceLink($data['ponyid'])); $details[] = array('Order', self::charDiff($data['oldgroups'], $data['newgroups'], 'block')); break; case "appearance_modify": $details[] = array('Appearance', self::_getAppearanceLink($data['ponyid'])); $changes = JSON::decode($data['changes']); $newOld = self::_arrangeNewOld($changes); if (isset($newOld['label']['new'])) { $details[] = array('Label', self::charDiff($newOld['label']['old'], $newOld['label']['new'], 'block')); } if (isset($newOld['notes']['new']) || isset($newOld['notes']['old'])) { $details[] = array('Notes', self::charDiff($newOld['notes']['old'] ?? '', $newOld['notes']['new'] ?? '', 'block smaller')); } if (isset($newOld['cm_favme']['old'])) { $details[] = array('Old CM Submission', self::_link('http://fav.me/' . $newOld['cm_favme']['old'])); } else { if (isset($newOld['cm_favme']['new'])) { $details[] = array('Old CM Submission', null); } } if (isset($newOld['cm_favme']['new'])) { $details[] = array('New CM Submission', self::_link('http://fav.me/' . $newOld['cm_favme']['new'])); } else { if (isset($newOld['cm_favme']['old'])) { $details[] = array('New CM Submission', null); } } $olddir = isset($newOld['cm_dir']['old']) ? CGUtils::$CM_DIR[$newOld['cm_dir']['old']] : ''; $newdir = isset($newOld['cm_dir']['new']) ? CGUtils::$CM_DIR[$newOld['cm_dir']['new']] : ''; if ($olddir || $newdir) { $details[] = array('CM Orientation', self::charDiff($olddir, $newdir, 'inline', new FineDiff\Granularity\Paragraph())); } if (isset($newOld['private']['new'])) { $details[] = array('<span class="typcn typcn-lock-' . ($newOld['private']['new'] ? 'closed' : 'open') . '"></span> ' . ($newOld['private']['new'] ? 'Marked private' : 'No longer private'), self::SKIP_VALUE, self::KEYCOLOR_INFO); } if (isset($newOld['cm_preview']['new'])) { $details[] = array('New Custom CM Preview', "<img src='" . CoreUtils::aposEncode($newOld['cm_preview']['new']) . "'>"); } else { if (isset($newOld['cm_preview']['old'])) { $details[] = array('New Custom CM Preview', null); } } break; case "da_namechange": $User = Users::get($data['id'], 'id', 'name'); $newIsCurrent = $User->name === $data['new']; $details[] = array('User', $User->getProfileLink()); if ($newIsCurrent) { $details[] = array('Old name', $data['old']); } else { $details[] = array('Name', Logs::charDiff($data['old'], $data['new'])); } break; case "video_broken": $IDstr = "S{$data['season']}E{$data['episode']}"; $details[] = array('Episode', "<a href='/episode/{$IDstr}'>{$IDstr}</a>"); $url = VideoProvider::getEmbed(new EpisodeVideo(array('provider' => $data['provider'], 'id' => $data['id'])), VideoProvider::URL_ONLY); $details[] = array('Link', "<a href='{$url}'>{$url}</a>"); break; default: $details[] = array('<span class="typcn typcn-warning"></span> Couldn\'t process details', 'No data processor defined for this entry type', self::KEYCOLOR_ERROR); $details[] = array('Raw details', '<pre>' . var_export($data, true) . '</pre>'); break; } return array('details' => $details); }
<?php use App\CGUtils; use App\CoreUtils; use App\Models\User; use App\DeviantArt; use App\Permission; use App\Users; use App\Appearances; use App\ColorGroups; use App\Tags; /** @var $Appearance array */ /** @var $heading string */ ?> <div id="content"> <div class="sprite-wrap"><?=Appearances::getSpriteHTML($Appearance)?></div> <h1><?=CoreUtils::escapeHTML($heading)?></h1> <p>from the MLP-VectorClub <a href="/cg"><?=$Color?> Guide</a></p> <? if (Permission::sufficient('staff')){ ?> <div class="notice warn align-center appearance-private-notice"<?=!empty($Appearance['private'])?'':' style="display:none"'?>><p><span class="typcn typcn-lock-closed"></span> <strong>This appearance is currently private (its colors are only visible to staff members)</strong></p></div> <?php } $RenderPath = FSPATH."cg_render/{$Appearance['id']}.png"; $FileModTime = '?t='.(file_exists($RenderPath) ? filemtime($RenderPath) : time()); ?> <div id="p<?=$Appearance['id']?>"> <div class='align-center'> <a class='darkblue btn typcn typcn-image' href='/cg/v/<?="{$Appearance['id']}.png$FileModTime"?>' target='_blank'>View as PNG</a> <button class='getswatch typcn typcn-brush teal'>Download swatch file</button> <? if (Permission::sufficient('staff')){ ?> <button class='blue edit typcn typcn-pencil'>Edit metadata</button> <?php if ($Appearance['id']){ ?>
<? 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>
} $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 echo $Title; ?> </title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta property="og:type" content="website"> <meta property="og:image" content="<?php echo $ThumbImage; ?> ">
?> : </span><?php echo CoreUtils::cutoff(Episodes::removeTitlePrefix($PrevEpisodeTitle['title']), Episodes::TITLE_CUTOFF); ?> </a> </div> <?php } else { echo " "; } ?> </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 }