Localisation updates from https://translatewiki.net.
[mediawiki.git] / includes / edit / SimpleParsoidOutputStash.php
blob0b53caf9b82a955afd49c238574968ca74681ea4
1 <?php
3 namespace MediaWiki\Edit;
5 use MediaWiki\Content\IContentHandlerFactory;
6 use Wikimedia\ObjectCache\BagOStuff;
7 use Wikimedia\Parsoid\Core\PageBundle;
9 /**
10 * @internal
11 * @since 1.39
13 class SimpleParsoidOutputStash implements ParsoidOutputStash {
15 /** @var BagOStuff */
16 private $bagOfStuff;
18 /** @var int */
19 private $duration;
21 /** @var IContentHandlerFactory */
22 private $contentHandlerFactory;
24 /**
25 * @param IContentHandlerFactory $contentHandlerFactory
26 * @param BagOStuff $bagOfStuff storage backend
27 * @param int $duration cache duration in seconds
29 public function __construct( IContentHandlerFactory $contentHandlerFactory, BagOStuff $bagOfStuff, int $duration ) {
30 $this->bagOfStuff = $bagOfStuff;
31 $this->duration = $duration;
32 $this->contentHandlerFactory = $contentHandlerFactory;
35 private function makeCacheKey( ParsoidRenderID $renderId ): string {
36 return $this->bagOfStuff->makeKey( 'ParsoidOutputStash', $renderId->getKey() );
39 /**
40 * Before we stash, we serialize & encode into JSON the relevant
41 * parts of the data we need to construct a page bundle in the future.
43 * @param ParsoidRenderID $renderId Combination of revision ID and revision's time ID
44 * @param SelserContext $selserContext
46 * @return bool
48 public function set( ParsoidRenderID $renderId, SelserContext $selserContext ): bool {
49 $jsonic = $this->selserContextToJsonArray( $selserContext );
51 $key = $this->makeCacheKey( $renderId );
52 return $this->bagOfStuff->set( $key, $jsonic, $this->duration );
55 /**
56 * This will decode the JSON data and create a page bundle from it
57 * if we have something in the stash that matches a given rendering or
58 * will just return an empty array if no entry in the stash.
60 * @param ParsoidRenderID $renderId
62 * @return SelserContext|null
64 public function get( ParsoidRenderID $renderId ): ?SelserContext {
65 $key = $this->makeCacheKey( $renderId );
66 $jsonic = $this->bagOfStuff->get( $key ) ?? [];
68 if ( !is_array( $jsonic ) ) {
69 // Defend against old stashed data.
70 // Only needed for a couple of days after this code has been deployed.
71 return null;
74 $selserContext = $this->newSelserContextFromJson( $jsonic );
75 return $selserContext ?: null;
78 private function newSelserContextFromJson( array $json ): ?SelserContext {
79 if ( !isset( $json['pb'] ) ) {
80 return null;
83 // TODO: should use proper JsonCodec for this
84 $pb = PageBundle::newFromJsonArray( $json['pb'] );
86 $revId = (int)$json['revId'];
88 if ( isset( $json['content'] ) ) {
89 $contentHandler = $this->contentHandlerFactory->getContentHandler( $json['content']['model'] );
90 $content = $contentHandler->unserializeContent( $json['content']['data'] );
91 } else {
92 $content = null;
95 return new SelserContext( $pb, $revId, $content );
98 private function selserContextToJsonArray( SelserContext $selserContext ): array {
99 $json = [
100 'revId' => $selserContext->getRevisionID(),
103 // TODO: should use proper JsonCodec for this
104 $json['pb'] = $selserContext->getPageBundle()->toJsonArray();
106 $content = $selserContext->getContent();
107 if ( $content ) {
108 $json['content'] = [
109 'model' => $content->getModel(),
110 'data' => $content->serialize()
114 return $json;