From 428acd7e190e2427a8ee8dce724afc79b0ea249f Mon Sep 17 00:00:00 2001 From: Grzegorz Rajchman Date: Tue, 5 Dec 2023 12:51:35 +0000 Subject: [PATCH] PLT-71 Fix Undefined array key in remove triple (#145) --- src/classes/ExtendedGraph.class.php | 18 +++++++-- test/unit/ExtendedGraphTest.php | 62 +++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/src/classes/ExtendedGraph.class.php b/src/classes/ExtendedGraph.class.php index 69f0d17..fbb41d1 100644 --- a/src/classes/ExtendedGraph.class.php +++ b/src/classes/ExtendedGraph.class.php @@ -467,7 +467,7 @@ public function get_first_literal($s, $p, $default = null, $preferred_language = * @return string the first resource value found or the supplied default if no values were found */ public function get_first_resource($s, $p, $default = null) { - if ( array_key_exists($s, $this->_index) && array_key_exists($p, $this->_index[$s]) ) { + if (isset($this->_index[$s][$p])) { foreach ($this->_index[$s][$p] as $value) { if ($value['type'] == 'uri' || $value['type'] == 'bnode' ) { return $value['value']; @@ -483,7 +483,12 @@ public function get_first_resource($s, $p, $default = null) { * @param string $p the predicate URI of the triple * @param string $o the object of the triple, either a URI or a blank node in the format _:name */ - public function remove_resource_triple( $s, $p, $o) { + public function remove_resource_triple($s, $p, $o) { + // Already removed + if (!isset($this->_index[$s]) || !isset($this->_index[$s][$p])) { + return; + } + for ($i = count($this->_index[$s][$p]) - 1; $i >= 0; $i--) { if (($this->_index[$s][$p][$i]['type'] == 'uri' || $this->_index[$s][$p][$i]['type'] == 'bnode') && $this->_index[$s][$p][$i]['value'] == $o) { array_splice($this->_index[$s][$p], $i, 1); @@ -493,10 +498,10 @@ public function remove_resource_triple( $s, $p, $o) { if (count($this->_index[$s][$p]) == 0) { unset($this->_index[$s][$p]); } + if (count($this->_index[$s]) == 0) { unset($this->_index[$s]); } - } /** @@ -505,6 +510,11 @@ public function remove_resource_triple( $s, $p, $o) { * @param string $o */ public function remove_literal_triple($s, $p, $o) { + // Already removed + if (!isset($this->_index[$s]) || !isset($this->_index[$s][$p])) { + return; + } + for ($i = count($this->_index[$s][$p]) - 1; $i >= 0; $i--) { if ($this->_index[$s][$p][$i]['type'] == 'literal' && $this->_index[$s][$p][$i]['value'] == $o) { array_splice($this->_index[$s][$p], $i, 1); @@ -514,10 +524,10 @@ public function remove_literal_triple($s, $p, $o) { if (count($this->_index[$s][$p]) == 0) { unset($this->_index[$s][$p]); } + if (count($this->_index[$s]) == 0) { unset($this->_index[$s]); } - } /** diff --git a/test/unit/ExtendedGraphTest.php b/test/unit/ExtendedGraphTest.php index 742ee56..f22f875 100644 --- a/test/unit/ExtendedGraphTest.php +++ b/test/unit/ExtendedGraphTest.php @@ -208,6 +208,68 @@ public function testRemoveProperties() $this->assertFalse($graph->subject_has_property('http://some/subject/3','http://some/predicate/to/remove'), 'should have removed triple about subject 3'); } + public function testGetFirstResource() + { + $graph = new ExtendedGraph(); + + $graph->add_literal_triple('http://some/subject/1', 'http://some/predicate', 'value 1'); + $graph->add_resource_triple('http://some/subject/1', 'http://some/predicate', 'http://value/2'); + + $this->assertEquals('http://value/2', $graph->get_first_resource('http://some/subject/1', 'http://some/predicate'), 'should have returned first resource'); + $this->assertEquals(null, $graph->get_first_resource('http://some/subject/2', 'http://other/predicate'), 'should have returned default value'); + $this->assertEquals('my default', $graph->get_first_resource('http://some/subject/3', 'http://other/predicate', 'my default'), 'should have returned default value'); + } + + public function testRemoveResourceTriple() + { + $graph = new ExtendedGraph(); + + // Add some triples + $graph->add_resource_triple('http://some/subject/1', 'http://some/predicate', 'http://value/1'); + $graph->add_resource_triple('http://some/subject/2', 'http://some/predicate', 'http://value/2'); + $this->assertEquals(2, $graph->get_triple_count(), 'should have 2 triples'); + + // Try to remove triples that don't exist + $graph->remove_resource_triple('http://some/subject/3', 'http://some/predicate', 'http://value/3'); + $graph->remove_literal_triple('http://some/subject/3', 'http://some/predicate', 'value 3'); + $this->assertEquals(2, $graph->get_triple_count(), 'should have 2 triples'); + + // Remove a triple that does exist + $graph->remove_resource_triple('http://some/subject/1', 'http://some/predicate', 'http://value/1'); + $this->assertEquals(1, $graph->get_triple_count(), 'should have 1 triple'); + + // Remove the last triple + $graph->remove_resource_triple('http://some/subject/2', 'http://some/predicate', 'http://value/2'); + $this->assertEquals(0, $graph->get_triple_count(), 'should have 0 triples'); + $this->assertTrue($graph->is_empty(), 'should be empty'); + $this->assertEquals([], $graph->get_index(), 'should have empty index'); + } + + public function testRemoveLiteralTriple() + { + $graph = new ExtendedGraph(); + + // Add some triples + $graph->add_literal_triple('http://some/subject/1', 'http://some/predicate', 'value 1'); + $graph->add_literal_triple('http://some/subject/2', 'http://some/predicate', 'value 2'); + $this->assertEquals(2, $graph->get_triple_count(), 'should have 2 triples'); + + // Try to remove triples that don't exist + $graph->remove_literal_triple('http://some/subject/3', 'http://some/predicate', 'value 3'); + $graph->remove_resource_triple('http://some/subject/3', 'http://some/predicate', 'http://value/3'); + $this->assertEquals(2, $graph->get_triple_count(), 'should have 2 triples'); + + // Remove a triple that does exist + $graph->remove_literal_triple('http://some/subject/1', 'http://some/predicate', 'value 1'); + $this->assertEquals(1, $graph->get_triple_count(), 'should have 1 triple'); + + // Remove the last triple + $graph->remove_literal_triple('http://some/subject/2', 'http://some/predicate', 'value 2'); + $this->assertEquals(0, $graph->get_triple_count(), 'should have 0 triples'); + $this->assertTrue($graph->is_empty(), 'should be empty'); + $this->assertEquals([], $graph->get_index(), 'should have empty index'); + } + public function testGetResourceProperties() { $graph = new ExtendedGraph();