[ Index ]

PHP Cross Reference of phpBB-3.3.3-deutsch

title

Body

[close]

/vendor/s9e/text-formatter/src/Configurator/Helpers/ -> ElementInspector.php (source)

   1  <?php
   2  
   3  /**
   4  * @package   s9e\TextFormatter
   5  * @copyright Copyright (c) 2010-2020 The s9e authors
   6  * @license   http://www.opensource.org/licenses/mit-license.php The MIT License
   7  */
   8  namespace s9e\TextFormatter\Configurator\Helpers;
   9  
  10  use DOMElement;
  11  use DOMXPath;
  12  
  13  class ElementInspector
  14  {
  15      /**
  16      * This is an abridged version of the HTML5 content models and rules, with some liberties taken.
  17      *
  18      * For each element, up to three bitfields are defined: "c", "ac" and "dd". Bitfields are stored
  19      * as raw bytes, formatted using the octal notation to keep the sources ASCII.
  20      *
  21      *    "c" represents the categories the element belongs to. The categories are comprised of HTML5
  22      *        content models (such as "phrasing content" or "interactive content") plus a few special
  23      *        categories created to cover the parts of the specs that refer to "a group of X and Y
  24      *        elements" rather than a specific content model.
  25      *
  26      *   "ac" represents the categories that are allowed as children of given element.
  27      *
  28      *   "dd" represents the categories that must not appear as a descendant of given element.
  29      *
  30      * Sometimes, HTML5 specifies some restrictions on when an element can accept certain children,
  31      * or what categories the element belongs to. For example, an <img> element is only part of the
  32      * "interactive content" category if it has a "usemap" attribute. Those restrictions are
  33      * expressed as an XPath expression and stored using the concatenation of the key of the bitfield
  34      * plus the bit number of the category. For instance, if "interactive content" got assigned to
  35      * bit 2, the definition of the <img> element will contain a key "c2" with value "@usemap".
  36      *
  37      * Additionally, other flags are set:
  38      *
  39      *    "t" indicates that the element uses the "transparent" content model.
  40      *    "e" indicates that the element uses the "empty" content model.
  41      *    "v" indicates that the element is a void element.
  42      *   "nt" indicates that the element does not accept text nodes. (no text)
  43      *   "to" indicates that the element should only contain text. (text-only)
  44      *   "fe" indicates that the element is a formatting element. It will automatically be reopened
  45      *        when closed by an end tag of a different name.
  46      *    "b" indicates that the element is not phrasing content, which makes it likely to act like
  47      *        a block element.
  48      *
  49      * Finally, HTML5 defines "optional end tag" rules, where one element automatically closes its
  50      * predecessor. Those are used to generate closeParent rules and are stored in the "cp" key.
  51      *
  52      * @var array
  53      * @see /scripts/patchElementInspector.php
  54      */
  55      protected static $htmlElements = [
  56          'a'=>['c'=>"\17\0\0\0\0\2",'c3'=>'@href','ac'=>"\0",'dd'=>"\10\0\0\0\0\2",'t'=>1,'fe'=>1],
  57          'abbr'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0"],
  58          'address'=>['c'=>"\3\10",'ac'=>"\1",'dd'=>"\200\14",'b'=>1,'cp'=>['p']],
  59          'article'=>['c'=>"\3\4",'ac'=>"\1",'dd'=>"\0\0\0\0\20",'b'=>1,'cp'=>['p']],
  60          'aside'=>['c'=>"\3\4",'ac'=>"\1",'dd'=>"\0\0\0\0\20",'b'=>1,'cp'=>['p']],
  61          'audio'=>['c'=>"\57",'c3'=>'@controls','c1'=>'@controls','ac'=>"\0\0\0\40\1",'ac29'=>'not(@src)','dd'=>"\0\0\0\0\0\4",'dd42'=>'@src','t'=>1],
  62          'b'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0",'fe'=>1],
  63          'base'=>['c'=>"\20",'ac'=>"\0",'dd'=>"\0",'nt'=>1,'e'=>1,'v'=>1,'b'=>1],
  64          'bdi'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0"],
  65          'bdo'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0"],
  66          'blockquote'=>['c'=>"\103",'ac'=>"\1",'dd'=>"\0",'b'=>1,'cp'=>['p']],
  67          'body'=>['c'=>"\100\0\40",'ac'=>"\1",'dd'=>"\0",'b'=>1],
  68          'br'=>['c'=>"\5",'ac'=>"\0",'dd'=>"\0",'nt'=>1,'e'=>1,'v'=>1],
  69          'button'=>['c'=>"\17\2",'ac'=>"\4",'dd'=>"\10"],
  70          'canvas'=>['c'=>"\47",'ac'=>"\0",'dd'=>"\0",'t'=>1],
  71          'caption'=>['c'=>"\0\1",'ac'=>"\1",'dd'=>"\0\0\20",'b'=>1],
  72          'cite'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0"],
  73          'code'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0",'fe'=>1],
  74          'col'=>['c'=>"\0\0\200",'ac'=>"\0",'dd'=>"\0",'nt'=>1,'e'=>1,'v'=>1,'b'=>1],
  75          'colgroup'=>['c'=>"\0\1",'ac'=>"\0\0\200",'ac23'=>'not(@span)','dd'=>"\0",'nt'=>1,'e'=>1,'e?'=>'@span','b'=>1],
  76          'data'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0"],
  77          'datalist'=>['c'=>"\5",'ac'=>"\4\0\1\100",'dd'=>"\0"],
  78          'dd'=>['c'=>"\0\200\0\4",'ac'=>"\1",'dd'=>"\0",'b'=>1,'cp'=>['dd','dt']],
  79          'del'=>['c'=>"\5",'ac'=>"\0",'dd'=>"\0",'t'=>1],
  80          'details'=>['c'=>"\113",'ac'=>"\1\0\0\20",'dd'=>"\0",'b'=>1,'cp'=>['p']],
  81          'dfn'=>['c'=>"\7\0\0\0\100",'ac'=>"\4",'dd'=>"\0\0\0\0\100"],
  82          'dialog'=>['c'=>"\101",'ac'=>"\1",'dd'=>"\0",'b'=>1],
  83          'div'=>['c'=>"\3\200",'ac'=>"\1\0\1\4",'ac0'=>'not(ancestor::dl)','dd'=>"\0",'b'=>1,'cp'=>['p']],
  84          'dl'=>['c'=>"\3",'c1'=>'dt and dd','ac'=>"\0\200\1",'dd'=>"\0",'nt'=>1,'b'=>1,'cp'=>['p']],
  85          'dt'=>['c'=>"\0\200\0\4",'ac'=>"\1",'dd'=>"\200\4\10",'b'=>1,'cp'=>['dd','dt']],
  86          'em'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0",'fe'=>1],
  87          'embed'=>['c'=>"\57",'ac'=>"\0",'dd'=>"\0",'nt'=>1,'e'=>1,'v'=>1],
  88          'fieldset'=>['c'=>"\103\2",'ac'=>"\1\0\0\200",'dd'=>"\0",'b'=>1,'cp'=>['p']],
  89          'figcaption'=>['c'=>"\0\0\0\0\0\10",'ac'=>"\1",'dd'=>"\0",'b'=>1,'cp'=>['p']],
  90          'figure'=>['c'=>"\103",'ac'=>"\1\0\0\0\0\10",'dd'=>"\0",'b'=>1,'cp'=>['p']],
  91          'footer'=>['c'=>"\3\110\10",'ac'=>"\1",'dd'=>"\0\0\0\0\20",'b'=>1,'cp'=>['p']],
  92          'form'=>['c'=>"\3\0\0\0\40",'ac'=>"\1",'dd'=>"\0\0\0\0\40",'b'=>1,'cp'=>['p']],
  93          'h1'=>['c'=>"\203",'ac'=>"\4",'dd'=>"\0",'b'=>1,'cp'=>['p']],
  94          'h2'=>['c'=>"\203",'ac'=>"\4",'dd'=>"\0",'b'=>1,'cp'=>['p']],
  95          'h3'=>['c'=>"\203",'ac'=>"\4",'dd'=>"\0",'b'=>1,'cp'=>['p']],
  96          'h4'=>['c'=>"\203",'ac'=>"\4",'dd'=>"\0",'b'=>1,'cp'=>['p']],
  97          'h5'=>['c'=>"\203",'ac'=>"\4",'dd'=>"\0",'b'=>1,'cp'=>['p']],
  98          'h6'=>['c'=>"\203",'ac'=>"\4",'dd'=>"\0",'b'=>1,'cp'=>['p']],
  99          'head'=>['c'=>"\0\0\40",'ac'=>"\20",'dd'=>"\0",'nt'=>1,'b'=>1],
 100          'header'=>['c'=>"\3\110\10",'ac'=>"\1",'dd'=>"\0\0\0\0\20",'b'=>1,'cp'=>['p']],
 101          'hr'=>['c'=>"\1",'ac'=>"\0",'dd'=>"\0",'nt'=>1,'e'=>1,'v'=>1,'b'=>1,'cp'=>['p']],
 102          'html'=>['c'=>"\0",'ac'=>"\0\0\40",'dd'=>"\0",'nt'=>1,'b'=>1],
 103          'i'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0",'fe'=>1],
 104          'iframe'=>['c'=>"\57",'ac'=>"\4",'dd'=>"\0"],
 105          'img'=>['c'=>"\57\40\100",'c3'=>'@usemap','ac'=>"\0",'dd'=>"\0",'nt'=>1,'e'=>1,'v'=>1],
 106          'input'=>['c'=>"\17\40",'c3'=>'@type!="hidden"','c13'=>'@type!="hidden" or @type="hidden"','c1'=>'@type!="hidden"','ac'=>"\0",'dd'=>"\0",'nt'=>1,'e'=>1,'v'=>1],
 107          'ins'=>['c'=>"\7",'ac'=>"\0",'dd'=>"\0",'t'=>1],
 108          'kbd'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0"],
 109          'label'=>['c'=>"\17\40\0\0\10",'ac'=>"\4",'dd'=>"\0\0\2\0\10"],
 110          'legend'=>['c'=>"\0\0\0\200",'ac'=>"\204",'dd'=>"\0",'b'=>1],
 111          'li'=>['c'=>"\0\0\0\0\0\1",'ac'=>"\1",'dd'=>"\0",'b'=>1,'cp'=>['li']],
 112          'link'=>['c'=>"\25",'ac'=>"\0",'dd'=>"\0",'nt'=>1,'e'=>1,'v'=>1],
 113          'main'=>['c'=>"\3\110\20\0\20",'ac'=>"\1",'dd'=>"\0",'b'=>1,'cp'=>['p']],
 114          'mark'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0"],
 115          'media element'=>['c'=>"\0\0\0\0\0\4",'ac'=>"\0",'dd'=>"\0",'nt'=>1,'b'=>1],
 116          'meta'=>['c'=>"\20",'ac'=>"\0",'dd'=>"\0",'nt'=>1,'e'=>1,'v'=>1,'b'=>1],
 117          'meter'=>['c'=>"\7\0\2\0\4",'ac'=>"\4",'dd'=>"\0\0\0\0\4"],
 118          'nav'=>['c'=>"\3\4",'ac'=>"\1",'dd'=>"\0\0\0\0\20",'b'=>1,'cp'=>['p']],
 119          'noscript'=>['c'=>"\25",'ac'=>"\0",'dd'=>"\0",'nt'=>1],
 120          'object'=>['c'=>"\47",'ac'=>"\0\0\0\0\2",'dd'=>"\0",'t'=>1],
 121          'ol'=>['c'=>"\3",'c1'=>'li','ac'=>"\0\0\1\0\0\1",'dd'=>"\0",'nt'=>1,'b'=>1,'cp'=>['p']],
 122          'optgroup'=>['c'=>"\0\0\4",'ac'=>"\0\0\1\100",'dd'=>"\0",'nt'=>1,'b'=>1,'cp'=>['optgroup','option']],
 123          'option'=>['c'=>"\0\0\4\100",'ac'=>"\0",'dd'=>"\0",'b'=>1,'cp'=>['option']],
 124          'output'=>['c'=>"\7\2",'ac'=>"\4",'dd'=>"\0"],
 125          'p'=>['c'=>"\3",'ac'=>"\4",'dd'=>"\0",'b'=>1,'cp'=>['p']],
 126          'param'=>['c'=>"\0\0\0\0\2",'ac'=>"\0",'dd'=>"\0",'nt'=>1,'e'=>1,'v'=>1,'b'=>1],
 127          'picture'=>['c'=>"\45",'ac'=>"\0\0\101",'dd'=>"\0",'nt'=>1],
 128          'pre'=>['c'=>"\3",'ac'=>"\4",'dd'=>"\0",'pre'=>1,'b'=>1,'cp'=>['p']],
 129          'progress'=>['c'=>"\7\0\2\10",'ac'=>"\4",'dd'=>"\0\0\0\10"],
 130          'q'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0"],
 131          'rb'=>['c'=>"\0\20",'ac'=>"\4",'dd'=>"\0",'b'=>1,'cp'=>['rb','rt','rtc']],
 132          'rp'=>['c'=>"\0\20\0\2",'ac'=>"\4",'dd'=>"\0",'b'=>1],
 133          'rt'=>['c'=>"\0\20\0\2",'ac'=>"\4",'dd'=>"\0",'b'=>1,'cp'=>['rb','rt']],
 134          'rtc'=>['c'=>"\0\20",'ac'=>"\4\0\0\2",'dd'=>"\0",'b'=>1,'cp'=>['rt','rtc']],
 135          'ruby'=>['c'=>"\7",'ac'=>"\4\20",'dd'=>"\0"],
 136          's'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0",'fe'=>1],
 137          'samp'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0"],
 138          'script'=>['c'=>"\25\0\1",'ac'=>"\0",'dd'=>"\0",'to'=>1],
 139          'section'=>['c'=>"\3\4",'ac'=>"\1",'dd'=>"\0",'b'=>1,'cp'=>['p']],
 140          'select'=>['c'=>"\17\2",'ac'=>"\0\0\5",'dd'=>"\0",'nt'=>1],
 141          'slot'=>['c'=>"\5",'ac'=>"\0",'dd'=>"\0",'t'=>1],
 142          'small'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0",'fe'=>1],
 143          'source'=>['c'=>"\0\0\100\40",'ac'=>"\0",'dd'=>"\0",'nt'=>1,'e'=>1,'v'=>1,'b'=>1],
 144          'span'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0"],
 145          'strong'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0",'fe'=>1],
 146          'style'=>['c'=>"\21",'ac'=>"\0",'dd'=>"\0",'to'=>1,'b'=>1],
 147          'sub'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0"],
 148          'summary'=>['c'=>"\0\0\0\20",'ac'=>"\204",'dd'=>"\0",'b'=>1],
 149          'sup'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0"],
 150          'table'=>['c'=>"\3\0\20",'ac'=>"\0\1\1",'dd'=>"\0",'nt'=>1,'b'=>1,'cp'=>['p']],
 151          'tbody'=>['c'=>"\0\1",'ac'=>"\0\0\1\0\200",'dd'=>"\0",'nt'=>1,'b'=>1,'cp'=>['tbody','td','th','thead','tr']],
 152          'td'=>['c'=>"\100\0\0\1",'ac'=>"\1",'dd'=>"\0\0\0\0\20",'b'=>1,'cp'=>['td','th']],
 153          'template'=>['c'=>"\25\0\201",'ac'=>"\0",'dd'=>"\0",'nt'=>1],
 154          'textarea'=>['c'=>"\17\2",'ac'=>"\0",'dd'=>"\0",'pre'=>1,'to'=>1],
 155          'tfoot'=>['c'=>"\0\1",'ac'=>"\0\0\1\0\200",'dd'=>"\0",'nt'=>1,'b'=>1,'cp'=>['tbody','td','th','thead','tr']],
 156          'th'=>['c'=>"\0\0\0\1",'ac'=>"\1",'dd'=>"\200\104",'b'=>1,'cp'=>['td','th']],
 157          'thead'=>['c'=>"\0\1",'ac'=>"\0\0\1\0\200",'dd'=>"\0",'nt'=>1,'b'=>1],
 158          'time'=>['c'=>"\7",'ac'=>"\4",'ac2'=>'@datetime','dd'=>"\0"],
 159          'title'=>['c'=>"\20",'ac'=>"\0",'dd'=>"\0",'to'=>1,'b'=>1],
 160          'tr'=>['c'=>"\0\1\0\0\200",'ac'=>"\0\0\1\1",'dd'=>"\0",'nt'=>1,'b'=>1,'cp'=>['td','th','tr']],
 161          'track'=>['c'=>"\0\0\0\0\1",'ac'=>"\0",'dd'=>"\0",'nt'=>1,'e'=>1,'v'=>1,'b'=>1],
 162          'u'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0",'fe'=>1],
 163          'ul'=>['c'=>"\3",'c1'=>'li','ac'=>"\0\0\1\0\0\1",'dd'=>"\0",'nt'=>1,'b'=>1,'cp'=>['p']],
 164          'var'=>['c'=>"\7",'ac'=>"\4",'dd'=>"\0"],
 165          'video'=>['c'=>"\57",'c3'=>'@controls','ac'=>"\0\0\0\40\1",'ac29'=>'not(@src)','dd'=>"\0\0\0\0\0\4",'dd42'=>'@src','t'=>1],
 166          'wbr'=>['c'=>"\5",'ac'=>"\0",'dd'=>"\0",'nt'=>1,'e'=>1,'v'=>1]
 167      ];
 168  
 169      /**
 170      * Test whether given child element closes given parent element
 171      *
 172      * @param  DOMElement $child
 173      * @param  DOMElement $parent
 174      * @return bool
 175      */
 176  	public static function closesParent(DOMElement $child, DOMElement $parent)
 177      {
 178          $parentName = $parent->nodeName;
 179          $childName  = $child->nodeName;
 180  
 181          return !empty(self::$htmlElements[$childName]['cp']) && in_array($parentName, self::$htmlElements[$childName]['cp'], true);
 182      }
 183  
 184      /**
 185      * Test whether given element disallows text nodes
 186      *
 187      * @param  DOMElement $element
 188      * @return bool
 189      */
 190  	public static function disallowsText(DOMElement $element)
 191      {
 192          return self::hasProperty($element, 'nt');
 193      }
 194  
 195      /**
 196      * Return the "allowChild" bitfield for given element
 197      *
 198      * @param  DOMElement $element
 199      * @return string
 200      */
 201  	public static function getAllowChildBitfield(DOMElement $element)
 202      {
 203          return self::getBitfield($element, 'ac');
 204      }
 205  
 206      /**
 207      * Return the "category" bitfield for given element
 208      *
 209      * @param  DOMElement $element
 210      * @return string
 211      */
 212  	public static function getCategoryBitfield(DOMElement $element)
 213      {
 214          return self::getBitfield($element, 'c');
 215      }
 216  
 217      /**
 218      * Return the "denyDescendant" bitfield for given element
 219      *
 220      * @param  DOMElement $element
 221      * @return string
 222      */
 223  	public static function getDenyDescendantBitfield(DOMElement $element)
 224      {
 225          return self::getBitfield($element, 'dd');
 226      }
 227  
 228      /**
 229      * Test whether given element is a block element
 230      *
 231      * @param  DOMElement $element
 232      * @return bool
 233      */
 234  	public static function isBlock(DOMElement $element)
 235      {
 236          return self::hasProperty($element, 'b');
 237      }
 238  
 239      /**
 240      * Test whether given element uses the empty content model
 241      *
 242      * @param  DOMElement $element
 243      * @return bool
 244      */
 245  	public static function isEmpty(DOMElement $element)
 246      {
 247          return self::hasProperty($element, 'e');
 248      }
 249  
 250      /**
 251      * Test whether given element is a formatting element
 252      *
 253      * @param  DOMElement $element
 254      * @return bool
 255      */
 256  	public static function isFormattingElement(DOMElement $element)
 257      {
 258          return self::hasProperty($element, 'fe');
 259      }
 260  
 261      /**
 262      * Test whether given element only accepts text nodes
 263      *
 264      * @param  DOMElement $element
 265      * @return bool
 266      */
 267  	public static function isTextOnly(DOMElement $element)
 268      {
 269          return self::hasProperty($element, 'to');
 270      }
 271  
 272      /**
 273      * Test whether given element uses the transparent content model
 274      *
 275      * @param  DOMElement $element
 276      * @return bool
 277      */
 278  	public static function isTransparent(DOMElement $element)
 279      {
 280          return self::hasProperty($element, 't');
 281      }
 282  
 283      /**
 284      * Test whether given element uses the void content model
 285      *
 286      * @param  DOMElement $element
 287      * @return bool
 288      */
 289  	public static function isVoid(DOMElement $element)
 290      {
 291          return self::hasProperty($element, 'v');
 292      }
 293  
 294      /**
 295      * Test whether given element preserves whitespace in its content
 296      *
 297      * @param  DOMElement $element
 298      * @return bool
 299      */
 300  	public static function preservesWhitespace(DOMElement $element)
 301      {
 302          return self::hasProperty($element, 'pre');
 303      }
 304  
 305      /**
 306      * Evaluate an XPath query using given element as context node
 307      *
 308      * @param  string     $query   XPath query
 309      * @param  DOMElement $element Context node
 310      * @return bool
 311      */
 312  	protected static function evaluate($query, DOMElement $element)
 313      {
 314          $xpath = new DOMXPath($element->ownerDocument);
 315  
 316          return $xpath->evaluate('boolean(' . $query . ')', $element);
 317      }
 318  
 319      /**
 320      * Get the bitfield value for a given element
 321      *
 322      * @param  DOMElement $element Context node
 323      * @param  string     $name    Bitfield name: either 'c', 'ac' or 'dd'
 324      * @return string
 325      */
 326  	protected static function getBitfield(DOMElement $element, $name)
 327      {
 328          $props    = self::getProperties($element);
 329          $bitfield = self::toBin($props[$name]);
 330  
 331          // For each bit set to 1, test whether there is an XPath condition to it and whether it is
 332          // fulfilled. If not, turn the bit to 0
 333          foreach (array_keys(array_filter(str_split($bitfield, 1))) as $bitNumber)
 334          {
 335              $conditionName = $name . $bitNumber;
 336              if (isset($props[$conditionName]) && !self::evaluate($props[$conditionName], $element))
 337              {
 338                  $bitfield[$bitNumber] = '0';
 339              }
 340          }
 341  
 342          return self::toRaw($bitfield);
 343      }
 344  
 345      /**
 346      * Return the properties associated with given element
 347      *
 348      * Returns span's properties if the element is not defined
 349      *
 350      * @param  DOMElement $element
 351      * @return array
 352      */
 353  	protected static function getProperties(DOMElement $element)
 354      {
 355          return (isset(self::$htmlElements[$element->nodeName])) ? self::$htmlElements[$element->nodeName] : self::$htmlElements['span'];
 356      }
 357  
 358      /**
 359      * Test whether given element has given property in context
 360      *
 361      * @param  DOMElement $element  Context node
 362      * @param  string     $propName Property name, see self::$htmlElements
 363      * @return bool
 364      */
 365  	protected static function hasProperty(DOMElement $element, $propName)
 366      {
 367          $props = self::getProperties($element);
 368  
 369          return !empty($props[$propName]) && (!isset($props[$propName . '?']) || self::evaluate($props[$propName . '?'], $element));
 370      }
 371  
 372      /**
 373      * Convert a raw string to a series of 0 and 1 in LSB order
 374      *
 375      * @param  string $raw
 376      * @return string
 377      */
 378  	protected static function toBin($raw)
 379      {
 380          $bin = '';
 381          foreach (str_split($raw, 1) as $char)
 382          {
 383              $bin .= strrev(substr('0000000' . decbin(ord($char)), -8));
 384          }
 385  
 386          return $bin;
 387      }
 388  
 389      /**
 390      * Convert a series of 0 and 1 in LSB order to a raw string
 391      *
 392      * @param  string $bin
 393      * @return string
 394      */
 395  	protected static function toRaw($bin)
 396      {
 397          return implode('', array_map('chr', array_map('bindec', array_map('strrev', str_split($bin, 8)))));
 398      }
 399  }


Generated: Sun Feb 14 20:08:31 2021 Cross-referenced by PHPXref 0.7.1