less-bridge.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. /**
  3. * LESSPHP wrapper
  4. *
  5. * @package vamtam/consulting
  6. */
  7. /**
  8. * class VamtamLessBridge
  9. */
  10. class VamtamLessBridge {
  11. /**
  12. * List of option names which are known to be percentages
  13. *
  14. * @var array
  15. */
  16. public static $percentages = array(
  17. 'left-sidebar-width',
  18. 'right-sidebar-width',
  19. );
  20. /**
  21. * List of option names which are known to be numbers
  22. *
  23. * @var array
  24. */
  25. public static $numbers = array(
  26. );
  27. public static function prepare_vars_for_export( $vars_raw, $deprecated = '' ) {
  28. global $wpdb, $vamtam_defaults;
  29. $vars_raw = self::flatten_vars( apply_filters( 'vamtam_less_vars', $vars_raw ) );
  30. $vars = array();
  31. foreach ( $vars_raw as $name => $value ) {
  32. if ( trim( $value ) === '' && preg_match( '/\bbackground-image\b/i', $name ) ) {
  33. $vars[ $name ] = '';
  34. continue;
  35. }
  36. if ( preg_match( '/^[-\w\d]+$/i', $name ) ) {
  37. $vars[ $name ] = self::prepare( $name, $value );
  38. }
  39. }
  40. $vars = array_merge(
  41. $vars,
  42. include( locate_template( 'vamtam/assets/css/additional-css-variables.php' ) )
  43. );
  44. // -----------------------------------------------------------------------------
  45. $out = array();
  46. foreach ( $vars as $name => $value_raw ) {
  47. $value = $value_raw;
  48. if ( ! $value_raw ) {
  49. $value = '';
  50. if ( strpos( $name, 'background-attachment' ) !== false ) {
  51. $value = 'scroll';
  52. } elseif ( strpos( $name, 'background-position' ) !== false ) {
  53. $value = 'left top';
  54. } elseif ( strpos( $name, 'background-repeat' ) !== false ) {
  55. $value = 'no-repeat';
  56. } elseif ( strpos( $name, 'background-size' ) !== false ) {
  57. $value = 'auto';
  58. }
  59. }
  60. if ( ! is_null( $value_raw ) ) {
  61. if ( preg_match( '/-variant$/', $name ) ) {
  62. $weight = 'normal';
  63. $style = 'normal';
  64. $value = explode( ' ', $value );
  65. if ( count( $value ) === 2 ) {
  66. list( $weight, $style ) = $value;
  67. } elseif ( $value[0] === 'italic' ) {
  68. $style = 'italic';
  69. } else {
  70. $weight = $value[0];
  71. }
  72. $name = str_replace( 'variant', '', $name );
  73. $out[ $name . 'font-weight' ] = $weight;
  74. $out[ $name . 'font-style' ] = $style;
  75. } elseif ( preg_match( '/-background-image$/', $name ) ) {
  76. $out[ $name ] = $value === '' ? 'none' : "url({$value})";
  77. } elseif ( ! preg_match( '/-(weight|style)$/', $name ) ) {
  78. $out[ $name ] = $value;
  79. }
  80. }
  81. }
  82. return $out;
  83. }
  84. private static function flatten_vars( $vars, $prefix = '' ) {
  85. $flat_vars = array();
  86. foreach ( $vars as $key => $var ) {
  87. if ( is_array( $var ) ) {
  88. $flat_vars = array_merge( $flat_vars, self::flatten_vars( $var, $prefix . $key . '-' ) );
  89. unset( $flat_vars[ $key ] );
  90. } else {
  91. $flat_vars[ $prefix . $key ] = $var;
  92. }
  93. }
  94. return $flat_vars;
  95. }
  96. /**
  97. * Sanitizes a variable
  98. *
  99. * @param string $name option name
  100. * @param string $value option value from db
  101. * @param boolean $returnOriginal whether to return the db value if no good sanitization is found
  102. * @return int|string|null sanitized value
  103. */
  104. private static function prepare( $name, $value, $returnOriginal = false ) {
  105. $good = true;
  106. $name = preg_replace( '/^vamtam_/', '', $name );
  107. $originalValue = $value;
  108. // duck typing values
  109. if ( preg_match( '/(^share|^has-|^show|-last$|-subsets$|-google$)/i', $name ) ) {
  110. $good = false;
  111. } elseif ( preg_match( '/(%|px|em)$/i', $value ) ) { // definitely a number, leave it as is
  112. } elseif ( is_numeric( $value ) ) { // most likely dimensions, must differentiate between percentages and pixels
  113. if ( in_array( $name, self::$percentages ) ) {
  114. $value .= '%';
  115. } elseif ( in_array( $name, self::$numbers ) ) {
  116. // as it is
  117. } elseif ( preg_match( '/(size|width|height)$/', $name ) || preg_match( '/padding|margin/', $name ) ) { // treat as px
  118. $value .= 'px';
  119. }
  120. } elseif ( preg_match( '/^#([0-9a-f]{3}|[0-9a-f]{6})$/i', $value ) || ( $value === '' && preg_match( '/-color$/', $name ) ) ) { // colors
  121. // as is
  122. } elseif ( preg_match( '/-font-family$/', $name ) && strpos( $value, ',' ) !== false ) {
  123. // as is
  124. } elseif ( preg_match( '/^http|^url/i', $value ) || preg_match( '/(family|weight)$/', $name ) ) { // urls and other strings
  125. $value = "'" . str_replace( "'", '"', $value ) . "'";
  126. } elseif ( preg_match( '/^accent(?:-color-)?\d$/', $value ) ) { // accents
  127. $value = vamtam_sanitize_accent( $value );
  128. } else {
  129. if ( ! preg_match( '/\bfamily\b|\burl\b|\bcolor\b/i', $name ) ) {
  130. // check keywords
  131. $keywords = explode( ' ', 'top right bottom left fixed static scroll cover contain auto repeat repeat-x repeat-y no-repeat center normal italic bold 100 200 300 400 500 600 700 800 900 transparent' );
  132. $sub_values = explode( ' ', $value );
  133. foreach ( $sub_values as $s ) {
  134. if ( ! in_array( $s, $keywords ) ) {
  135. $good = false;
  136. break;
  137. }
  138. }
  139. }
  140. }
  141. return $good ? $value : ( $returnOriginal ? $originalValue : null );
  142. }
  143. }