diff --git a/data/no-dbf.shp b/data/no-dbf.shp index e69de29..aa19d09 100644 Binary files a/data/no-dbf.shp and b/data/no-dbf.shp differ diff --git a/src/ShapeFile.php b/src/ShapeFile.php index cd13f70..8f87b12 100644 --- a/src/ShapeFile.php +++ b/src/ShapeFile.php @@ -87,6 +87,9 @@ class ShapeFile /** @var array */ public $records = []; + /** @var bool */ + private $allowNoDbf = false; + /** * Checks whether dbase manipulations are supported. */ @@ -121,6 +124,11 @@ public function __construct( $this->fileLength = 50; } + public function setAllowNoDbf(bool $allowNoDbf): void + { + $this->allowNoDbf = $allowNoDbf; + } + /** * Loads shapefile and dbase (if supported). * @@ -326,8 +334,16 @@ public function getIndexFromDBFData(string $field, $value): int */ private function loadDBFHeader(): array { - $DBFFile = fopen($this->getFilename('.dbf'), 'r'); + if (! self::supportsDbase()) { + return []; + } + $dbfName = $this->getFilename('.dbf'); + if (! file_exists($dbfName)) { + return []; + } + + $DBFFile = fopen($dbfName, 'r'); $result = []; $i = 1; $inHeader = true; @@ -405,9 +421,7 @@ private function loadHeaders(): bool $this->boundingBox['mmin'] = Util::loadData('d', $this->readSHP(8)); $this->boundingBox['mmax'] = Util::loadData('d', $this->readSHP(8)); - if (self::supportsDbase()) { - $this->dbfHeader = $this->loadDBFHeader(); - } + $this->dbfHeader = $this->loadDBFHeader(); return true; } @@ -620,6 +634,10 @@ private function openDBFFile(): bool $dbfName = $this->getFilename('.dbf'); if (! is_readable($dbfName)) { + if ($this->allowNoDbf) { + return true; + } + $this->setError(sprintf('It wasn\'t possible to find the DBase file "%s"', $dbfName)); return false; diff --git a/tests/ShapeFileTest.php b/tests/ShapeFileTest.php index 505825b..35c0e4b 100644 --- a/tests/ShapeFileTest.php +++ b/tests/ShapeFileTest.php @@ -548,4 +548,15 @@ public function testSearch(): void $shp->getIndexFromDBFData('CNTRY_NAME', 'Czech Republic') ); } + + public function testAllowsNoDbf(): void + { + if (! ShapeFile::supportsDbase()) { + self::markTestSkipped(); + } + + $shp = new ShapeFile(0); + $shp->setAllowNoDbf(true); + self::assertTrue($shp->loadFromFile('data/no-dbf.*')); + } }