|
| 1 | +<?php |
| 2 | + |
| 3 | +namespace JBBCode; |
| 4 | + |
| 5 | +/** |
| 6 | + * This class represents a BBCode Definition. You may construct instances of this class directly, |
| 7 | + * usually through the CodeDefinitionBuilder class, to create text replacement bbcodes, or you |
| 8 | + * may subclass it to create more complex bbcode definitions. |
| 9 | + * |
| 10 | + * @author jbowens |
| 11 | + */ |
| 12 | +class CodeDefinition |
| 13 | +{ |
| 14 | + /* NOTE: THIS PROPERTY SHOULD ALWAYS BE LOWERCASE; USE setTagName() TO ENSURE THIS */ |
| 15 | + protected $tagName; |
| 16 | + |
| 17 | + /* Whether or not this CodeDefinition uses an option parameter. */ |
| 18 | + protected $useOption; |
| 19 | + |
| 20 | + /* The replacement text to be used for simple CodeDefinitions */ |
| 21 | + protected $replacementText; |
| 22 | + |
| 23 | + /* Whether or not to parse elements of this definition's contents */ |
| 24 | + protected $parseContent; |
| 25 | + |
| 26 | + /* How many of this element type may be nested within each other */ |
| 27 | + protected $nestLimit; |
| 28 | + |
| 29 | + /* How many of this element type have been seen */ |
| 30 | + protected $elCounter; |
| 31 | + |
| 32 | + /* The input validator to run options through */ |
| 33 | + protected $optionValidator; |
| 34 | + |
| 35 | + /* The input validator to run the body ({param}) through */ |
| 36 | + protected $bodyValidator; |
| 37 | + |
| 38 | + /** |
| 39 | + * Constructs a new CodeDefinition. |
| 40 | + */ |
| 41 | + public static function construct($tagName, $replacementText, $useOption = false, |
| 42 | + $parseContent = true, $nestLimit = -1, $optionValidator = null, |
| 43 | + $bodyValidator = null) |
| 44 | + { |
| 45 | + $def = new CodeDefinition(); |
| 46 | + $def->elCounter = 0; |
| 47 | + $def->setTagName($tagName); |
| 48 | + $def->setReplacementText($replacementText); |
| 49 | + $def->useOption = $useOption; |
| 50 | + $def->parseContent = $parseContent; |
| 51 | + $def->nestLimit = $nestLimit; |
| 52 | + $def->optionValidator = $optionValidator; |
| 53 | + $def->bodyValidator = $bodyValidator; |
| 54 | + return $def; |
| 55 | + } |
| 56 | + |
| 57 | + /** |
| 58 | + * Constructs a new CodeDefinition. |
| 59 | + * |
| 60 | + * This constructor is deprecated. You should use the static construct() method or the |
| 61 | + * CodeDefinitionBuilder class to construct a new CodeDefiniton. |
| 62 | + * |
| 63 | + * @deprecated |
| 64 | + */ |
| 65 | + public function __construct() |
| 66 | + { |
| 67 | + /* WARNING: This function is deprecated and will be made protected in a future |
| 68 | + * version of jBBCode. */ |
| 69 | + $this->parseContent = true; |
| 70 | + $this->useOption = false; |
| 71 | + $this->nestLimit = -1; |
| 72 | + $this->elCounter = 0; |
| 73 | + $this->optionValidator = null; |
| 74 | + $this->bodyValidator = null; |
| 75 | + } |
| 76 | + |
| 77 | + /** |
| 78 | + * Determines if the arguments to the given element are valid based on |
| 79 | + * any validators attached to this CodeDefinition. |
| 80 | + * |
| 81 | + * @param $el the ElementNode to validate |
| 82 | + * @return true if the ElementNode's {option} and {param} are OK, false if they're not |
| 83 | + */ |
| 84 | + public function hasValidInputs(ElementNode $el) |
| 85 | + { |
| 86 | + if ($this->usesOption() && $this->optionValidator && |
| 87 | + !$this->optionValidator->validate($el->getAttribute())) { |
| 88 | + /* The option argument to $el does not pass the option validator. */ |
| 89 | + return false; |
| 90 | + } |
| 91 | + |
| 92 | + if (!$this->parseContent() && $this->bodyValidator) { |
| 93 | + /* We only evaluate the content if we're not parsing the content. */ |
| 94 | + $content = ""; |
| 95 | + foreach ($el->getChildren() as $child) { |
| 96 | + $content .= $child->getAsBBCode(); |
| 97 | + } |
| 98 | + if (!$this->bodyValidator->validate($content)) { |
| 99 | + /* The content of the element is not valid. */ |
| 100 | + return false; |
| 101 | + } |
| 102 | + } |
| 103 | + |
| 104 | + return true; |
| 105 | + } |
| 106 | + |
| 107 | + /** |
| 108 | + * Accepts an ElementNode that is defined by this CodeDefinition and returns the HTML |
| 109 | + * markup of the element. This is a commonly overridden class for custom CodeDefinitions |
| 110 | + * so that the content can be directly manipulated. |
| 111 | + * |
| 112 | + * @param $el the element to return an html representation of |
| 113 | + * |
| 114 | + * @return the parsed html of this element (INCLUDING ITS CHILDREN) |
| 115 | + */ |
| 116 | + public function asHtml(ElementNode $el) |
| 117 | + { |
| 118 | + if (!$this->hasValidInputs($el)) { |
| 119 | + return $el->getAsBBCode(); |
| 120 | + } |
| 121 | + |
| 122 | + $html = $this->getReplacementText(); |
| 123 | + |
| 124 | + if ($this->usesOption()) { |
| 125 | + $html = str_ireplace('{option}', $el->getAttribute(), $html); |
| 126 | + } |
| 127 | + |
| 128 | + if ($this->parseContent()) { |
| 129 | + $content = ""; |
| 130 | + foreach ($el->getChildren() as $child) |
| 131 | + $content .= $child->getAsHTML(); |
| 132 | + } else { |
| 133 | + $content = ""; |
| 134 | + foreach ($el->getChildren() as $child) |
| 135 | + $content .= $child->getAsBBCode(); |
| 136 | + } |
| 137 | + |
| 138 | + $html = str_ireplace('{param}', $content, $html); |
| 139 | + |
| 140 | + return $html; |
| 141 | + } |
| 142 | + |
| 143 | + /** |
| 144 | + * Accepts an ElementNode that is defined by this CodeDefinition and returns the text |
| 145 | + * representation of the element. This may be overridden by a custom CodeDefinition. |
| 146 | + * |
| 147 | + * @param $el the element to return a text representation of |
| 148 | + * |
| 149 | + * @return the text representation of $el |
| 150 | + */ |
| 151 | + public function asText(ElementNode $el) |
| 152 | + { |
| 153 | + if (!$this->hasValidInputs($el)) { |
| 154 | + return $el->getAsBBCode(); |
| 155 | + } |
| 156 | + |
| 157 | + $s = ""; |
| 158 | + foreach ($el->getChildren() as $child) |
| 159 | + $s .= $child->getAsText(); |
| 160 | + return $s; |
| 161 | + } |
| 162 | + |
| 163 | + /** |
| 164 | + * Returns the tag name of this code definition |
| 165 | + * |
| 166 | + * @return this definition's associated tag name |
| 167 | + */ |
| 168 | + public function getTagName() |
| 169 | + { |
| 170 | + return $this->tagName; |
| 171 | + } |
| 172 | + |
| 173 | + /** |
| 174 | + * Returns the replacement text of this code definition. This usually has little, if any meaning if the |
| 175 | + * CodeDefinition class was extended. For default, html replacement CodeDefinitions this returns the html |
| 176 | + * markup for the definition. |
| 177 | + * |
| 178 | + * @return the replacement text of this CodeDefinition |
| 179 | + */ |
| 180 | + public function getReplacementText() |
| 181 | + { |
| 182 | + return $this->replacementText; |
| 183 | + } |
| 184 | + |
| 185 | + /** |
| 186 | + * Returns whether or not this CodeDefinition uses the optional {option} |
| 187 | + * |
| 188 | + * @return true if this CodeDefinition uses the option, false otherwise |
| 189 | + */ |
| 190 | + public function usesOption() |
| 191 | + { |
| 192 | + return $this->useOption; |
| 193 | + } |
| 194 | + |
| 195 | + /** |
| 196 | + * Returns whether or not this CodeDefnition parses elements contained within it, |
| 197 | + * or just treats its children as text. |
| 198 | + * |
| 199 | + * @return true if this CodeDefinition parses elements contained within itself |
| 200 | + */ |
| 201 | + public function parseContent() |
| 202 | + { |
| 203 | + return $this->parseContent; |
| 204 | + } |
| 205 | + |
| 206 | + /** |
| 207 | + * Returns the limit of how many elements defined by this CodeDefinition may be |
| 208 | + * nested together. If after parsing elements are nested beyond this limit, the |
| 209 | + * subtrees formed by those nodes will be removed from the parse tree. A nest |
| 210 | + * limit of -1 signifies no limit. |
| 211 | + */ |
| 212 | + public function getNestLimit() |
| 213 | + { |
| 214 | + return $this->nestLimit; |
| 215 | + } |
| 216 | + |
| 217 | + /** |
| 218 | + * Sets the tag name of this CodeDefinition |
| 219 | + * |
| 220 | + * @deprecated |
| 221 | + * |
| 222 | + * @param the new tag name of this definition |
| 223 | + */ |
| 224 | + public function setTagName($tagName) |
| 225 | + { |
| 226 | + $this->tagName = strtolower($tagName); |
| 227 | + } |
| 228 | + |
| 229 | + /** |
| 230 | + * Sets the html replacement text of this CodeDefinition |
| 231 | + * |
| 232 | + * @deprecated |
| 233 | + * |
| 234 | + * @param the new replacement text |
| 235 | + */ |
| 236 | + public function setReplacementText($txt) |
| 237 | + { |
| 238 | + $this->replacementText = $txt; |
| 239 | + } |
| 240 | + |
| 241 | + /** |
| 242 | + * Sets whether or not this CodeDefinition uses the {option} |
| 243 | + * |
| 244 | + * @deprecated |
| 245 | + * |
| 246 | + * @param boolean $bool |
| 247 | + */ |
| 248 | + public function setUseOption($bool) |
| 249 | + { |
| 250 | + $this->useOption = $bool; |
| 251 | + } |
| 252 | + |
| 253 | + /** |
| 254 | + * Sets whether or not this CodeDefinition allows its children to be parsed as html |
| 255 | + * |
| 256 | + * @deprecated |
| 257 | + * |
| 258 | + * @param boolean $bool |
| 259 | + */ |
| 260 | + public function setParseContent($bool) |
| 261 | + { |
| 262 | + $this->parseContent = $bool; |
| 263 | + } |
| 264 | + |
| 265 | + /** |
| 266 | + * Increments the element counter. This is used for tracking depth of elements of the same type for next limits. |
| 267 | + * |
| 268 | + * @deprecated |
| 269 | + * |
| 270 | + * @return void |
| 271 | + */ |
| 272 | + public function incrementCounter() |
| 273 | + { |
| 274 | + $this->elCounter++; |
| 275 | + } |
| 276 | + |
| 277 | + /** |
| 278 | + * Decrements the element counter. |
| 279 | + * |
| 280 | + * @deprecated |
| 281 | + * |
| 282 | + * @return void |
| 283 | + */ |
| 284 | + public function decrementCounter() |
| 285 | + { |
| 286 | + $this->elCounter--; |
| 287 | + } |
| 288 | + |
| 289 | + /** |
| 290 | + * Resets the element counter. |
| 291 | + * |
| 292 | + * @deprecated |
| 293 | + */ |
| 294 | + public function resetCounter() |
| 295 | + { |
| 296 | + $this->elCounter = 0; |
| 297 | + } |
| 298 | + |
| 299 | + /** |
| 300 | + * Returns the current value of the element counter. |
| 301 | + * |
| 302 | + * @deprecated |
| 303 | + * |
| 304 | + * @return int |
| 305 | + */ |
| 306 | + public function getCounter() |
| 307 | + { |
| 308 | + return $this->elCounter; |
| 309 | + } |
| 310 | +} |
0 commit comments