| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | declare(strict_types=1); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | namespace HexMakina\Marker; | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 5 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 6 |  |  | class Element | 
            
                                                                        
                            
            
                                    
            
            
                | 7 |  |  | { | 
            
                                                                        
                            
            
                                    
            
            
                | 8 |  |  |     /** | 
            
                                                                        
                            
            
                                    
            
            
                | 9 |  |  |      * @var string[] | 
            
                                                                        
                            
            
                                    
            
            
                | 10 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 11 |  |  |     public const VOID_ELEMENTS = [ | 
            
                                                                        
                            
            
                                    
            
            
                | 12 |  |  |       'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', | 
            
                                                                        
                            
            
                                    
            
            
                | 13 |  |  |       'link', 'meta', 'param', 'source', 'track', 'wbr' | 
            
                                                                        
                            
            
                                    
            
            
                | 14 |  |  |     ]; | 
            
                                                                        
                            
            
                                    
            
            
                | 15 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 16 |  |  |     /** | 
            
                                                                        
                            
            
                                    
            
            
                | 17 |  |  |      * @var string | 
            
                                                                        
                            
            
                                    
            
            
                | 18 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 19 |  |  |     public const FORMAT_VOID = '<%s%s/>'; | 
            
                                                                        
                            
            
                                    
            
            
                | 20 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 21 |  |  |     /** | 
            
                                                                        
                            
            
                                    
            
            
                | 22 |  |  |      * @var string | 
            
                                                                        
                            
            
                                    
            
            
                | 23 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 24 |  |  |     public const FORMAT_ELEMENT = '<%s%s>%s</%s>'; | 
            
                                                                        
                            
            
                                    
            
            
                | 25 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 26 |  |  |     /** | 
            
                                                                        
                            
            
                                    
            
            
                | 27 |  |  |      * @var string | 
            
                                                                        
                            
            
                                    
            
            
                | 28 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 29 |  |  |     public const FORMAT_ATTRIBUTES = '%s="%s"'; | 
            
                                                                        
                            
            
                                    
            
            
                | 30 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 31 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 32 |  |  |     protected string $tag; | 
            
                                                                        
                            
            
                                    
            
            
                | 33 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 34 |  |  |     protected array $attributes; | 
            
                                                                        
                            
            
                                    
            
            
                | 35 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 36 |  |  |     protected string $content; | 
            
                                                                        
                            
            
                                    
            
            
                | 37 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 38 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 39 |  |  |     /** | 
            
                                                                        
                            
            
                                    
            
            
                | 40 |  |  |      * ::span('inner text', ['class' => 'd-block']) | 
            
                                                                        
                            
            
                                    
            
            
                | 41 |  |  |      * ::p('lorem ipsum') | 
            
                                                                        
                            
            
                                    
            
            
                | 42 |  |  |      * ::img('alternative text', ['src' => 'path/to/img', 'width' => 100, 'height'=>100]) | 
            
                                                                        
                            
            
                                    
            
            
                | 43 |  |  |      * ::a('click here', ['href' => 'url/to/destination', 'class' => 'nav-link']) | 
            
                                                                        
                            
            
                                    
            
            
                | 44 |  |  |      * ::a('anchor title', ['name' => 'anchor_name']) | 
            
                                                                        
                            
            
                                    
            
            
                | 45 |  |  |      * | 
            
                                                                        
                            
            
                                    
            
            
                | 46 |  |  |      * @param mixed[] $arguments | 
            
                                                                        
                            
            
                                    
            
            
                | 47 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 48 |  |  |     public static function __callStatic(string $tag, array $arguments): Element | 
            
                                                                        
                            
            
                                    
            
            
                | 49 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 50 |  |  |         // first argument is the inner text | 
            
                                                                        
                            
            
                                    
            
            
                | 51 |  |  |         $inner_text = $arguments[0] ?? null; | 
            
                                                                        
                            
            
                                    
            
            
                | 52 |  |  |         // second argument, an array for HTML attributes | 
            
                                                                        
                            
            
                                    
            
            
                | 53 |  |  |         $attributes = $arguments[1] ?? []; | 
            
                                                                        
                            
            
                                    
            
            
                | 54 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 55 |  |  |         return new Element($tag, $inner_text, $attributes); | 
            
                                                                        
                            
            
                                    
            
            
                | 56 |  |  |     } | 
            
                                                                        
                            
            
                                    
            
            
                | 57 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 58 |  |  |     /** | 
            
                                                                        
                            
            
                                    
            
            
                | 59 |  |  |      * @param mixed[] $attributes | 
            
                                                                        
                            
            
                                    
            
            
                | 60 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |     public function __construct(string $tag, string $content = null, array $attributes = []) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |         $this->tag = $tag; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |         $this->content = $content ?? ''; | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 65 |  |  |         $this->attributes = $attributes; | 
            
                                                                        
                                                                
            
                                    
            
            
                | 66 |  |  |     } | 
            
                                                                        
                            
            
                                    
            
            
                | 67 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 68 |  |  |     public function __toString(): string | 
            
                                                                        
                            
            
                                    
            
            
                | 69 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 70 |  |  |         $attributes = self::attributesAsString($this->attributes); | 
            
                                                                        
                            
            
                                    
            
            
                | 71 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 72 |  |  |         if ($this->isVoid()) { | 
            
                                                                        
                            
            
                                    
            
            
                | 73 |  |  |             return sprintf( | 
            
                                                                        
                            
            
                                    
            
            
                | 74 |  |  |                 self::FORMAT_VOID, | 
            
                                                                        
                            
            
                                    
            
            
                | 75 |  |  |                 $this->tag, | 
            
                                                                        
                            
            
                                    
            
            
                | 76 |  |  |                 $attributes, | 
            
                                                                        
                            
            
                                    
            
            
                | 77 |  |  |             ); | 
            
                                                                        
                            
            
                                    
            
            
                | 78 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 79 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 80 |  |  |         return sprintf( | 
            
                                                                        
                            
            
                                    
            
            
                | 81 |  |  |             self::FORMAT_ELEMENT, | 
            
                                                                        
                            
            
                                    
            
            
                | 82 |  |  |             $this->tag, | 
            
                                                                        
                            
            
                                    
            
            
                | 83 |  |  |             $attributes, | 
            
                                                                        
                            
            
                                    
            
            
                | 84 |  |  |             $this->content, | 
            
                                                                        
                            
            
                                    
            
            
                | 85 |  |  |             $this->tag | 
            
                                                                        
                            
            
                                    
            
            
                | 86 |  |  |         ); | 
            
                                                                        
                            
            
                                    
            
            
                | 87 |  |  |     } | 
            
                                                                        
                            
            
                                    
            
            
                | 88 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 89 |  |  |     public function isVoid(): bool | 
            
                                                                        
                            
            
                                    
            
            
                | 90 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 91 |  |  |         return in_array($this->tag, self::VOID_ELEMENTS); | 
            
                                                                        
                            
            
                                    
            
            
                | 92 |  |  |     } | 
            
                                                                        
                            
            
                                    
            
            
                | 93 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 94 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |     private static function isBooleanAttribute($k): bool | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |     { | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 97 |  |  |         return is_int($k); | 
            
                                                                        
                                                                
            
                                    
            
            
                | 98 |  |  |     } | 
            
                                                                        
                                                                
            
                                    
            
            
                | 99 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 100 |  |  |     private static function isValidValue($v): bool | 
            
                                                                        
                            
            
                                    
            
            
                | 101 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 102 |  |  |         return !is_null($v) && $v != '' && !is_array($v); | 
            
                                                                        
                            
            
                                    
            
            
                | 103 |  |  |     } | 
            
                                                                        
                            
            
                                    
            
            
                | 104 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |     public static function attributesAsString(array $attributes = []): string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |         $ret = ''; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |         foreach ($attributes as $k => $v) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |             if (self::isValidValue($v)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |                 $ret .=  ' ' . (self::isBooleanAttribute($k) ? $v : sprintf(self::FORMAT_ATTRIBUTES, $k, $v)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |  | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 114 |  |  |         return $ret; | 
            
                                                                        
                                                                
            
                                    
            
            
                | 115 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 116 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 117 |  |  |  |