MediaWiki  master
PagePropsTable.php
Go to the documentation of this file.
1 <?php
2 
4 
6 use JobQueueGroup;
9 use ParserOutput;
10 
20 class PagePropsTable extends LinksTable {
22  private $jobQueueGroup;
23 
25  private $newProps = [];
26 
28  private $existingProps;
29 
38  private $linkInvalidations;
39 
41 
42  public function __construct(
43  ServiceOptions $options,
44  JobQueueGroup $jobQueueGroup
45  ) {
46  $this->jobQueueGroup = $jobQueueGroup;
47  $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
48  $this->linkInvalidations = $options->get( MainConfigNames::PagePropLinkInvalidations );
49  }
50 
51  public function setParserOutput( ParserOutput $parserOutput ) {
52  $this->newProps = $parserOutput->getPageProperties();
53  }
54 
55  protected function getTableName() {
56  return 'page_props';
57  }
58 
59  protected function getFromField() {
60  return 'pp_page';
61  }
62 
63  protected function getExistingFields() {
64  return [ 'pp_propname', 'pp_value' ];
65  }
66 
67  protected function getNewLinkIDs() {
68  foreach ( $this->newProps as $name => $value ) {
69  yield [ (string)$name, $value ];
70  }
71  }
72 
78  private function getExistingProps() {
79  if ( $this->existingProps === null ) {
80  $this->existingProps = [];
81  foreach ( $this->fetchExistingRows() as $row ) {
82  $this->existingProps[$row->pp_propname] = $row->pp_value;
83  }
84  }
85  return $this->existingProps;
86  }
87 
88  protected function getExistingLinkIDs() {
89  foreach ( $this->getExistingProps() as $name => $value ) {
90  yield [ (string)$name, $value ];
91  }
92  }
93 
94  protected function isExisting( $linkId ) {
95  $existing = $this->getExistingProps();
96  [ $name, $value ] = $linkId;
97  return \array_key_exists( $name, $existing )
98  && $this->encodeValue( $existing[$name] ) === $this->encodeValue( $value );
99  }
100 
101  protected function isInNewSet( $linkId ) {
102  [ $name, $value ] = $linkId;
103  return \array_key_exists( $name, $this->newProps )
104  && $this->encodeValue( $this->newProps[$name] ) === $this->encodeValue( $value );
105  }
106 
107  private function encodeValue( $value ) {
108  if ( is_bool( $value ) ) {
109  return (string)(int)$value;
110  } elseif ( $value === null ) {
111  return '';
112  } else {
113  return (string)$value;
114  }
115  }
116 
117  protected function insertLink( $linkId ) {
118  [ $name, $value ] = $linkId;
119  $this->insertRow( [
120  'pp_propname' => $name,
121  'pp_value' => $this->encodeValue( $value ),
122  'pp_sortkey' => $this->getPropertySortKeyValue( $value )
123  ] );
124  }
125 
138  private function getPropertySortKeyValue( $value ) {
139  if ( is_int( $value ) || is_float( $value ) || is_bool( $value ) ) {
140  return floatval( $value );
141  }
142 
143  return null;
144  }
145 
146  protected function deleteLink( $linkId ) {
147  $this->deleteRow( [
148  'pp_propname' => $linkId[0]
149  ] );
150  }
151 
152  protected function finishUpdate() {
153  $changed = array_unique( array_merge(
154  array_column( $this->insertedLinks, 0 ),
155  array_column( $this->deletedLinks, 0 ) ) );
156  $this->invalidateProperties( $changed );
157  }
158 
164  private function invalidateProperties( array $changed ) {
165  $jobs = [];
166  foreach ( $changed as $name ) {
167  if ( isset( $this->linkInvalidations[$name] ) ) {
168  $inv = $this->linkInvalidations[$name];
169  if ( !is_array( $inv ) ) {
170  $inv = [ $inv ];
171  }
172  foreach ( $inv as $table ) {
174  $this->getSourcePage(),
175  $table,
176  [ 'causeAction' => 'page-props' ]
177  );
178  }
179  }
180  }
181 
182  if ( $jobs ) {
183  $this->jobQueueGroup->lazyPush( $jobs );
184  }
185  }
186 
193  public function getAssocArray( $setType ) {
194  $props = [];
195  foreach ( $this->getLinkIDs( $setType ) as $linkId ) {
196  [ $name, $value ] = $linkId;
197  $props[$name] = $value;
198  }
199  return $props;
200  }
201 }
Job to purge the HTML/file cache for all pages that link to or use another page or file.
static newForBacklinks(PageReference $page, $table, $params=[])
Class to handle enqueueing of background jobs.
A class for passing options to services.
assertRequiredOptions(array $expectedKeys)
Assert that the list of options provided in this instance exactly match $expectedKeys,...
The base class for classes which update a single link table.
Definition: LinksTable.php:41
insertRow( $row)
Queue a row for insertion.
Definition: LinksTable.php:407
fetchExistingRows()
Do a select query to fetch the existing rows.
Definition: LinksTable.php:369
getSourcePage()
Get the source page, i.e.
Definition: LinksTable.php:292
getLinkIDs( $setType)
Get an array or iterator of link IDs of a given type.
Definition: LinksTable.php:522
deleteRow( $conds)
Queue a deletion operation.
Definition: LinksTable.php:422
finishUpdate()
Subclasses can override this to do any updates associated with their link data, for example dispatchi...
getFromField()
Get the name of the field which links to page_id.
getExistingFields()
Get the fields to be used in fetchExistingRows().
insertLink( $linkId)
Insert a link identified by ID.
isExisting( $linkId)
Determine whether a link (from the new set) is in the existing set.
deleteLink( $linkId)
Delete a link identified by ID.
getExistingLinkIDs()
Get an array (or iterator) of link IDs for the existing state.
__construct(ServiceOptions $options, JobQueueGroup $jobQueueGroup)
setParserOutput(ParserOutput $parserOutput)
Subclasses should implement this to extract the data they need from the ParserOutput.
getAssocArray( $setType)
Get the properties for a given link set as an associative array.
getNewLinkIDs()
Get an array (or iterator) of link IDs for the new state.
isInNewSet( $linkId)
Determine whether a link (from the existing set) is in the new set.
A class containing constants representing the names of configuration variables.
const PagePropLinkInvalidations
Name constant for the PagePropLinkInvalidations setting, for use with Config::get()
getPageProperties()
Return all the page properties set on this ParserOutput.