MediaWiki  master
LessVarFileModule.php
Go to the documentation of this file.
1 <?php
20 namespace MediaWiki\ResourceLoader;
21 
22 use Wikimedia\Minify\CSSMin;
23 
24 // Per https://phabricator.wikimedia.org/T241091
25 // phpcs:disable MediaWiki.Commenting.FunctionAnnotations.UnrecognizedAnnotation
26 
34  protected $lessVariables = [];
35 
39  public function __construct(
40  array $options = [],
41  $localBasePath = null,
42  $remoteBasePath = null
43  ) {
44  if ( isset( $options['lessMessages'] ) ) {
45  $this->lessVariables = $options['lessMessages'];
46  }
47  parent::__construct( $options, $localBasePath, $remoteBasePath );
48  }
49 
53  public function getMessages() {
54  // Overload so MessageBlobStore can detect updates to messages and purge as needed.
55  return array_merge( $this->messages, $this->lessVariables );
56  }
57 
65  private function pluckFromMessageBlob( $blob, array $allowed ): array {
66  $data = $blob ? json_decode( $blob, true ) : [];
67  // Keep only the messages intended for LESS export
68  // (opposite of getMessages essentially).
69  return array_intersect_key( $data, array_fill_keys( $allowed, true ) );
70  }
71 
75  protected function getMessageBlob( Context $context ) {
76  $blob = parent::getMessageBlob( $context );
77  if ( !$blob ) {
78  // If module has no blob, preserve null to avoid needless WAN cache allocation
79  // client output for modules without messages.
80  return $blob;
81  }
82  return json_encode( (object)$this->pluckFromMessageBlob( $blob, $this->messages ) );
83  }
84 
85  // phpcs:disable MediaWiki.Commenting.DocComment.SpacingDocTag, Squiz.WhiteSpace.FunctionSpacing.Before
106  private static function wrapAndEscapeMessage( $msg ) {
107  return str_replace( "'", "\'", CSSMin::serializeStringValue( $msg ) );
108  }
109 
110  // phpcs:enable MediaWiki.Commenting.DocComment.SpacingDocTag, Squiz.WhiteSpace.FunctionSpacing.Before
111 
118  protected function getLessVars( Context $context ) {
119  $vars = parent::getLessVars( $context );
120 
121  $blob = parent::getMessageBlob( $context );
122  $messages = $this->pluckFromMessageBlob( $blob, $this->lessVariables );
123 
124  // It is important that we iterate the declared list from $this->lessVariables,
125  // and not $messages since in the case of undefined messages, the key is
126  // omitted entirely from the blob. This emits a log warning for developers,
127  // but we must still carry on and produce a valid LESS variable declaration,
128  // to avoid a LESS syntax error (T267785).
129  foreach ( $this->lessVariables as $msgKey ) {
130  $vars['msg-' . $msgKey] = self::wrapAndEscapeMessage( $messages[$msgKey] ?? "⧼{$msgKey}⧽" );
131  }
132 
133  return $vars;
134  }
135 }
136 
138 class_alias( LessVarFileModule::class, 'ResourceLoaderLessVarFileModule' );
Context object that contains information about the state of a specific ResourceLoader web request.
Definition: Context.php:46
Module based on local JavaScript/CSS files.
Definition: FileModule.php:53
string $remoteBasePath
Remote base path, see __construct()
Definition: FileModule.php:58
string $localBasePath
Local base path, see __construct()
Definition: FileModule.php:55
Module augmented with context-specific LESS variables.
getMessageBlob(Context $context)
Get the hash of the message blob.Stability: stableto override 1.27 string|null JSON blob or null if m...
__construct(array $options=[], $localBasePath=null, $remoteBasePath=null)
getMessages()
Get message keys used by this module.string[] List of message keys
getLessVars(Context $context)
Get language-specific LESS variables for this module.
return true
Definition: router.php:90