Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   1  <?php
   2  
   3  /* W3C says:
   4      [ // adjective and number must be in correct order, even if
   5        // you could switch them without introducing ambiguity.
   6        // some browsers support that syntax
   7          [
   8              <percentage> | <length> | left | center | right
   9          ]
  10          [
  11              <percentage> | <length> | top | center | bottom
  12          ]?
  13      ] |
  14      [ // this signifies that the vertical and horizontal adjectives
  15        // can be arbitrarily ordered, however, there can only be two,
  16        // one of each, or none at all
  17          [
  18              left | center | right
  19          ] ||
  20          [
  21              top | center | bottom
  22          ]
  23      ]
  24      top, left = 0%
  25      center, (none) = 50%
  26      bottom, right = 100%
  27  */
  28  
  29  /* QuirksMode says:
  30      keyword + length/percentage must be ordered correctly, as per W3C
  31  
  32      Internet Explorer and Opera, however, support arbitrary ordering. We
  33      should fix it up.
  34  
  35      Minor issue though, not strictly necessary.
  36  */
  37  
  38  // control freaks may appreciate the ability to convert these to
  39  // percentages or something, but it's not necessary
  40  
  41  /**
  42   * Validates the value of background-position.
  43   */
  44  class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef
  45  {
  46  
  47      /**
  48       * @type HTMLPurifier_AttrDef_CSS_Length
  49       */
  50      protected $length;
  51  
  52      /**
  53       * @type HTMLPurifier_AttrDef_CSS_Percentage
  54       */
  55      protected $percentage;
  56  
  57      public function __construct()
  58      {
  59          $this->length = new HTMLPurifier_AttrDef_CSS_Length();
  60          $this->percentage = new HTMLPurifier_AttrDef_CSS_Percentage();
  61      }
  62  
  63      /**
  64       * @param string $string
  65       * @param HTMLPurifier_Config $config
  66       * @param HTMLPurifier_Context $context
  67       * @return bool|string
  68       */
  69      public function validate($string, $config, $context)
  70      {
  71          $string = $this->parseCDATA($string);
  72          $bits = explode(' ', $string);
  73  
  74          $keywords = array();
  75          $keywords['h'] = false; // left, right
  76          $keywords['v'] = false; // top, bottom
  77          $keywords['ch'] = false; // center (first word)
  78          $keywords['cv'] = false; // center (second word)
  79          $measures = array();
  80  
  81          $i = 0;
  82  
  83          $lookup = array(
  84              'top' => 'v',
  85              'bottom' => 'v',
  86              'left' => 'h',
  87              'right' => 'h',
  88              'center' => 'c'
  89          );
  90  
  91          foreach ($bits as $bit) {
  92              if ($bit === '') {
  93                  continue;
  94              }
  95  
  96              // test for keyword
  97              $lbit = ctype_lower($bit) ? $bit : strtolower($bit);
  98              if (isset($lookup[$lbit])) {
  99                  $status = $lookup[$lbit];
 100                  if ($status == 'c') {
 101                      if ($i == 0) {
 102                          $status = 'ch';
 103                      } else {
 104                          $status = 'cv';
 105                      }
 106                  }
 107                  $keywords[$status] = $lbit;
 108                  $i++;
 109              }
 110  
 111              // test for length
 112              $r = $this->length->validate($bit, $config, $context);
 113              if ($r !== false) {
 114                  $measures[] = $r;
 115                  $i++;
 116              }
 117  
 118              // test for percentage
 119              $r = $this->percentage->validate($bit, $config, $context);
 120              if ($r !== false) {
 121                  $measures[] = $r;
 122                  $i++;
 123              }
 124          }
 125  
 126          if (!$i) {
 127              return false;
 128          } // no valid values were caught
 129  
 130          $ret = array();
 131  
 132          // first keyword
 133          if ($keywords['h']) {
 134              $ret[] = $keywords['h'];
 135          } elseif ($keywords['ch']) {
 136              $ret[] = $keywords['ch'];
 137              $keywords['cv'] = false; // prevent re-use: center = center center
 138          } elseif (count($measures)) {
 139              $ret[] = array_shift($measures);
 140          }
 141  
 142          if ($keywords['v']) {
 143              $ret[] = $keywords['v'];
 144          } elseif ($keywords['cv']) {
 145              $ret[] = $keywords['cv'];
 146          } elseif (count($measures)) {
 147              $ret[] = array_shift($measures);
 148          }
 149  
 150          if (empty($ret)) {
 151              return false;
 152          }
 153          return implode(' ', $ret);
 154      }
 155  }
 156  
 157  // vim: et sw=4 sts=4