1<?php 2 3 4namespace ComboStrap; 5 6 7class Brand 8{ 9 10 const NEWSLETTER_BRAND_NAME = "newsletter"; 11 const EMAIL_BRAND_NAME = "email"; 12 13 14 /** 15 * The brand of the current application/website 16 */ 17 public const CURRENT_BRAND = "current"; 18 const CANONICAL = "brand"; 19 const ABBR_PROPERTY = 'abbr'; 20 /** 21 * @var array an array of brand abbreviation as key and their name as value 22 */ 23 private static array $BRAND_ABBR; 24 25 26 private $secondaryColor; 27 private $brandUrl; 28 29 /** 30 * @var array 31 */ 32 public static array $brandDictionary; 33 /** 34 * @var bool 35 */ 36 private bool $unknown = false; 37 /** 38 * @var mixed 39 */ 40 private $brandDict; 41 42 43 /** 44 * Brand constructor. 45 * @param string $name 46 */ 47 private function __construct(string $name) 48 { 49 50 $this->name = $name; 51 52 /** 53 * Get the brands 54 */ 55 $brandDictionary = Brand::getBrandDictionary(); 56 57 58 /** 59 * Build the data for the brand 60 */ 61 $this->brandDict = $brandDictionary[$this->name]; 62 switch ($this->name) { 63 case self::CURRENT_BRAND: 64 $this->brandUrl = Site::getBaseUrl(); 65 $secondaryColor = Site::getSecondaryColor(); 66 if ($secondaryColor !== null) { 67 // the predicates on the secondary value is to avoid a loop with the the function below 68 $this->secondaryColor = $secondaryColor->toCssValue(); 69 } 70 break; 71 default: 72 if ($this->brandDict !== null) { 73 $this->secondaryColor = $this->brandDict["colors"]["secondary"]; 74 $this->brandUrl = $this->brandDict["url"]; 75 return; 76 } 77 $this->unknown = true; 78 break; 79 } 80 81 } 82 83 /** 84 * @return string[] 85 */ 86 public static function getAllKnownBrandNames(): array 87 { 88 89 $brands = self::getAllBrands(); 90 $brandNames = [self::CURRENT_BRAND]; 91 foreach ($brands as $brand) { 92 $brandNames[] = $brand->getName(); 93 try { 94 $brandNames[] = $brand->getAbbr(); 95 } catch (ExceptionNotFound $e) { 96 // ok 97 } 98 } 99 return $brandNames; 100 101 } 102 103 104 /** 105 * @return Brand[] 106 */ 107 public static function getAllBrands(): array 108 { 109 $brandDictionary = self::getBrandDictionary(); 110 $brands = []; 111 foreach (array_keys($brandDictionary) as $brandName) { 112 $brands[] = self::create($brandName); 113 } 114 return $brands; 115 } 116 117 /** 118 * @param $type - the button type (ie one of {@link BrandButton::TYPE_BUTTONS} 119 * @return array - the brand names that can be used as type in the brand button 120 */ 121 public static function getBrandNamesForButtonType($type): array 122 { 123 $brands = self::getAllBrands(); 124 $brandNamesForType = []; 125 foreach ($brands as $brand) { 126 if ($brand->supportButtonType($type)) { 127 $brandNamesForType[] = $brand->getName(); 128 try { 129 $brandNamesForType[] = $brand->getAbbr(); 130 } catch (ExceptionNotFound $e) { 131 // ok 132 } 133 } 134 } 135 return $brandNamesForType; 136 } 137 138 /** 139 * 140 */ 141 public static function getBrandDictionary(): array 142 { 143 if (!isset(Brand::$brandDictionary)) { 144 try { 145 Brand::$brandDictionary = Dictionary::getFrom("brands"); 146 } catch (ExceptionCompile $e) { 147 // Should never happens 148 Brand::$brandDictionary = []; 149 LogUtility::error("We can't load the brands dictionary. Error: " . $e->getMessage(), self::CANONICAL, $e); 150 } 151 } 152 return Brand::$brandDictionary; 153 } 154 155 156 /** 157 * @var string 158 * The name of the brand, 159 * for company, we follow the naming of 160 * https://github.com/ellisonleao/sharer.js 161 */ 162 private $name; 163 164 165 public static function create(string $brandName): Brand 166 { 167 168 $brandNameQualified = strtolower($brandName); 169 $brandNameQualified = Brand::getBrandNameFromAbbr($brandNameQualified); 170 $objectIdentifier = self::CANONICAL . "-" . $brandNameQualified; 171 $executionContext = ExecutionContext::getActualOrCreateFromEnv(); 172 try { 173 return $executionContext->getRuntimeObject($objectIdentifier); 174 } catch (ExceptionNotFound $e) { 175 $brandObject = new Brand($brandNameQualified); 176 $executionContext->setRuntimeObject($objectIdentifier, $brandObject); 177 return $brandObject; 178 } 179 180 } 181 182 private static function getBrandNameFromAbbr(string $name) 183 { 184 if (!isset(self::$BRAND_ABBR)) { 185 $brandDictionary = self::getBrandDictionary(); 186 foreach ($brandDictionary as $brandName => $brandProperties) { 187 $abbr = $brandProperties[self::ABBR_PROPERTY]; 188 if (empty($abbr)) { 189 continue; 190 } 191 self::$BRAND_ABBR[$abbr] = $brandName; 192 } 193 } 194 if (isset(self::$BRAND_ABBR[$name])) { 195 return self::$BRAND_ABBR[$name]; 196 } 197 return $name; 198 199 } 200 201 202 /** 203 * If the brand name is unknown (ie custom) 204 * @return bool 205 */ 206 public function isUnknown(): bool 207 { 208 return $this->unknown; 209 210 } 211 212 public function getName(): string 213 { 214 return $this->name; 215 } 216 217 public function __toString() 218 { 219 if ($this->name === Brand::CURRENT_BRAND) { 220 return $this->name . " (" . Site::getTitle() . ")"; 221 } 222 return $this->name; 223 } 224 225 /** 226 * Shared/Follow Url template 227 * the endpoint template url (for sharing and following) 228 * @var string $type - the type of button 229 */ 230 public function getWebUrlTemplate(string $type): ?string 231 { 232 if (isset($this->brandDict[$type])) { 233 return $this->brandDict[$type]["web"]; 234 } 235 return null; 236 } 237 238 /** 239 * Brand button title 240 * @return string 241 * @var ?string $type - the button type 242 */ 243 public function getTitle(string $type = null): ?string 244 { 245 if ($this->name === self::CURRENT_BRAND) { 246 return Site::getTitle(); 247 } 248 if ($this->brandDict !== null && $type !== null) { 249 if (isset($this->brandDict[$type])) { 250 return $this->brandDict[$type]["popup"]; 251 } 252 } 253 return null; 254 255 } 256 257 public function getPrimaryColor(): ?string 258 { 259 260 if ($this->brandDict !== null) { 261 $primaryColor = $this->brandDict["colors"]["primary"]; 262 if ($primaryColor !== null) { 263 return $primaryColor; 264 } 265 } 266 267 // Unknown or current brand / unknown color 268 try { 269 return ExecutionContext::getExecutionContext() 270 ->getConfig() 271 ->getPrimaryColor(); 272 } catch (ExceptionNotFound $e) { 273 return null; 274 } 275 276 } 277 278 public function getSecondaryColor(): ?string 279 { 280 return $this->secondaryColor; 281 } 282 283 /** 284 * @param string|null $type - the button type 285 * @return string|null 286 */ 287 public function getIconName(?string $type): ?string 288 { 289 290 switch ($this->name) { 291 case self::CURRENT_BRAND: 292 try { 293 return Site::getLogoAsSvgImage() 294 ->getWikiId(); 295 } catch (ExceptionNotFound $e) { 296 // no logo installed 297 } 298 break; 299 default: 300 if (isset($this->brandDict["icons"])) { 301 return $this->brandDict["icons"][$type]; 302 } 303 break; 304 } 305 306 return null; 307 } 308 309 public function getBrandUrl(): ?string 310 { 311 return $this->brandUrl; 312 } 313 314 /** 315 */ 316 public function supportButtonType(string $type): bool 317 { 318 switch ($type) { 319 case BrandButton::TYPE_BUTTON_SHARE: 320 case BrandButton::TYPE_BUTTON_FOLLOW: 321 if ($this->getWebUrlTemplate($type) !== null) { 322 return true; 323 } 324 return false; 325 default: 326 case BrandButton::TYPE_BUTTON_BRAND: 327 return true; 328 } 329 } 330 331 /** 332 * @throws ExceptionNotFound 333 */ 334 private function getAbbr() 335 { 336 $value = $this->brandDict['abbr']; 337 if (empty($value)) { 338 throw new ExceptionNotFound("No abbreviations"); 339 } 340 return $value; 341 } 342 343 344} 345