1<?php 2 3namespace OOUI; 4 5/** 6 * Element with named flags that can be added, removed, listed and checked. 7 * 8 * A flag, when set, adds a CSS class on the `$element` by combining `oo-ui-flaggedElement-` with 9 * the flag name. Flags are primarily useful for styling. 10 * 11 * @abstract 12 */ 13trait FlaggedElement { 14 /** 15 * Flags. 16 * 17 * @var bool[] 18 * @phan-var array<string,bool> 19 */ 20 protected $flags = []; 21 22 /** 23 * @var Element 24 */ 25 protected $flagged; 26 27 /** 28 * @param array $config Configuration options 29 * - string|string[] $config['flags'] Flags describing importance and functionality, e.g. 30 * 'primary', 'safe', 'progressive', or 'destructive'. 31 */ 32 public function initializeFlaggedElement( array $config = [] ) { 33 // Properties 34 $this->flagged = $config['flagged'] ?? $this; 35 36 // Initialization 37 $this->setFlags( $config['flags'] ?? null ); 38 39 $this->registerConfigCallback( function ( &$config ) { 40 if ( !empty( $this->flags ) ) { 41 $config['flags'] = $this->getFlags(); 42 } 43 } ); 44 } 45 46 /** 47 * Check if a flag is set. 48 * 49 * @param string $flag Name of flag 50 * @return bool Has flag 51 */ 52 public function hasFlag( $flag ) { 53 return isset( $this->flags[$flag] ); 54 } 55 56 /** 57 * Get the names of all flags set. 58 * 59 * @return string[] Flag names 60 */ 61 public function getFlags() { 62 return array_keys( $this->flags ); 63 } 64 65 /** 66 * Clear all flags. 67 * 68 * @return $this 69 */ 70 public function clearFlags() { 71 $remove = []; 72 $classPrefix = 'oo-ui-flaggedElement-'; 73 74 foreach ( $this->flags as $flag => $value ) { 75 $remove[] = $classPrefix . $flag; 76 } 77 78 $this->flagged->removeClasses( $remove ); 79 $this->flags = []; 80 81 return $this; 82 } 83 84 /** 85 * Add one or more flags. 86 * 87 * @param string|array $flags One or more flags to add, or an array keyed by flag name 88 * containing boolean set/remove instructions. 89 * @return $this 90 */ 91 public function setFlags( $flags ) { 92 $add = []; 93 $remove = []; 94 $classPrefix = 'oo-ui-flaggedElement-'; 95 96 if ( is_string( $flags ) ) { 97 // Set 98 if ( !isset( $this->flags[$flags] ) ) { 99 $this->flags[$flags] = true; 100 $add[] = $classPrefix . $flags; 101 } 102 } elseif ( is_array( $flags ) ) { 103 foreach ( $flags as $key => $value ) { 104 if ( is_numeric( $key ) ) { 105 // Set 106 if ( !isset( $this->flags[$value] ) ) { 107 $this->flags[$value] = true; 108 $add[] = $classPrefix . $value; 109 } 110 } else { 111 if ( $value ) { 112 // Set 113 if ( !isset( $this->flags[$key] ) ) { 114 $this->flags[$key] = true; 115 $add[] = $classPrefix . $key; 116 } 117 } else { 118 // Remove 119 if ( isset( $this->flags[$key] ) ) { 120 unset( $this->flags[$key] ); 121 $remove[] = $classPrefix . $key; 122 } 123 } 124 } 125 } 126 } 127 128 $this->flagged 129 ->addClasses( $add ) 130 ->removeClasses( $remove ); 131 132 return $this; 133 } 134} 135