diff --git a/Sitemap.php b/Sitemap.php index 94f501d..6c05a54 100644 --- a/Sitemap.php +++ b/Sitemap.php @@ -181,7 +181,7 @@ private function createNewFile() * elements that did not fit into the previous file. (See self::flush) */ $this->writer->text("\n"); - $this->flush(true); + $this->flush(); } /** @@ -209,17 +209,22 @@ private function finishFile() */ public function write() { - $this->finishFile(); + if ($this->writer !== null) { + $this->flush(); + $this->finishFile(); + } } /** * Flushes buffer into file * * @param int $footSize Size of the remaining closing tags + * @return bool is new file created * @throws \OverflowException */ private function flush($footSize = 10) { + $isNewFileCreated = false; $data = $this->writer->flush(true); $dataSize = mb_strlen($data, '8bit'); @@ -235,10 +240,13 @@ private function flush($footSize = 10) } $this->finishFile(); $this->createNewFile(); + $isNewFileCreated = true; } $this->writerBackend->append($data); $this->byteCount += $dataSize; + + return $isNewFileCreated; } /** @@ -268,8 +276,11 @@ protected function validateLocation($location) { */ public function addItem($location, $lastModified = null, $changeFrequency = null, $priority = null) { - if ($this->urlsCount >= $this->maxUrls) { - $this->finishFile(); + if ($this->urlsCount >= $this->maxUrls && $this->writer !== null) { + $isNewFileCreated = $this->flush(); + if (!$isNewFileCreated) { + $this->finishFile(); + } } if ($this->writerBackend === null) { @@ -517,4 +528,4 @@ public function setStylesheet($stylesheetUrl) $this->stylesheet = $stylesheetUrl; } } -} \ No newline at end of file +} diff --git a/tests/SitemapTest.php b/tests/SitemapTest.php index 2b1936d..d058f4c 100644 --- a/tests/SitemapTest.php +++ b/tests/SitemapTest.php @@ -7,6 +7,10 @@ class SitemapTest extends \PHPUnit_Framework_TestCase { + const HEADER_LENGTH = 100; + const FOOTER_LENGTH = 10; + const ELEMENT_LENGTH_WITHOUT_URL = 137; + /** * Asserts validity of simtemap according to XSD schema * @param string $fileName @@ -365,4 +369,161 @@ public function testBufferSizeImpact() $this->assertLessThan($times[0] * 1.2, $times[1]); } + + public function testBufferSizeIsNotTooBigOnFinishFileInWrite() + { + $time = 100; + $urlLength = 13; + $urlsQty = 4; + + $sitemapPath = __DIR__ . '/sitemap.xml'; + $sitemap = new Sitemap($sitemapPath); + $sitemap->setBufferSize(3); + $sitemap->setMaxUrls(4); + $sitemap->setMaxBytes( + self::HEADER_LENGTH + self::FOOTER_LENGTH + self::ELEMENT_LENGTH_WITHOUT_URL * $urlsQty + + $urlLength * $urlsQty - 1 + ); + + for ($i = 0; $i < $urlsQty; $i++) { + $sitemap->addItem( + // url 13 bytes + "https://a.b/{$i}", + $time, + Sitemap::WEEKLY, + 1 + ); + } + $sitemap->write(); + + $expectedFiles = array( + __DIR__ . '/sitemap.xml', + __DIR__ . '/sitemap_2.xml', + ); + $expected[] = << + + + https://a.b/0 + 1970-01-01T00:01:40+00:00 + weekly + 1.0 + + + https://a.b/1 + 1970-01-01T00:01:40+00:00 + weekly + 1.0 + + + https://a.b/2 + 1970-01-01T00:01:40+00:00 + weekly + 1.0 + + +EOF; + $expected[] = << + + + https://a.b/3 + 1970-01-01T00:01:40+00:00 + weekly + 1.0 + + +EOF; + foreach ($expectedFiles as $expectedFileNumber => $expectedFile) { + $this->assertTrue(file_exists($expectedFile), "$expectedFile does not exist!"); + $this->assertIsValidSitemap($expectedFile); + + $actual = trim(file_get_contents($expectedFile)); + $this->assertEquals($expected[$expectedFileNumber], $actual); + + unlink($expectedFile); + } + } + + public function testBufferSizeIsNotTooBigOnFinishFileInAddItem() + { + $time = 100; + $urlLength = 13; + $urlsQty = 5; + + $sitemapPath = __DIR__ . '/sitemap.xml'; + $sitemap = new Sitemap($sitemapPath); + $sitemap->setBufferSize(3); + $sitemap->setMaxUrls(4); + $sitemap->setMaxBytes( + // 100 + 10 + 137 * 4 + self::HEADER_LENGTH + self::FOOTER_LENGTH + self::ELEMENT_LENGTH_WITHOUT_URL * 4 + + $urlLength * 4 - 1 + ); + + for ($i = 0; $i < $urlsQty; $i++) { + $sitemap->addItem( + // url 13 bytes + "https://a.b/{$i}", + $time, + Sitemap::WEEKLY, + 1 + ); + } + $sitemap->write(); + + $expectedFiles = array( + __DIR__ . '/sitemap.xml', + __DIR__ . '/sitemap_2.xml', + ); + $expected[] = << + + + https://a.b/0 + 1970-01-01T00:01:40+00:00 + weekly + 1.0 + + + https://a.b/1 + 1970-01-01T00:01:40+00:00 + weekly + 1.0 + + + https://a.b/2 + 1970-01-01T00:01:40+00:00 + weekly + 1.0 + + +EOF; + $expected[] = << + + + https://a.b/3 + 1970-01-01T00:01:40+00:00 + weekly + 1.0 + + + https://a.b/4 + 1970-01-01T00:01:40+00:00 + weekly + 1.0 + + +EOF; + foreach ($expectedFiles as $expectedFileNumber => $expectedFile) { + $this->assertTrue(file_exists($expectedFile), "$expectedFile does not exist!"); + $this->assertIsValidSitemap($expectedFile); + + $actual = trim(file_get_contents($expectedFile)); + $this->assertEquals($expected[$expectedFileNumber], $actual); + + unlink($expectedFile); + } + } }