ImportOntosaur::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Colligator\Console\Commands;
4
5
use Colligator\Genre;
6
use Colligator\Ontosaur;
7
use Colligator\Subject;
8
use EasyRdf\Graph;
9
use EasyRdf\Resource;
10
use Illuminate\Console\Command;
11
12
class ImportOntosaur extends Command
13
{
14
    /**
15
     * The name and signature of the console command.
16
     *
17
     * @var string
18
     */
19
    protected $signature = 'colligator:import-ontosaur
20
                            {--url=https://dl.dropboxusercontent.com/u/1007809/42/ont42.rdf : URL to the RDF file}';
21
22
    /**
23
     * The console command description.
24
     *
25
     * @var string
26
     */
27
    protected $description = 'Import Ontosaur from RDF file.';
28
29
    /**
30
     * Create a new command instance.
31
     */
32
    public function __construct()
33
    {
34
        parent::__construct();
35
    }
36
37
    /**
38
     * @param Resource $res
39
     *
40
     * @return array
41
     */
42
    public function getLabels(Resource $res)
43
    {
44
        $languages = ['en', 'nb'];
45
46
        $spl = explode('#', $res->getUri());
47
48
        // TODO: Remove this when all nodes have labels in the RDF file
49
        //$defaultLabel = (count($spl) > 1) ? '[' . $spl[1] . ']' : '(no label)';
50
        $defaultLabel = (count($spl) > 1) ? ucfirst(str_replace('_', ' ', $spl[1])) : '(no label)';
51
52
        $labels = [];
53
        foreach ($res->all('skos:prefLabel') as $label) {
54
            $labels[$label->getLang()] = $label->getValue();
55
        }
56
        foreach ($languages as $lang) {
57
            $lab = array_get($labels, $lang);
58
            $labels[$lang] = empty($lab) ? $defaultLabel : $lab;
59
        }
60
61
        return $labels;
62
    }
63
64
    /**
65
     * @param Resource $res
66
     *
67
     * @return array
68
     */
69
    public function getNode(Resource $res)
70
    {
71
        $labels = $this->getLabels($res);
72
73
        $node = [
74
            'label_nb'       => $labels['nb'],
75
            'label_en'       => $labels['en'],
76
            'id'             => $res->getUri(),
77
            'local_id'       => null,
78
            'documents'      => null,
79
            'document_count' => 0,
80
        ];
81
82
        $entity = Subject::where('term', '=', $labels['nb'])->where('vocabulary', '=', 'noubomn')->first();
83
        $field = 'subjects';
84
        if (is_null($entity)) {
85
            $field = 'genres';
86
            $entity = Genre::where('term', '=', $labels['nb'])->where('vocabulary', '=', 'noubomn')->first();
87
            if (is_null($entity)) {
88
                $this->error('[ImportOntosaur] Entity not found: "' . $labels['nb'] . '"');
89
            }
90
        }
91
        if (!is_null($entity)) {
92
            $node['local_id'] = $entity->id;
93
            $node['documents'] = action('DocumentsController@index', [
94
                'q' => $field . '.noubomn.id:' . $entity->id,
95
            ]);
96
            // Can be used e.g. to determine bubble size in a visualization
97
            $node['document_count'] = $entity->documents()->count();
98
        }
99
100
        return $node;
101
    }
102
103
    /**
104
     * @param Resource $res
105
     *
106
     * @return array
107
     */
108
    public function getLinks(Resource $res)
109
    {
110
        $links = [];
111
        foreach ($res->all('skos:broader') as $broader) {
112
            $links[] = [
113
                'source' => $broader->getUri(),
114
                'target' => $res->getUri(),
115
            ];
116
        }
117
118
        return $links;
119
    }
120
121
    /**
122
     * Get arrays of nodes and links from an RDF graph.
123
     *
124
     * @param $graph
125
     *
126
     * @throws \Exception
127
     *
128
     * @return array
129
     */
130
    public function getNetwork(Graph $graph)
131
    {
132
        $nodes = [];
133
        $links = [];
134
        $topNodes = [];
135
136
        foreach ($graph->resources() as $res) {
137
            if (in_array('skos:Concept', $res->types())) {
138
                $nodes[] = $this->getNode($res);
139
                $nodeLinks = $this->getLinks($res);
140
                if (!count($nodeLinks)) {
141
                    $topNodes[] = $res->getUri();
142
                }
143
                $links = array_merge($links, $nodeLinks);
144
            }
145
        }
146
147
        if (count($topNodes) != 1) {
148
            throw new \Exception('Found ' . count($topNodes) . ' topnodes rather than 1: ' . implode(', ', $topNodes));
149
        }
150
151
        return [$nodes, $links, $topNodes[0]];
152
    }
153
154
    /**
155
     * Execute the console command.
156
     *
157
     * @return mixed
158
     */
159
    public function handle()
160
    {
161
        $url = $this->option('url');
162
        $graph = Graph::newAndLoad($url);
0 ignored issues
show
Bug introduced by
It seems like $url defined by $this->option('url') on line 161 can also be of type array or null; however, EasyRdf\Graph::newAndLoad() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
163
        list($nodes, $links, $topnode) = $this->getNetwork($graph);
164
165
        $saur = Ontosaur::firstOrNew(['url' => $url]);
166
        $saur->nodes = $nodes;
167
        $saur->links = $links;
168
        $saur->topnode = $topnode;
169
        $saur->save();
170
        $this->info('[ImportOntosaur] Completed. Have ' . count($nodes) . ' nodes, ' . count($links) . ' links.');
171
    }
172
}
173