diff --git a/.gitignore b/.gitignore
index 5e8a691..cfa689f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,12 @@
.DS_Store
composer.lock
+/test.php
+/docker-compose.yml
+/Dockerfile
+/test-2.php
+/sitemaps/
+/logs/
+/.config/
+/.phpunit.result.cache
+/sitemap.xml
diff --git a/.scrutinizer.yml b/.scrutinizer.yml
deleted file mode 100644
index e93aa2c..0000000
--- a/.scrutinizer.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-before_commands:
- - "composer install --prefer-source"
-
-filter:
- excluded_paths: [vendor/*, tests/*]
- paths: [src/*]
-
-tools:
- php_code_coverage: true
- php_sim: true
- php_pdepend: true
- php_analyzer: true
- php_code_coverage: true
-
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 23d335b..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-language: php
-php:
- - 5.4
- - 5.5
- - 5.6
- - hhvm
-
-before_script:
- - composer self-update
- - composer install --prefer-source --no-interaction --dev
-
-script: phpunit
-
-matrix:
- allow_failures:
- - php: 5.6
- - php: hhvm
- fast_finish: true
diff --git a/README.md b/README.md
index a87c8f6..fae832b 100644
--- a/README.md
+++ b/README.md
@@ -1,32 +1,22 @@
# Cartographer
-[](https://packagist.org/packages/tackk/cartographer)
-[](https://packagist.org/packages/tackk/cartographer)
-[](https://packagist.org/packages/tackk/cartographer)
+A sitemap generation tool for PHP following the [Sitemap Protocol v0.9](http://www.sitemaps.org/protocol.html), based on the work of Dan Horrigan ([tackk/cartographer](https://github.com/tackk/cartographer)).
-[](https://travis-ci.org/tackk/cartographer)
-[](https://scrutinizer-ci.com/g/tackk/cartographer/)
-[](https://scrutinizer-ci.com/g/tackk/cartographer/)
-
-A sitemap generation tool for PHP following the [Sitemap Protocol v0.9](http://www.sitemaps.org/protocol.html).
+This fork was originally created to address vulnerabilities arising from outdated dependencies and along the way became compatible with PHP 8, bringing the original features into the current context.
Cartographer can handle Sitemaps of any size. When generating sitemaps with more than 50,000
-entries (the limit), the sitemap becomes a "map of maps" (i.e. nested sitemaps).
-
-* **GitHub Repo:** [http://github.com/tackk/cartographer/](http://github.com/tackk/cartographer/)
-* **Documentation:** [http://tackk.github.io/cartographer/](http://tackk.github.io/cartographer/)
+entries, the sitemap becomes a "map of maps" (i.e. nested sitemaps).
## Supported PHP/HHVM Versions
-* **PHP:** >= 5.4 (including 5.6 beta1)
-* **HHVM:** >= 3.0.0
+* **PHP:** >= 8.0.2
## Installation
### Composer CLI
```
-composer require tackk/cartographer:1.0.*
+composer require creativefactoryrv/cartographer:1.*
```
### composer.json
@@ -34,7 +24,7 @@ composer require tackk/cartographer:1.0.*
``` json
{
"require": {
- "tackk/cartographer": "1.0.*"
+ "creativefactoryrv/cartographer": "1.*"
}
}
```
@@ -45,10 +35,10 @@ If you have a sitemap that is under 50,000 items, you can just use the Sitemap c
Generator.
``` php
-use Tackk\Cartographer\Sitemap;
-use Tackk\Cartographer\ChangeFrequency;
+use CreativeFactoryRV\Cartographer\ChangeFrequency;
+use CreativeFactoryRV\Cartographer\Sitemap;
-$sitemap = new Tackk\Cartographer\Sitemap();
+$sitemap = new Sitemap();
$sitemap->add('http://foo.com', '2005-01-02', ChangeFrequency::WEEKLY, 1.0);
$sitemap->add('http://foo.com/about', '2005-01-01');
@@ -83,7 +73,8 @@ echo $sitemap->toString();
If you want to build a Sitemap Index, separate from the Sitemap Generator, you can!
``` php
-$sitemapIndex = new Tackk\Cartographer\SitemapIndex();
+$sitemapIndex = new CreativeFactoryRV\Cartographer\SitemapIndex();
+
$sitemapIndex->add('http://foo.com/sitemaps/sitemap.1.xml', '2012-01-02');
$sitemapIndex->add('http://foo.com/sitemaps/sitemap.2.xml', '2012-01-02');
@@ -114,7 +105,7 @@ echo $sitemapIndex->toString();
## Sitemap Factory
The Sitemap Factory create Sitemaps and Sitemap Indexes and writes them to the Filesystem.
-Is is can be used to generate full Sitemaps with more than **50,000** URLs.
+It can be used to generate full Sitemaps with more than **50,000** URLs.
If more than one sitemap is generated, it will create a Sitemap Index automatically.
@@ -126,13 +117,14 @@ means you can write the sitemaps to Local Disk, S3, Dropbox, wherever you want.
``` php
setBaseUrl('http://foo.com/sitemaps/');
-// Returns the URL to the main Sitemap/Index file
-$mainSitemap = $sitemapFactory->createSitemap($urls);
+$entries = [
+ [
+ 'url' => 'http://example.com/page1',
+ 'lastmod' => '2023-04-01',
+ 'changefreq' => 'daily',
+ 'priority' => '1.0'
+ ],
+ [
+ 'url' => 'http://example.com/page2',
+ 'lastmod' => '2023-04-02',
+ 'changefreq' => 'weekly',
+ 'priority' => '0.8'
+ ],
+];
+
+$iterator = new ArrayIterator($entries);
+// Returns the URL to the main Sitemap/Index file
+$mainSitemap = $sitemapFactory->createSitemap($iterator);
```
### Return Value
@@ -186,7 +194,7 @@ $files = $sitemapFactory->getFilesCreated();
## Running Tests
-*This assumes you have ran `composer update`.*
+*This assumes you ran `composer update`.*
From the repository root, run:
diff --git a/composer.json b/composer.json
index 551fa04..444de96 100644
--- a/composer.json
+++ b/composer.json
@@ -1,28 +1,36 @@
{
- "name": "tackk/cartographer",
- "description": "A PHP sitemap generation tool.",
+ "name": "creativefactoryrv/cartographer",
+ "description": "A powerful yet user-friendly PHP sitemap generator designed to create large, comprehensive sitemaps.",
+ "version": "1.1.3",
"keywords": ["sitemap", "generator"],
"license": "MIT",
"authors": [
{
"name": "Dan Horrigan",
"email": "dh@tackk.com"
+ },
+ {
+ "name": "Daniele ViganĂ²"
}
],
- "minimum-stability": "dev",
+ "minimum-stability": "stable",
"require-dev": {
- "phpunit/phpunit": "4.0.*"
+ "phpunit/phpunit": "11.4.*"
},
"require": {
- "php": ">=5.4",
- "league/flysystem": "1.0.*"
+ "php": "^8.0.2",
+ "league/flysystem": "3.*",
+ "ext-dom": "*"
},
"autoload": {
"files": [
"src/functions.php"
],
"psr-4": {
- "Tackk\\Cartographer\\": "src/"
+ "CreativeFactoryRV\\Cartographer\\": "src/"
}
+ },
+ "extra": {
+ "note": "This fork includes modifications by Daniele ViganĂ² to address a vulnerability caused by using an outdated version of League\\Flysystem as of 28/10/2024, based on the original work by Dan Horrigan."
}
}
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 480a1c8..4fd63d1 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,18 +1,19 @@
-
+
tests
-
-
+
+
+
./vendor
-
-
-
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/AbstractSitemap.php b/src/AbstractSitemap.php
index e8964c2..d73fe98 100644
--- a/src/AbstractSitemap.php
+++ b/src/AbstractSitemap.php
@@ -1,21 +1,15 @@
document = new DOMDocument($this->xmlVersion, $this->xmlEncoding);
$this->rootNode = $this->document->createElementNS($this->xmlNamespaceUri, $this->getRootNodeName());
@@ -80,14 +73,12 @@ public function __construct()
/**
* Freeze the sitemap, and append the rootNode to the document.
*/
- public function freeze()
- {
+ public function freeze() {
$this->document->appendChild($this->rootNode);
$this->isFrozen = true;
}
- public function isFrozen()
- {
+ public function isFrozen() {
return $this->isFrozen;
}
@@ -95,8 +86,7 @@ public function isFrozen()
* Gets the number of Urls in the sitemap.
* @return int
*/
- public function getUrlCount()
- {
+ public function getUrlCount() {
return $this->urlCount;
}
@@ -104,8 +94,7 @@ public function getUrlCount()
* Checks if the sitemap contains the maximum URL count.
* @return bool
*/
- public function hasMaxUrlCount()
- {
+ public function hasMaxUrlCount() {
return $this->urlCount === static::MAX_URLS;
}
@@ -113,18 +102,16 @@ public function hasMaxUrlCount()
* Converts the Sitemap to an XML string.
* @return string
*/
- public function toString()
- {
- return (string) $this;
+ public function toString() {
+ return (string)$this;
}
/**
* Converts the Sitemap to an XML string.
* @return string
*/
- public function __toString()
- {
- if (!$this->isFrozen()) {
+ public function __toString() {
+ if ( !$this->isFrozen() ) {
$this->freeze();
}
@@ -133,20 +120,19 @@ public function __toString()
/**
* Adds a URL to the document with the given array of elements.
- * @param array $urlArray
+ * @param array $urlArray
* @return $this
* @throws MaxUrlCountExceededException
*/
- protected function addUrlToDocument(array $urlArray)
- {
- if ($this->hasMaxUrlCount()) {
+ protected function addUrlToDocument(array $urlArray) {
+ if ( $this->hasMaxUrlCount() ) {
throw new MaxUrlCountExceededException('Maximum number of URLs has been reached, cannot add more.');
}
$node = $this->document->createElement($this->getNodeName());
- foreach ($urlArray as $key => $value) {
- if (is_null($value)) {
+ foreach ( $urlArray as $key => $value ) {
+ if ( is_null($value) ) {
continue;
}
$node->appendChild(new DOMElement($key, $value));
@@ -159,35 +145,47 @@ protected function addUrlToDocument(array $urlArray)
/**
* Escapes a string so it can be inserted into the Sitemap
- * @param string $string The string to escape.
+ * @param string $string The string to escape.
* @return string
*/
- protected function escapeString($string)
- {
- $from = ['&', '\'', '"', '>', '<'];
- $to = ['&', ''', '"', '>', '<'];
+ protected function escapeString($string) {
+ $from = [
+ '&',
+ '\'',
+ '"',
+ '>',
+ '<'
+ ];
+ $to = [
+ '&',
+ ''',
+ '"',
+ '>',
+ '<'
+ ];
return str_replace($from, $to, $string);
}
/**
* Takes a date as a string (or int in the case of a unix timestamp).
- * @param string $dateString
+ * @param string $dateString
* @return string
* @throws InvalidArgumentException
*/
- protected function formatDate($dateString)
- {
+ protected function formatDate($dateString) {
try {
// We have to handle timestamps a little differently
- if (is_numeric($dateString) && (int) $dateString == $dateString) {
- $date = DateTime::createFromFormat('U', (int) $dateString, new DateTimeZone('UTC'));
- } else {
+ if ( is_numeric($dateString) && (int)$dateString == $dateString ) {
+ $date = DateTime::createFromFormat('U', (int)$dateString, new DateTimeZone('UTC'));
+ }
+ else {
$date = new DateTime($dateString, new DateTimeZone('UTC'));
}
return $date->format(DateTime::W3C);
- } catch (\Exception $e) {
+ }
+ catch (\Exception $e) {
throw new InvalidArgumentException("Malformed last modified date: {$dateString}", 0, $e);
}
}
diff --git a/src/ChangeFrequency.php b/src/ChangeFrequency.php
index c83a665..319b3f5 100644
--- a/src/ChangeFrequency.php
+++ b/src/ChangeFrequency.php
@@ -1,6 +1,6 @@
filesystem = $filesystem;
}
/**
* Gets the Filesystem.
- * @return FilesystemInterface
+ * @return FilesystemOperator
*/
public function getFilesystem()
{
@@ -184,7 +184,7 @@ protected function parseEntry($entry)
*/
protected function randomHash()
{
- return md5($this->randomBytes(32));
+ return md5(random_bytes(32));
}
/**
@@ -196,22 +196,4 @@ protected function fileUrl($file)
{
return $this->baseUrl.'/'.ltrim($file, '/');
}
-
- /**
- * Generates a string of random bytes (of given length).
- * @param integer $bytes The number of bytes to return.
- * @throws \RuntimeException
- * @return string
- * @codeCoverageIgnore
- */
- protected function randomBytes($bytes = 32)
- {
- if (extension_loaded('openssl')) {
- return openssl_random_pseudo_bytes($bytes);
- } elseif (extension_loaded('mcrypt')) {
- return mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM);
- }
-
- throw new RuntimeException('Extension "openssl" or "mcrypt" is required, but is not installed.');
- }
}
diff --git a/src/SitemapIndex.php b/src/SitemapIndex.php
index 6bf0061..d254ef5 100644
--- a/src/SitemapIndex.php
+++ b/src/SitemapIndex.php
@@ -1,6 +1,6 @@
abstractMock = new MockAbstractSitemap();
}
@@ -41,7 +42,7 @@ public function testFormatDateWithUnixTimestamp()
public function testFormatDateWithInvalidDate()
{
- $this->setExpectedException('InvalidArgumentException');
+ $this->expectException(\InvalidArgumentException::class);
$this->callProtectedMethod('formatDate', ['foo']);
}
@@ -71,7 +72,7 @@ public function testMaxUrlCount()
$urlCount->setAccessible(true);
$urlCount->setValue($this->abstractMock, AbstractSitemap::MAX_URLS);
- $this->setExpectedException('Tackk\Cartographer\MaxUrlCountExceededException');
+ $this->expectException(MaxUrlCountExceededException::class);
$this->callProtectedMethod('addUrlToDocument', [['loc' => 'http://foo.com']]);
}
diff --git a/tests/FunctionsTest.php b/tests/FunctionsTest.php
index 5179fbf..6f3443d 100644
--- a/tests/FunctionsTest.php
+++ b/tests/FunctionsTest.php
@@ -1,9 +1,9 @@
setExpectedException('InvalidArgumentException',
- 'Invalid type: string, Expected type(s): array, object, ArrayAccess');
+ $this->expectException(InvalidArgumentException::class);
Cartographer\get_property('foo', 'foo');
}
@@ -45,8 +44,7 @@ public function testCheckTypePasses()
public function testCheckTypeFails()
{
- $this->setExpectedException('InvalidArgumentException',
- 'Invalid type: ArrayObject, Expected type(s): array');
+ $this->expectException(InvalidArgumentException::class);
Cartographer\checktype(new ArrayObject(), ['array']);
}
}
diff --git a/tests/SitemapFactoryTest.php b/tests/SitemapFactoryTest.php
index 0e06375..42e14a1 100644
--- a/tests/SitemapFactoryTest.php
+++ b/tests/SitemapFactoryTest.php
@@ -1,47 +1,38 @@
filesystem = new Filesystem($adapter);
- $this->factory = new Tackk\Cartographer\SitemapFactory($this->filesystem);
+ $this->factory = new CreativeFactoryRV\Cartographer\SitemapFactory($this->filesystem);
}
- public function testCanInstantiate()
- {
- $this->assertInstanceOf('Tackk\Cartographer\SitemapFactory', $this->factory);
+ public function testCanInstantiate() {
+ $this->assertInstanceOf(SitemapFactory::class, $this->factory);
}
- public function testGetFilesystem()
- {
- $this->assertInstanceOf('League\Flysystem\FilesystemInterface', $this->factory->getFilesystem());
+ public function testGetFilesystem() {
+ $this->assertInstanceOf(FilesystemOperator::class, $this->factory->getFilesystem());
}
- public function testSetBaseUrl()
- {
+ public function testSetBaseUrl() {
$this->factory->setBaseUrl('foo/');
- $this->assertAttributeEquals('foo', 'baseUrl', $this->factory);
+ $this->assertEquals('foo', $this->factory->getBaseUrl());
$this->factory->setBaseUrl('foo');
- $this->assertAttributeEquals('foo', 'baseUrl', $this->factory);
+ $this->assertEquals('foo', $this->factory->getBaseUrl());
}
- public function testGetBaseUrl()
- {
+ public function testGetBaseUrl() {
$class = new ReflectionClass($this->factory);
$baseUrl = $class->getProperty('baseUrl');
$baseUrl->setAccessible(true);
@@ -50,8 +41,7 @@ public function testGetBaseUrl()
$this->assertEquals('foo', $this->factory->getBaseUrl());
}
- public function testGetFileCreated()
- {
+ public function testGetFileCreated() {
$class = new ReflectionClass($this->factory);
$filesCreated = $class->getProperty('filesCreated');
$filesCreated->setAccessible(true);
@@ -60,14 +50,12 @@ public function testGetFileCreated()
$this->assertEquals(['foo.txt'], $this->factory->getFilesCreated());
}
- public function testCreateRequiresIterator()
- {
- $this->setExpectedException('PHPUnit_Framework_Error');
+ public function testCreateRequiresIterator() {
+ $this->expectException(ArgumentCountError::class);
$this->factory->createSitemap();
}
- public function testCanCreateSmallSitemap()
- {
+ public function testCanCreateSmallSitemap() {
$expected = <<
@@ -84,8 +72,8 @@ public function testCanCreateSmallSitemap()
XML;
$urls = [];
- for ($i = 1; $i <= 3; $i++) {
- $urls[] = ['url' => 'http://foo.com/'.$i];
+ for ( $i = 1; $i <= 3; $i++ ) {
+ $urls[] = ['url' => 'http://foo.com/' . $i];
}
$path = $this->factory->createSitemap(new ArrayIterator($urls));
@@ -94,24 +82,23 @@ public function testCanCreateSmallSitemap()
$this->assertEquals($expected, $actual);
}
- public function testLargeSitemapCreatesIndex()
- {
+ public function testLargeSitemapCreatesIndex() {
$urls = [];
- for ($i = 1; $i <= 50002; $i++) {
- $urls[] = ['url' => 'http://foo.com/'.$i];
+ for ( $i = 1; $i <= 50002; $i++ ) {
+ $urls[] = ['url' => 'http://foo.com/' . $i];
}
$path = $this->factory->createSitemap(new ArrayIterator($urls));
$this->assertTrue($this->filesystem->has($path));
- foreach ($this->factory->getFilesCreated() as $file) {
+ foreach ( $this->factory->getFilesCreated() as $file ) {
$this->assertTrue($this->filesystem->has($file));
$this->filesystem->delete($file);
}
}
- public function testUrlMustBePresent()
- {
- $this->setExpectedException('InvalidArgumentException', 'Url is missing or not accessible.');
+ public function testUrlMustBePresent() {
+ $this->expectException(InvalidArgumentException::class);
+ $this->expectExceptionMessage('Url is missing or not accessible.');
$this->factory->createSitemap(new ArrayIterator([[]]));
}
}
diff --git a/tests/SitemapIndexTest.php b/tests/SitemapIndexTest.php
index 62cc3e2..114b095 100644
--- a/tests/SitemapIndexTest.php
+++ b/tests/SitemapIndexTest.php
@@ -1,6 +1,6 @@
XML;
- $sitemapIndex = new Tackk\Cartographer\SitemapIndex();
+ $sitemapIndex = new CreativeFactoryRV\Cartographer\SitemapIndex();
$sitemapIndex->add('http://foo.com/sitemaps/sitemap.1.xml', '2012-01-02');
$sitemapIndex->add('http://foo.com/sitemaps/sitemap.2.xml', '2012-01-02');
$this->assertEquals($expected, $sitemapIndex->toString());
diff --git a/tests/SitemapTest.php b/tests/SitemapTest.php
index 7f64980..bde08b3 100644
--- a/tests/SitemapTest.php
+++ b/tests/SitemapTest.php
@@ -1,8 +1,8 @@