function testDifference() { $now = strtotime('2016-12-03T12:03:56Z'); $target = strtotime('2015-11-01T11:00:00Z'); $result = Time::difference($now, $target); self::assertTrue($result['past'], '$target is in the past'); self::assertEquals(1, $result['year'], 'Year diff calculation fails'); self::assertEquals(1, $result['month'], 'Month diff calculation fails'); self::assertEquals(2, $result['day'], 'Day diff calculation fails'); self::assertEquals(1, $result['hour'], 'Hour diff calculation fails'); self::assertEquals(3, $result['minute'], 'Minute diff calculation fails'); self::assertEquals(56, $result['second'], 'Seoond diff calculation fails'); }
/** * 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); }
/** * Render upcoming episode HTML * * @param bool $wrap Whether to output the wrapper elements * * @return string */ static function getSidebarUpcoming($wrap = WRAP) { global $Database, $PREFIX_REGEX; /** @var $Upcoming Episode[] */ $Upcoming = $Database->where('airs > NOW()')->orderBy('airs', 'ASC')->get('episodes'); if (empty($Upcoming)) { return; } $HTML = ''; foreach ($Upcoming as $Episode) { $airtime = strtotime($Episode->airs); $airs = date('c', $airtime); $month = date('M', $airtime); $day = date('j', $airtime); $diff = Time::difference(time(), $airtime); $time = 'in '; if ($diff['time'] < Time::$IN_SECONDS['month']) { $tz = "(" . date('T', $airtime) . ")"; if (!empty($diff['day'])) { $time .= "{$diff['day']} day" . ($diff['day'] !== 1 ? 's' : '') . ' & '; } if (!empty($diff['hour'])) { $time .= "{$diff['hour']}:"; } foreach (array('minute', 'second') as $k) { $diff[$k] = CoreUtils::pad($diff[$k]); } $time = "<time datetime='{$airs}'>{$time}{$diff['minute']}:{$diff['second']} {$tz}</time>"; } else { $time = Time::tag($Episode->airs); } $title = !$Episode->isMovie ? $Episode->title : ($PREFIX_REGEX->match($Episode->title) ? Episodes::shortenTitlePrefix($Episode->title) : "Movie: {$Episode->title}"); $HTML .= "<li><div class='calendar'><span class='top'>{$month}</span><span class='bottom'>{$day}</span></div>" . "<div class='meta'><span class='title'>{$title}</span><span class='time'>Airs {$time}</span></div></li>"; } return $wrap ? "<section id='upcoming'><h2>Upcoming episodes</h2><ul>{$HTML}</ul></section>" : $HTML; }