xref: /plugin/combo/ComboStrap/Brand.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
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