MediaWiki 1.43.1
dumpCategoriesAsRdf.php
Go to the documentation of this file.
1<?php
22use Wikimedia\Purtle\RdfWriter;
23use Wikimedia\Purtle\RdfWriterFactory;
25
26// @codeCoverageIgnoreStart
27require_once __DIR__ . '/Maintenance.php';
28// @codeCoverageIgnoreEnd
29
36class DumpCategoriesAsRdf extends Maintenance {
40 private $rdfWriter;
45 private $categoriesRdf;
46
47 public function __construct() {
48 parent::__construct();
49
50 $this->addDescription( "Generate RDF dump of categories in a wiki." );
51
52 $this->setBatchSize( 200 );
53 $this->addOption( 'output', "Output file (default is stdout). Will be overwritten.",
54 false, true );
55 $this->addOption( 'format', "Set the dump format.", false, true );
56 }
57
64 public function getCategoryIterator( IReadableDatabase $dbr, $fname ) {
65 $it = new BatchRowIterator(
66 $dbr,
67 [ 'page', 'page_props', 'category' ],
68 [ 'page_title' ],
69 $this->getBatchSize()
70 );
71 $it->addConditions( [
72 'page_namespace' => NS_CATEGORY,
73 ] );
74 $it->setFetchColumns( [
75 'page_title',
76 'page_id',
77 'pp_propname',
78 'cat_pages',
79 'cat_subcats',
80 'cat_files'
81 ] );
82 $it->addJoinConditions(
83 [
84 'page_props' => [
85 'LEFT JOIN', [ 'pp_propname' => 'hiddencat', 'pp_page = page_id' ]
86 ],
87 'category' => [
88 'LEFT JOIN', [ 'cat_title = page_title' ]
89 ]
90 ]
91
92 );
93 $it->setCaller( $fname );
94 return $it;
95 }
96
104 public function getCategoryLinksIterator( IReadableDatabase $dbr, array $ids, $fname ) {
105 $it = new BatchRowIterator(
106 $dbr,
107 'categorylinks',
108 [ 'cl_from', 'cl_to' ],
109 $this->getBatchSize()
110 );
111 $it->addConditions( [
112 'cl_type' => 'subcat',
113 'cl_from' => $ids
114 ] );
115 $it->setFetchColumns( [ 'cl_from', 'cl_to' ] );
116 $it->setCaller( $fname );
117 return new RecursiveIteratorIterator( $it );
118 }
119
123 public function addDumpHeader( $timestamp ) {
124 $licenseUrl = $this->getConfig()->get( MainConfigNames::RightsUrl );
125 if ( str_starts_with( $licenseUrl, '//' ) ) {
126 $licenseUrl = 'https:' . $licenseUrl;
127 }
128 $urlUtils = $this->getServiceContainer()->getUrlUtils();
129 $this->rdfWriter->about( $this->categoriesRdf->getDumpURI() )
130 ->a( 'schema', 'Dataset' )
131 ->a( 'owl', 'Ontology' )
132 ->say( 'cc', 'license' )->is( $licenseUrl )
133 ->say( 'schema', 'softwareVersion' )->value( CategoriesRdf::FORMAT_VERSION )
134 ->say( 'schema', 'dateModified' )
135 ->value( wfTimestamp( TS_ISO_8601, $timestamp ), 'xsd', 'dateTime' )
136 ->say( 'schema', 'isPartOf' )->is( (string)$urlUtils->expand( '/', PROTO_CANONICAL ) )
137 ->say( 'owl', 'imports' )->is( CategoriesRdf::OWL_URL );
138 }
139
140 public function execute() {
141 $outFile = $this->getOption( 'output', 'php://stdout' );
142
143 if ( $outFile === '-' ) {
144 $outFile = 'php://stdout';
145 }
146
147 $output = fopen( $outFile, 'w' );
148 $this->rdfWriter = $this->createRdfWriter( $this->getOption( 'format', 'ttl' ) );
149 $this->categoriesRdf = new CategoriesRdf( $this->rdfWriter );
150
151 $this->categoriesRdf->setupPrefixes();
152 $this->rdfWriter->start();
153
154 $this->addDumpHeader( time() );
155 fwrite( $output, $this->rdfWriter->drain() );
156
157 $dbr = $this->getDB( DB_REPLICA, [ 'vslow' ] );
158
159 foreach ( $this->getCategoryIterator( $dbr, __METHOD__ ) as $batch ) {
160 $pages = [];
161 foreach ( $batch as $row ) {
162 $this->categoriesRdf->writeCategoryData(
163 $row->page_title,
164 $row->pp_propname === 'hiddencat',
165 (int)$row->cat_pages - (int)$row->cat_subcats - (int)$row->cat_files,
166 (int)$row->cat_subcats
167 );
168 if ( $row->page_id ) {
169 $pages[$row->page_id] = $row->page_title;
170 }
171 }
172
173 foreach ( $this->getCategoryLinksIterator( $dbr, array_keys( $pages ), __METHOD__ ) as $row ) {
174 $this->categoriesRdf->writeCategoryLinkData( $pages[$row->cl_from], $row->cl_to );
175 }
176 fwrite( $output, $this->rdfWriter->drain() );
177 }
178 fflush( $output );
179 if ( $outFile !== '-' ) {
180 fclose( $output );
181 }
182 }
183
188 private function createRdfWriter( $format ) {
189 $factory = new RdfWriterFactory();
190 return $factory->getWriter( $factory->getFormatName( $format ) );
191 }
192}
193
194// @codeCoverageIgnoreStart
195$maintClass = DumpCategoriesAsRdf::class;
196require_once RUN_MAINTENANCE_IF_MAIN;
197// @codeCoverageIgnoreEnd
const PROTO_CANONICAL
Definition Defines.php:210
const NS_CATEGORY
Definition Defines.php:79
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Allows iterating a large number of rows in batches transparently.
Maintenance script to provide RDF representation of the category tree.
getCategoryLinksIterator(IReadableDatabase $dbr, array $ids, $fname)
Get iterator for links for categories.
getCategoryIterator(IReadableDatabase $dbr, $fname)
Produce row iterator for categories.
Helper class to produce RDF representation of categories.
A class containing constants representing the names of configuration variables.
A database connection without write operations.
const DB_REPLICA
Definition defines.php:26