static function start() { if (!Lock::isOn('cron-running-' . $_ENV['projectName'])) { if (Lock::on('cron-running-' . $_ENV['projectName'])) { Debug::out('Starting'); Control::req('scripts/crons/config'); while (!Lock::isOn('cron-off-' . $_ENV['projectName'])) { $time = new Time(); //+ ensure running only every minute { $parseTime = $time->format('YmdHi'); if (self::$lastParsedTime == $parseTime) { sleep(2); continue; } self::$lastParsedTime = $parseTime; //+ } //+ execute run items { $run = self::getRun($time); foreach ($run as $i) { $item = self::$list[$i]; if (self::$running[$i]) { $pid = pcntl_waitpid(self::$running[$i], $status, WNOHANG); if ($pid == 0) { //process is currently running, don't run again continue; } elseif ($pid == -1) { Debug::out('Process error:', $item); continue; } } $pid = pcntl_fork(); if ($pid == -1) { Debug::quit('Could not fork process', $item); } elseif ($pid) { //this is the parent self::$running[$i] = $pid; } else { //this is the child self::$args = $item[2]; $script = Config::userFileLocation($item[1], 'control/scripts/crons'); Control::req($script); exit; } } //+ } } Lock::off('cron-running-' . $_ENV['projectName']); } else { Debug::quit('Failed to lock "cron-running"'); } } else { Debug::quit('Cron already running'); } }
/** @param format DateTime::format() format @param zone The zone of the output time @param relation see php relative times; ex "-1 day". */ function format($format, $zone = null, $relation = null) { if ($relation) { $newDate = new Time($relation, $this->getTimezone(), $this); return $newDate->format($format, $zone); } if ($zone) { $currentZone = $this->getTimezone(); $this->setZone($zone); $return = parent::format($format); $this->setZone($currentZone); return $return; } else { return parent::format($format); } }
/** * Tests the format() method. * * @see \Jyxo\Time\Time::format() */ public function testFormat() { // Time with no translation necessary $this->assertEquals('121212', Time::get('2012-12-12T12:12:12+02:00')->format('ymd')); // Weekdays translation $days = array(_('Monday'), _('Tuesday'), _('Wednesday'), _('Thursday'), _('Friday'), _('Saturday'), _('Sunday')); $daysShort = array(_('Mon'), _('Tue'), _('Wed'), _('Thu'), _('Fri'), _('Sat'), _('Sun')); foreach ($days as $day => $name) { $time = new Time('2009-10-' . ($day + 12)); $this->assertEquals($days[date('N', strtotime('2009-10-' . ($day + 12))) - 1], $time->format('l')); $this->assertEquals($daysShort[date('N', strtotime('2009-10-' . ($day + 12))) - 1], $time->format('D')); } // Months translation $months = array(_('January'), _('February'), _('March'), _('April'), _('May'), _('June'), _('July'), _('August'), _('September'), _('October'), _('November'), _('December')); $monthsGen = array(_('January#~Genitive'), _('February#~Genitive'), _('March#~Genitive'), _('April#~Genitive'), _('May#~Genitive'), _('June#~Genitive'), _('July#~Genitive'), _('August#~Genitive'), _('September#~Genitive'), _('October#~Genitive'), _('November#~Genitive'), _('December#~Genitive')); $monthsShort = array(_('Jan'), _('Feb'), _('Mar'), _('Apr'), _('May#~Shortcut'), _('Jun'), _('Jul'), _('Aug'), _('Sep'), _('Oct'), _('Nov'), _('Dec')); foreach ($months as $month => $name) { $time = new Time('2009-' . str_pad($month + 1, 2, '0', STR_PAD_LEFT) . '-01'); $this->assertEquals($name, $time->format('F')); $this->assertEquals('1. ' . mb_strtolower($monthsGen[$month]), $time->format('j. F')); $this->assertEquals($monthsShort[$month], $time->format('M')); } // Full date/time $this->assertEquals(sprintf('%s 10. %s 2012 10:11:12', $days[5], mb_strtolower($monthsGen[10])), Time::get('2012-11-10 10:11:12')->format('l j. F Y H:i:s')); $this->assertEquals(sprintf('%s 2012', $months[9]), Time::get('2012-10-10')->format('F Y')); $this->assertEquals(sprintf('%s 2012', $monthsShort[8]), Time::get('2012-09-09')->format('M Y')); // Time zone handling $time1 = Time::now(); $timeZone = new \DateTimeZone($time1->getTimeZone()->getName() == 'Europe/Prague' ? 'UTC' : 'Europe/Prague'); $time2 = Time::now()->setTimeZone($timeZone); // Date/times must not be the same (Prague is UTC+1/+2) $this->assertNotSame($time1->format('Y-m-d H:i:s'), $time2->format('Y-m-d H:i:s')); // Get the results in the same time zone (of the first one) $this->assertSame($time1->format('Y-m-d H:i:s'), $time2->format('Y-m-d H:i:s', $time1->getTimeZone())); // Get the results in the same time zone (different for both instances) $commonTimeZone = new \DateTimeZone($timeZone->getName() == 'Europe/Prague' ? $time1->getTimeZone()->getName() == 'Pacific/Honolulu' ? 'America/Havana' : 'Pacific/Honolulu' : ($time1->getTimeZone()->getName() == 'Europe/Prague' ? 'Pacific/Honolulu' : 'Europe/Prague')); // The "common" time zone differs from both instances' time zones $this->assertNotSame($time1->getTimeZone()->getName(), $commonTimeZone->getName()); $this->assertNotSame($time2->getTimeZone()->getName(), $commonTimeZone->getName()); // And therefore local times differ (the common time zone is selected so that they do really differ :) $this->assertNotSame($time1->format('Y-m-d H:i:s'), $time1->format('Y-m-d H:i:s', $commonTimeZone)); $this->assertNotSame($time2->format('Y-m-d H:i:s'), $time2->format('Y-m-d H:i:s', $commonTimeZone)); // The result in the common time zone $this->assertSame($time1->format('Y-m-d H:i:s', $commonTimeZone), $time2->format('Y-m-d H:i:s', $commonTimeZone)); // Invalid timezone - name try { $this->assertSame(null, $time->format('Y-m-d', 'Foo/Bar')); $this->fail('Expected exception \\InvalidArgumentException.'); } catch (\PHPUnit_Framework_AssertionFailedError $e) { throw $e; } catch (\Exception $e) { // Correctly thrown exception $this->assertInstanceOf('\\InvalidArgumentException', $e); } // Invalid timezone - object try { $this->assertSame(null, $time->format('Y-m-d', new \stdClass())); $this->fail('Expected exception \\InvalidArgumentException.'); } catch (\PHPUnit_Framework_AssertionFailedError $e) { throw $e; } catch (\Exception $e) { // Correctly thrown exception $this->assertInstanceOf('\\InvalidArgumentException', $e); } }
/** * Render appearance PNG image * * @param array $Appearance * * @throws \Exception */ static function renderAppearancePNG($Appearance) { global $CGPath; $OutputPath = FSPATH . "cg_render/{$Appearance['id']}-palette.png"; $FileRelPath = "{$CGPath}/v/{$Appearance['id']}.png"; if (file_exists($OutputPath)) { Image::outputPNG(null, $OutputPath, $FileRelPath); } $OutWidth = 0; $OutHeight = 0; $SpriteWidth = $SpriteHeight = 0; $SpriteRightMargin = 10; $ColorCircleSize = 17; $ColorCircleRMargin = 5; $ColorNameFontSize = 12; $FontFile = APPATH . 'font/Celestia Medium Redux.ttf'; //$PixelatedFontFile = APPATH.'font/Volter (Goldfish).ttf'; $PixelatedFontFile = $FontFile; if (!file_exists($FontFile)) { throw new \Exception('Font file missing'); } $Name = $Appearance['label']; $NameVerticalMargin = 5; $NameFontSize = 22; $TextMargin = 10; $ColorsOutputted = 0; $SplitTreshold = 12; $ColumnRightMargin = 20; // Detect if sprite exists and adjust image size & define starting positions $SpritePath = SPRITE_PATH . "{$Appearance['id']}.png"; $SpriteExists = file_exists($SpritePath); if ($SpriteExists) { $SpriteSize = getimagesize($SpritePath); $Sprite = Image::preserveAlpha(imagecreatefrompng($SpritePath)); $SpriteHeight = $SpriteSize[HEIGHT]; $SpriteWidth = $SpriteSize[WIDTH]; $SpriteRealWidth = $SpriteWidth + $SpriteRightMargin; $OutWidth = $SpriteRealWidth; $OutHeight = $SpriteHeight; } else { $SpriteRealWidth = 0; } $origin = array('x' => $SpriteExists ? $SpriteRealWidth : $TextMargin, 'y' => 0); // Get color groups & calculate the space they take up $ColorGroups = ColorGroups::get($Appearance['id']); $CGCount = count($ColorGroups); $CGFontSize = round($NameFontSize / 1.25); $CGVerticalMargin = $NameVerticalMargin; $GroupLabelBox = Image::saneGetTTFBox($CGFontSize, $FontFile, 'ABCDEFGIJKLMOPQRSTUVWQYZabcdefghijklmnopqrstuvwxyz'); $ColorNameBox = Image::saneGetTTFBox($ColorNameFontSize, $PixelatedFontFile, 'AGIJKFagijkf'); $CGsHeight = $CGCount * ($GroupLabelBox['height'] + $CGVerticalMargin * 2 + $ColorCircleSize); // Get export time & size $ExportTS = "Generated at: " . Time::format(time(), Time::FORMAT_FULL); $ExportFontSize = round($CGFontSize / 1.5); $ExportBox = Image::saneGetTTFBox($ExportFontSize, $FontFile, $ExportTS); // Check how long & tall appearance name is, and set image width $NameBox = Image::saneGetTTFBox($NameFontSize, $FontFile, $Name); $OutWidth = $origin['x'] + max($NameBox['width'], $ExportBox['width']) + $TextMargin; // Set image height $OutHeight = max($origin['y'] + ($NameVerticalMargin * 4 + $NameBox['height'] + $ExportBox['height'] + $CGsHeight), $OutHeight); // Create base image $BaseImage = Image::createTransparent($OutWidth, $OutHeight); $BLACK = imagecolorallocate($BaseImage, 0, 0, 0); // If sprite exists, output it on base image if ($SpriteExists) { Image::copyExact($BaseImage, $Sprite, 0, 0, $SpriteWidth, $SpriteHeight); } // Output appearance name $origin['y'] += $NameVerticalMargin * 2; Image::writeOn($BaseImage, $Name, $origin['x'], $NameFontSize, $BLACK, $origin, $FontFile); $origin['y'] += $NameVerticalMargin; // Output generation time Image::writeOn($BaseImage, $ExportTS, $origin['x'], $ExportFontSize, $BLACK, $origin, $FontFile); $origin['y'] += $NameVerticalMargin; if (!empty($ColorGroups)) { $LargestX = 0; $LargestLabel = ''; $AllColors = ColorGroups::getColorsForEach($ColorGroups); foreach ($ColorGroups as $cg) { $CGLabelBox = Image::saneGetTTFBox($CGFontSize, $FontFile, $cg['label']); Image::calcRedraw($OutWidth, $OutHeight, $CGLabelBox['width'] + $TextMargin, $GroupLabelBox['height'] + $NameVerticalMargin + $CGVerticalMargin, $BaseImage, $origin); Image::writeOn($BaseImage, $cg['label'], $origin['x'], $CGFontSize, $BLACK, $origin, $FontFile, $GroupLabelBox); $origin['y'] += $GroupLabelBox['height'] + $CGVerticalMargin; if ($CGLabelBox['width'] > $LargestX) { $LargestX = $CGLabelBox['width']; $LargestLabel = $cg['label']; } if (!empty($AllColors[$cg['groupid']])) { foreach ($AllColors[$cg['groupid']] as $c) { $ColorNameLeftOffset = $ColorCircleSize + $ColorCircleRMargin; $CNBox = Image::saneGetTTFBox($ColorNameFontSize, $PixelatedFontFile, $c['label']); $WidthIncrease = $ColorNameLeftOffset + $CNBox['width'] + $TextMargin; $HeightIncrease = max($ColorCircleSize, $CNBox['height']) + $CGVerticalMargin; Image::calcRedraw($OutWidth, $OutHeight, $WidthIncrease, $HeightIncrease, $BaseImage, $origin); Image::drawCircle($BaseImage, $origin['x'], $origin['y'], $ColorCircleSize, $c['hex'], $BLACK); $yOffset = 2; Image::writeOn($BaseImage, $c['label'], $origin['x'] + $ColorNameLeftOffset, $ColorNameFontSize, $BLACK, $origin, $PixelatedFontFile, $ColorNameBox, $yOffset); $origin['y'] += $HeightIncrease; $ColorsOutputted++; $TotalWidth = $ColorNameLeftOffset + $CNBox['width']; if ($TotalWidth > $LargestX) { $LargestX = $TotalWidth; $LargestLabel = $c['label']; } } } if ($ColorsOutputted > $SplitTreshold) { Image::calcRedraw($OutWidth, $OutHeight, 0, $NameVerticalMargin, $BaseImage, $origin); $origin['y'] = $NameVerticalMargin * 4 + Image::saneGetTTFBox($NameFontSize, $FontFile, $Name)['height'] + Image::saneGetTTFBox($ExportFontSize, $FontFile, $ExportTS)['height']; $origin['x'] += $LargestX + $ColumnRightMargin; $ColorsOutputted = 0; $LargestX = 0; } else { $origin['y'] += $NameVerticalMargin; } } } $FinalBase = Image::createWhiteBG($OutWidth, $OutHeight); Image::drawSquare($FinalBase, 0, 0, array($OutWidth, $OutHeight), null, $BLACK); Image::copyExact($FinalBase, $BaseImage, 0, 0, $OutWidth, $OutHeight); if (!CoreUtils::createUploadFolder($OutputPath)) { Response::fail('Failed to create render directory'); } Image::outputPNG($FinalBase, $OutputPath, $FileRelPath); }
/** * @return string */ public function format() { return $this->time->format() . $this->command . $this->output->format() . PHP_EOL; }
public static function Output($string, $to = "natural", $timezone = "UTC") { $time = new Time($string); return $time->format($to, self::CoerceTimezone($timezone)); }