MediaWiki  master
MetadataStorageHelper.php
Go to the documentation of this file.
1 <?php
23 
32  private $repo;
33 
34  public function __construct( LocalRepo $repo ) {
35  $this->repo = $repo;
36  }
37 
46  public function getJsonMetadata( $file, $envelope ) {
47  // Try encoding
48  $s = $this->jsonEncode( $envelope );
49 
50  // Decide whether to try splitting the metadata.
51  // Return early if it's not going to happen.
52  if ( !$this->repo->isSplitMetadataEnabled()
53  || !$file->getHandler()
54  || !$file->getHandler()->useSplitMetadata()
55  ) {
56  return [ $s, [] ];
57  }
58  $threshold = $this->repo->getSplitMetadataThreshold();
59  if ( !$threshold || strlen( $s ) <= $threshold ) {
60  return [ $s, [] ];
61  }
62  $blobStore = $this->repo->getBlobStore();
63  if ( !$blobStore ) {
64  return [ $s, [] ];
65  }
66 
67  // The data as a whole is above the item threshold. Look for
68  // large items that can be split out.
69  $blobAddresses = [];
70  foreach ( $envelope['data'] as $name => $value ) {
71  $encoded = $this->jsonEncode( $value );
72  if ( strlen( $encoded ) > $threshold ) {
73  $blobAddresses[$name] = $blobStore->storeBlob(
74  $encoded,
75  [ BlobStore::IMAGE_HINT => $file->getName() ]
76  );
77  }
78  }
79  // Remove any items that were split out
80  $envelope['data'] = array_diff_key( $envelope['data'], $blobAddresses );
81  $envelope['blobs'] = $blobAddresses;
82  $s = $this->jsonEncode( $envelope );
83 
84  return [ $s, $blobAddresses ];
85  }
86 
95  public function jsonEncode( $data ): string {
96  $s = json_encode( $data,
97  JSON_INVALID_UTF8_IGNORE |
98  JSON_UNESCAPED_SLASHES |
99  JSON_UNESCAPED_UNICODE );
100  if ( $s === false ) {
101  throw new MWException( __METHOD__ . ': metadata is not JSON-serializable ' );
102  }
103  return $s;
104  }
105 
110  public function getMetadataFromBlobStore( array $addresses ): array {
111  $result = [];
112  if ( $addresses ) {
113  $blobStore = $this->repo->getBlobStore();
114  if ( !$blobStore ) {
115  LoggerFactory::getInstance( 'LocalFile' )->warning(
116  "Unable to load metadata: repo has no blob store" );
117  return $result;
118  }
119  $status = $blobStore->getBlobBatch( $addresses );
120  if ( !$status->isGood() ) {
121  $msg = Status::wrap( $status )->getWikiText(
122  false, false, 'en' );
123  LoggerFactory::getInstance( 'LocalFile' )->warning(
124  "Error loading metadata from BlobStore: $msg" );
125  }
126  foreach ( $addresses as $itemName => $address ) {
127  $json = $status->getValue()[$address] ?? null;
128  if ( $json !== null ) {
129  $value = $this->jsonDecode( $json );
130  $result[$itemName] = $value;
131  }
132  }
133  }
134  return $result;
135  }
136 
148  public function jsonDecode( string $s ) {
149  // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
150  return @json_decode( $s, true, 512, JSON_INVALID_UTF8_IGNORE );
151  }
152 
153 }
Local repository that stores files in the local filesystem and registers them in the wiki's own datab...
Definition: LocalRepo.php:39
MediaWiki exception.
Definition: MWException.php:29
PSR-3 logger instance factory.
Helper for storage of metadata.
jsonEncode( $data)
Do JSON encoding with local flags.
getJsonMetadata( $file, $envelope)
Get metadata in JSON format ready for DB insertion, optionally splitting items out to BlobStore.
jsonDecode(string $s)
Do JSON decoding with local flags.
getMetadataFromBlobStore(array $addresses)
static wrap( $sv)
Succinct helper method to wrap a StatusValue.
Definition: Status.php:62
Service for loading and storing data blobs.
Definition: BlobStore.php:35
foreach( $mmfl['setupFiles'] as $fileName) if( $queue) if(empty( $mmfl['quiet'])) $s
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42