/**
  * @dataProvider provideValidTimestampDifferences
  * @covers MWTimestamp::diff
  */
 public function testDiff($timestamp1, $timestamp2, $expected)
 {
     $timestamp1 = new MWTimestamp($timestamp1);
     $timestamp2 = new MWTimestamp($timestamp2);
     $diff = $timestamp1->diff($timestamp2);
     $this->assertEquals($expected, $diff->format('%D %H %I %S'));
 }
 /**
  * Get the footer with user information (when joined, how
  * many edits/uploads, visit user page and talk page)
  * @return string
  */
 protected function getUserFooterData()
 {
     $fromDate = $this->targetUser->getRegistration();
     $ts = new MWTimestamp(wfTimestamp(TS_UNIX, $fromDate));
     $diff = $ts->diff(new MWTimestamp());
     if ($fromDate === null) {
         // User was registered in pre-historic times when registration wasn't recorded
         $msg = 'mobile-frontend-profile-footer-ancient';
         $units = 0;
         $fromDate = '20010115000000';
         // No users before that date
     } elseif ($diff->y) {
         $msg = 'mobile-frontend-profile-footer-years';
         $units = $diff->y;
     } elseif ($diff->m) {
         $msg = 'mobile-frontend-profile-footer-months';
         $units = $diff->m;
     } else {
         $msg = 'mobile-frontend-profile-footer-days';
         $units = $diff->d;
     }
     $editCount = $this->targetUser->getEditCount();
     $uploadCount = $this->userInfo->countRecentUploads($fromDate);
     // Ensure that the upload count is compatible with the i18n message
     if ($uploadCount > 500) {
         $uploadCount = 500;
     }
     $username = $this->targetUser->getName();
     return array('editsSummary' => $this->msg($msg, $username)->numParams($units, $editCount, $uploadCount)->parse(), 'linkUserPage' => Linker::link($this->targetUser->getUserPage(), $this->msg('mobile-frontend-profile-userpage-link', $username)->escaped()), 'linkTalk' => $this->getTalkLink());
 }
Ejemplo n.º 3
0
 /**
  * Convert an MWTimestamp into a pretty human-readable timestamp using
  * the given user preferences and relative base time.
  *
  * @see Language::getHumanTimestamp
  * @param MWTimestamp $ts Timestamp to prettify
  * @param MWTimestamp $relativeTo Base timestamp
  * @param User $user User preferences to use
  * @return string Human timestamp
  * @since 1.26
  */
 private function getHumanTimestampInternal(MWTimestamp $ts, MWTimestamp $relativeTo, User $user)
 {
     $diff = $ts->diff($relativeTo);
     $diffDay = (bool) ((int) $ts->timestamp->format('w') - (int) $relativeTo->timestamp->format('w'));
     $days = $diff->days ?: (int) $diffDay;
     if ($diff->invert || $days > 5 && $ts->timestamp->format('Y') !== $relativeTo->timestamp->format('Y')) {
         // Timestamps are in different years: use full timestamp
         // Also do full timestamp for future dates
         /**
          * @todo FIXME: Add better handling of future timestamps.
          */
         $format = $this->getDateFormatString('both', $user->getDatePreference() ?: 'default');
         $ts = $this->sprintfDate($format, $ts->getTimestamp(TS_MW));
     } elseif ($days > 5) {
         // Timestamps are in same year,  but more than 5 days ago: show day and month only.
         $format = $this->getDateFormatString('pretty', $user->getDatePreference() ?: 'default');
         $ts = $this->sprintfDate($format, $ts->getTimestamp(TS_MW));
     } elseif ($days > 1) {
         // Timestamp within the past week: show the day of the week and time
         $format = $this->getDateFormatString('time', $user->getDatePreference() ?: 'default');
         $weekday = self::$mWeekdayMsgs[$ts->timestamp->format('w')];
         // Messages:
         // sunday-at, monday-at, tuesday-at, wednesday-at, thursday-at, friday-at, saturday-at
         $ts = wfMessage("{$weekday}-at")->inLanguage($this)->params($this->sprintfDate($format, $ts->getTimestamp(TS_MW)))->text();
     } elseif ($days == 1) {
         // Timestamp was yesterday: say 'yesterday' and the time.
         $format = $this->getDateFormatString('time', $user->getDatePreference() ?: 'default');
         $ts = wfMessage('yesterday-at')->inLanguage($this)->params($this->sprintfDate($format, $ts->getTimestamp(TS_MW)))->text();
     } elseif ($diff->h > 1 || $diff->h == 1 && $diff->i > 30) {
         // Timestamp was today, but more than 90 minutes ago: say 'today' and the time.
         $format = $this->getDateFormatString('time', $user->getDatePreference() ?: 'default');
         $ts = wfMessage('today-at')->inLanguage($this)->params($this->sprintfDate($format, $ts->getTimestamp(TS_MW)))->text();
         // From here on in, the timestamp was soon enough ago so that we can simply say
         // XX units ago, e.g., "2 hours ago" or "5 minutes ago"
     } elseif ($diff->h == 1) {
         // Less than 90 minutes, but more than an hour ago.
         $ts = wfMessage('hours-ago')->inLanguage($this)->numParams(1)->text();
     } elseif ($diff->i >= 1) {
         // A few minutes ago.
         $ts = wfMessage('minutes-ago')->inLanguage($this)->numParams($diff->i)->text();
     } elseif ($diff->s >= 30) {
         // Less than a minute, but more than 30 sec ago.
         $ts = wfMessage('seconds-ago')->inLanguage($this)->numParams($diff->s)->text();
     } else {
         // Less than 30 seconds ago.
         $ts = wfMessage('just-now')->text();
     }
     return $ts;
 }
 /**
  * Handler for GetHumanTimestamp hook.
  * Converts the given time into a human-friendly relative format, for
  * example, '6 days ago', 'In 10 months'.
  *
  * @param string &$output The output timestamp
  * @param MWTimestamp $timestamp The current (user-adjusted) timestamp
  * @param MWTimestamp $relativeTo The relative (user-adjusted) timestamp
  * @param User $user User whose preferences are being used to make timestamp
  * @param Language $lang Language that will be used to render the timestamp
  * @return bool False means the timestamp was overridden so stop further
  *     processing. True means the timestamp was not overridden.
  */
 public static function onGetHumanTimestamp(&$output, $timestamp, $relativeTo, $user, $lang)
 {
     // Map PHP's DateInterval property codes to CLDR unit names.
     $units = array('s' => 'second', 'i' => 'minute', 'h' => 'hour', 'd' => 'day', 'm' => 'month', 'y' => 'year');
     // Get the difference between the two timestamps (as a DateInterval object).
     $timeDifference = $timestamp->diff($relativeTo);
     // Figure out if the timestamp is in the future or the past.
     if ($timeDifference->invert) {
         $tense = 'future';
     } else {
         $tense = 'past';
     }
     // Figure out which unit (days, months, etc.) it makes sense to display
     // the timestamp in, and get the number of that unit to use.
     $unit = null;
     foreach ($units as $code => $testUnit) {
         $testNumber = $timeDifference->format('%' . $code);
         if (intval($testNumber) > 0) {
             $unit = $testUnit;
             $number = $testNumber;
         }
     }
     // If it occurred less than 1 second ago, output 'just now' message.
     if (!$unit) {
         $output = wfMessage('just-now')->inLanguage($lang)->text();
         return false;
     }
     // Get the CLDR time unit strings for the user's language.
     // If no strings are returned, abandon the timestamp override.
     $timeUnits = TimeUnits::getUnits($lang->getCode());
     if (!$timeUnits) {
         return true;
     }
     // Figure out which grammatical number to use.
     // If the template doesn't exist, fall back to 'other' as the default.
     $grammaticalNumber = $lang->getPluralRuleType($number);
     $timeUnitKey = "{$unit}-{$tense}-{$grammaticalNumber}";
     if (!isset($timeUnits[$timeUnitKey])) {
         $timeUnitKey = "{$unit}-{$tense}-other";
     }
     // Not all languages have translations for everything
     if (!isset($timeUnits[$timeUnitKey])) {
         return true;
     }
     // Select the appropriate template for the timestamp.
     $timeUnit = $timeUnits[$timeUnitKey];
     // Replace the placeholder with the number.
     $output = str_replace('{0}', $lang->formatNum($number), $timeUnit);
     return false;
 }
Ejemplo n.º 5
0
 function execute()
 {
     global $wgVersion, $wgLang, $wgAllowSchemaUpdates;
     if (!$wgAllowSchemaUpdates && !($this->hasOption('force') || $this->hasOption('schema') || $this->hasOption('noschema'))) {
         $this->error("Do not run update.php on this wiki. If you're seeing this you should\n" . "probably ask for some help in performing your schema updates or use\n" . "the --noschema and --schema options to get an SQL file for someone\n" . "else to inspect and run.\n\n" . "If you know what you are doing, you can continue with --force\n", true);
     }
     $this->fileHandle = null;
     if (substr($this->getOption('schema'), 0, 2) === "--") {
         $this->error("The --schema option requires a file as an argument.\n", true);
     } elseif ($this->hasOption('schema')) {
         $file = $this->getOption('schema');
         $this->fileHandle = fopen($file, "w");
         if ($this->fileHandle === false) {
             $err = error_get_last();
             $this->error("Problem opening the schema file for writing: {$file}\n\t{$err['message']}", true);
         }
     }
     $wgLang = Language::factory('en');
     define('MW_UPDATER', true);
     $this->output("MediaWiki {$wgVersion} Updater\n\n");
     wfWaitForSlaves(5);
     // let's not kill databases, shall we? ;) --tor
     if (!$this->hasOption('skip-compat-checks')) {
         $this->compatChecks();
     } else {
         $this->output("Skipping compatibility checks, proceed at your own risk (Ctrl+C to abort)\n");
         wfCountdown(5);
     }
     // Check external dependencies are up to date
     if (!$this->hasOption('skip-external-dependencies')) {
         $composerLockUpToDate = $this->runChild('CheckComposerLockUpToDate');
         $composerLockUpToDate->execute();
     } else {
         $this->output("Skipping checking whether external dependencies are up to date, proceed at your own risk\n");
     }
     # Attempt to connect to the database as a privileged user
     # This will vomit up an error if there are permissions problems
     $db = wfGetDB(DB_MASTER);
     $this->output("Going to run database updates for " . wfWikiID() . "\n");
     if ($db->getType() === 'sqlite') {
         $this->output("Using SQLite file: '{$db->getDbFilePath()}'\n");
     }
     $this->output("Depending on the size of your database this may take a while!\n");
     if (!$this->hasOption('quick')) {
         $this->output("Abort with control-c in the next five seconds " . "(skip this countdown with --quick) ... ");
         wfCountDown(5);
     }
     $time1 = new MWTimestamp();
     $shared = $this->hasOption('doshared');
     $updates = array('core', 'extensions');
     if (!$this->hasOption('schema')) {
         if ($this->hasOption('noschema')) {
             $updates[] = 'noschema';
         }
         $updates[] = 'stats';
     }
     $updater = DatabaseUpdater::newForDb($db, $shared, $this);
     $updater->doUpdates($updates);
     foreach ($updater->getPostDatabaseUpdateMaintenance() as $maint) {
         $child = $this->runChild($maint);
         // LoggedUpdateMaintenance is checking the updatelog itself
         $isLoggedUpdate = is_a($child, 'LoggedUpdateMaintenance');
         if (!$isLoggedUpdate && $updater->updateRowExists($maint)) {
             continue;
         }
         $child->execute();
         if (!$isLoggedUpdate) {
             $updater->insertUpdateRow($maint);
         }
     }
     $updater->setFileAccess();
     if (!$this->hasOption('nopurge')) {
         $updater->purgeCache();
     }
     $time2 = new MWTimestamp();
     $timeDiff = $time2->diff($time1);
     $this->output("\nDone in " . $timeDiff->format("%i:%S") . ".\n");
 }