155 public function setCookie( $name, $value, $expire = 0, $options = [] ) {
157 $mainConfig = $services->getMainConfig();
164 $options = array_filter( $options,
static function ( $a ) {
167 'prefix' => $cookiePrefix,
168 'domain' => $cookieDomain,
169 'path' => $cookiePath,
170 'secure' => $cookieSecure,
171 'httpOnly' => $cookieHttpOnly,
176 if ( $expire ===
null ) {
178 } elseif ( $expire == 0 && $cookieExpiration != 0 ) {
179 $expire = time() + $cookieExpiration;
183 $prefixedName = $options[
'prefix'] . $name;
184 wfDebugLog(
'cookie',
'ignored post-send cookie {cookie}',
'all', [
185 'cookie' => $prefixedName,
187 'name' => $prefixedName,
188 'value' => (
string)$value,
189 'expire' => (
int)$expire,
190 'path' => (
string)$options[
'path'],
191 'domain' => (
string)$options[
'domain'],
192 'secure' => (
bool)$options[
'secure'],
193 'httpOnly' => (
bool)$options[
'httpOnly'],
194 'sameSite' => (
string)$options[
'sameSite']
196 'exception' =>
new RuntimeException(
'Ignored post-send cookie' ),
201 $hookRunner =
new HookRunner( $services->getHookContainer() );
202 if ( !$hookRunner->onWebResponseSetCookie( $name, $value, $expire, $options ) ) {
208 $prefixedName = $options[
'prefix'] . $name;
209 $value = (string)$value;
210 $func = $options[
'raw'] ?
'setrawcookie' :
'setcookie';
212 'expires' => (int)$expire,
213 'path' => (
string)$options[
'path'],
214 'domain' => (string)$options[
'domain'],
215 'secure' => (
bool)$options[
'secure'],
216 'httponly' => (bool)$options[
'httpOnly'],
217 'samesite' => (
string)$options[
'sameSite'],
221 $key =
"{$prefixedName}\n{$setOptions['domain']}\n{$setOptions['path']}";
225 if ( isset( $_COOKIE[$prefixedName] ) && !array_key_exists( $key, self::$setCookies ) ) {
226 self::$setCookies[$key] = [];
230 $deleting = ( $value ===
'' || ( $setOptions[
'expires'] > 0 && $setOptions[
'expires'] <= time() ) );
232 $logDesc =
"$func: \"$prefixedName\", \"$value\", \"" .
233 implode(
'", "', array_map(
'strval', $setOptions ) ) .
'"';
234 $optionsForDeduplication = [ $func, $prefixedName, $value, $setOptions ];
236 if ( $deleting && !isset( self::$setCookies[$key] ) ) {
237 wfDebugLog(
'cookie',
"already deleted $logDesc" );
239 } elseif ( !$deleting && isset( self::$setCookies[$key] ) &&
240 self::$setCookies[$key] === $optionsForDeduplication
242 wfDebugLog(
'cookie',
"already set $logDesc" );
247 if ( $func ===
'setrawcookie' ) {
248 setrawcookie( $prefixedName, $value, $setOptions );
250 setcookie( $prefixedName, $value, $setOptions );
252 self::$setCookies[$key] = $deleting ? null : $optionsForDeduplication;