Skip to content

Problem: SKOS import fatals with "Call to a member function getValue() on null" when skos:related points at a concept that was not imported #2417

Closed as not planned

Description

@johanpiet2

Current Behavior

sfSkosPlugin::importGraph() runs two passes that disagree about which concepts exist, and the mismatch is fatal.

Pass one imports concepts and stamps each with atom:id:

$concepts = $this->getRootConcepts();
foreach ($concepts as $item) {
    ... 
    $this->addConcept($item, $this->parent->id);
}   

addConcept() sets the stamp and recurses through skos:narrower only:

$concept->set('atom:id', (int) $term->id);

foreach ($concept->allResources('skos:narrower') as $item) {
    $this->addConcept($item, $term->id);
}   

Pass two walks every concept in the graph and dereferences that stamp on both ends of every skos:related, unguarded (line 113):

foreach ($this->graph->allOfType('skos:Concept') as $c) {
    foreach ($c->allResources('skos:related') as $r) {
        $relations->insert($c->get('atom:id')->getValue(), $r->get('atom:id')->getValue());
    }   
}   

Pass one visits only what is reachable from a root via skos:narrower; pass two visits everything. Any concept in the second set but not the first has no atom:id, get() returns null, and getValue() is a fatal.

getRootConcepts() is what makes this easy to hit:

$conceptScheme = $this->graph->get('skos:ConceptScheme', '^rdf:type');
if (null !== $conceptScheme) {
    $topConcepts = $conceptScheme->allResources('skos:hasTopConcept');
    if (0 < count($topConcepts)) {
        return $topConcepts;
    }   
}   

return $this->graph->allOfType('skos:Concept');

### Expected Behavior

1. Save this as sample.ttl:

turtle
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix ex:   <http://example.org/> .

ex:scheme a skos:ConceptScheme ;
    skos:hasTopConcept ex:a .
    
ex:a a skos:Concept ;
    skos:prefLabel "Imported"@en ;
    skos:related ex:b .
    
ex:b a skos:Concept ;
    skos:prefLabel "Never imported"@en .
    
2. Import it into any taxonomy (Manage > Taxonomies > Import, or the XML import).
3. ex:a is created, then the job ends in Error.

ex:b is a skos:Concept, so pass two sees it; it is neither a top concept nor skos:narrower of one, so pass one never stamps it.

Job report from the original report (a 10-concept Places file):

[info] Importing SKOS file: sample_skos.ttl
[info] Type of scheme: file 
[info] Taxonomy: Places
[info] Term ID: 110
[info] The graph contains 10 concepts.
[err]  Exception: Call to a member function getValue() on null
[err]  File: plugins/sfSkosPlugin/lib/sfSkosPlugin.class.php
[err]  Line: 113

**Expected Behavior**

```markdown
The import completes, creating the concepts it can and skipping only the relation it cannot express — with a line in the job log naming the concepts involved, so the cataloguer can see what was dropped and why.

A `skos:related` naming a concept outside the imported set is ordinary, valid SKOS. It should not be able to end the run.

Two things make the current behaviour worse than a simple failure:

- **The partial import persists.** Terms created before the fatal are already saved, so a re-run duplicates them and the file cannot simply be re-imported after a fix.
- **The error names no concept.** It reports a file and a line, so there is nothing to point the cataloguer at in a 10-concept file, let alone a large vocabulary. 

### Possible Solution

```php
foreach ($this->graph->allOfType('skos:Concept') as $c) {
    foreach ($c->allResources('skos:related') as $r) {
        $subject = $c->get('atom:id');
        $object = $r->get('atom:id');
        
        if (null === $subject || null === $object) {
            $this->logger->info($this->i18n->__(
                'Skipping skos:related between %1% and %2%: one of them was not imported.',
                ['%1%' => $c->getUri(), '%2%' => $r->getUri()]
            )); 
            
            continue;
        }   
        
        $relations->insert($subject->getValue(), $object->getValue());
    }   
}   

### Context and Notes

AtoM 2.10.1 and 2.10.2 (plugins/sfSkosPlugin/lib/sfSkosPlugin.class.php:113, unchanged between the two). PHP 8.3, MySQL 8, nginx, Ubuntu 22.04.



### Version used

2.10.1

### Operating System and version

22.04

### Default installation culture

en

### PHP version

8.3

### Contact details

johan@theahg.co.za

Activity

  1. added
    Type: bugA flaw in the code that causes the software to produce an incorrect or unexpected result.
    on Aug 25, 2026
  2. johanpiet2 commented on Oct 2, 2026

    @johanpiet2
    Author

    Duplicate of #2418, filed twice by mistake.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type: bugA flaw in the code that causes the software to produce an incorrect or unexpected result.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions