1<?php 2/** 3 * Copyright (c) 2021. ComboStrap, Inc. and its affiliates. All Rights Reserved. 4 * 5 * This source code is licensed under the GPL license found in the 6 * COPYING file in the root directory of this source tree. 7 * 8 * @license GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html) 9 * @author ComboStrap <support@combostrap.com> 10 * 11 */ 12 13namespace ComboStrap; 14 15 16class Snippet 17{ 18 /** 19 * The head in css format 20 * We need to add the style node 21 */ 22 const TYPE_CSS = "css"; 23 24 /** 25 * The snippet is attached to a bar (main, sidebar, ...) or to the page (request) 26 */ 27 const SCOPE_BAR = "bar"; 28 const SCOPE_PAGE = "page"; 29 /** 30 * The head in javascript 31 * We need to wrap it in a script node 32 */ 33 const TYPE_JS = "js"; 34 /** 35 * A tag head in array format 36 * No need 37 */ 38 const TAG_TYPE = "tag"; 39 40 private $snippetId; 41 private $scope; 42 private $type; 43 44 /** 45 * @var bool 46 */ 47 private $critical = false; 48 49 /** 50 * @var string the text script / style (may be null if it's an external resources) 51 */ 52 private $content; 53 /** 54 * @var array 55 */ 56 private $headsTags; 57 58 /** 59 * Snippet constructor. 60 */ 61 public function __construct($snippetId, $snippetType) 62 { 63 $this->snippetId = $snippetId; 64 $this->type = $snippetType; 65 if ($this->type == self::TYPE_CSS) { 66 // All CSS should be loaded first 67 // The CSS animation / background can set this to false 68 $this->critical = true; 69 } 70 } 71 72 public static function createJavascriptSnippet($snippetId) 73 { 74 return new Snippet($snippetId,self::TYPE_JS); 75 } 76 77 public static function createCssSnippet($snippetId) 78 { 79 return new Snippet($snippetId,self::TYPE_CSS); 80 } 81 82 /** 83 * @deprecated You should create a snippet with a known type, this constructor was created for refactoring 84 * @param $snippetId 85 * @return Snippet 86 */ 87 public static function createUnknownSnippet($snippetId) 88 { 89 return new Snippet($snippetId,"unknwon"); 90 } 91 92 93 /** 94 * @param $bool - if the snippet is critical, it would not be deferred or preloaded 95 * @return Snippet for chaining 96 * All css that are for animation or background for instance 97 * should not be set as critical as they are not needed to paint 98 * exactly the page 99 */ 100 public function setCritical($bool) 101 { 102 $this->critical = $bool; 103 return $this; 104 } 105 106 /** 107 * @param $content - Set an inline content for a script or stylesheet 108 * @return Snippet for chaining 109 */ 110 public function setContent($content) 111 { 112 $this->content = $content; 113 return $this; 114 } 115 116 /** 117 * @return string 118 */ 119 public function getContent() 120 { 121 if ($this->content == null) { 122 switch ($this->type) { 123 case self::TYPE_CSS: 124 $this->content = $this->getCssRulesFromFile($this->snippetId); 125 break; 126 case self::TYPE_JS: 127 $this->content = $this->getJavascriptContentFromFile($this->snippetId); 128 break; 129 default: 130 LogUtility::msg("The snippet ($this) has no content", LogUtility::LVL_MSG_ERROR, "support"); 131 } 132 } 133 return $this->content; 134 } 135 136 /** 137 * @param $tagName 138 * @return false|string - the css content of the css file 139 */ 140 private function getCssRulesFromFile($tagName) 141 { 142 143 $path = Resources::getSnippetResourceDirectory() . "/style/" . strtolower($tagName) . ".css"; 144 if (file_exists($path)) { 145 return file_get_contents($path); 146 } else { 147 LogUtility::msg("The css file ($path) was not found", LogUtility::LVL_MSG_WARNING, $tagName); 148 return ""; 149 } 150 151 } 152 153 /** 154 * @param $tagName - the tag name 155 * @return false|string - the specific javascript content for the tag 156 */ 157 private function getJavascriptContentFromFile($tagName) 158 { 159 160 $path = Resources::getSnippetResourceDirectory() . "/js/" . strtolower($tagName) . ".js"; 161 if (file_exists($path)) { 162 return file_get_contents($path); 163 } else { 164 LogUtility::msg("The javascript file ($path) was not found", LogUtility::LVL_MSG_WARNING, $tagName); 165 return ""; 166 } 167 168 } 169 170 public function __toString() 171 { 172 return $this->snippetId."-".$this->type; 173 } 174 175 /** 176 * Set all tags at once. 177 * @param array $tags 178 * @return Snippet 179 */ 180 public function setTags(array $tags) 181 { 182 $this->headsTags = $tags; 183 return $this; 184 } 185 186 public function getTags() 187 { 188 return $this->headsTags; 189 } 190 191 public function getCritical() 192 { 193 return $this->critical; 194 } 195 196 public function getClass() 197 { 198 /** 199 * The class for the snippet is just to be able to identify them 200 * 201 * The `snippet` prefix was added to be sure that the class 202 * name will not conflict with a css class 203 * Example: if you set the class to `combo-list` 204 * and that you use it in a inline `style` tag with 205 * the same class name, the inline `style` tag is not applied 206 * 207 */ 208 return "snippet-" . $this->snippetId . "-" . SnippetManager::COMBO_CLASS_SUFFIX; 209 210 } 211 212 /** 213 * @return string the HTML of the tag (works for now only with CSS content) 214 */ 215 public function getHtmlStyleTag() 216 { 217 $content = $this->getContent(); 218 $class = $this->getClass(); 219 return <<<EOF 220<style class="$class"> 221$content 222</style> 223EOF; 224 225 } 226 227 public function getId() 228 { 229 return $this->snippetId; 230 } 231 232 233} 234