class.lessautoprefixer.inc 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. /**
  3. * @file
  4. * Contains 'LessAutoprefixer' class; an abstraction layer for command line Autoprefixer.
  5. */
  6. /**
  7. * 'Autoprefixer' class.
  8. */
  9. class LessAutoprefixer {
  10. // Base command is hardcoded here to reduce security vulnerability.
  11. const BASE_COMMAND = 'autoprefixer';
  12. protected $input_file = NULL;
  13. protected $source_maps_enabled = FALSE;
  14. /**
  15. * Constructor function for 'LessAutoprefixer'.
  16. *
  17. * @param string $input_file
  18. * Path for .less file relative to getcwd().
  19. */
  20. protected function __construct($input_file) {
  21. $this->input_file = $input_file;
  22. }
  23. /**
  24. * @param string $input_file
  25. *
  26. * @return LessAutoprefixer
  27. */
  28. public static function create($input_file) {
  29. return new self($input_file);
  30. }
  31. /**
  32. * Returns the version string from command line Autoprefixer.
  33. *
  34. * @return string|null
  35. * Version string from Autoprefixer, or null if no version found.
  36. */
  37. public static function version() {
  38. $version = NULL;
  39. if (function_exists('proc_open')) {
  40. try {
  41. $version_response = self::create(NULL)->proc_open(array('--version'));
  42. $version = preg_replace('/.*?([\d\.]+).*/', '$1', $version_response);
  43. }
  44. catch (Exception $e) {
  45. }
  46. }
  47. return $version;
  48. }
  49. /**
  50. * Enable source maps for current file, and configure source map paths.
  51. *
  52. * @param bool $enabled
  53. * Set the source maps flag.
  54. */
  55. public function source_maps($enabled) {
  56. $this->source_maps_enabled = $enabled;
  57. }
  58. /**
  59. * Provides list to command line arguments for execution.
  60. *
  61. * @return array
  62. * Array of command line arguments.
  63. */
  64. protected function command_arguments() {
  65. $arguments = array();
  66. // Set service map flags.
  67. if ($this->source_maps_enabled) {
  68. $arguments[] = '--map';
  69. $arguments[] = '--inline-map';
  70. }
  71. // Input file should be last argument.
  72. $arguments[] = $this->input_file;
  73. return $arguments;
  74. }
  75. /**
  76. * Executes auto-prefixing of LESS output file.
  77. *
  78. * @return string
  79. * Compiled CSS.
  80. */
  81. public function compile() {
  82. return $this->proc_open($this->command_arguments());
  83. }
  84. protected function proc_open($command_arguments = array()) {
  85. $output_data = NULL;
  86. $command = implode(' ', array_merge(array(self::BASE_COMMAND), $command_arguments));
  87. // Handles for data exchange.
  88. $pipes = array(
  89. 0 => NULL, // STDIN
  90. 1 => NULL, // STDOUT
  91. 2 => NULL, // STDERR
  92. );
  93. // Sets permissions on $pipes.
  94. $descriptors = array(
  95. 0 => array('pipe', 'r'), // STDIN
  96. 1 => array('pipe', 'w'), // STDOUT
  97. 2 => array('pipe', 'w'), // STDERR
  98. );
  99. try {
  100. $process = proc_open($command, $descriptors, $pipes);
  101. if (is_resource($process)) {
  102. fclose($pipes[0]); // fclose() on STDIN executes $command, if program is expecting input from STDIN.
  103. $output_data = stream_get_contents($pipes[1]);
  104. fclose($pipes[1]);
  105. $error = stream_get_contents($pipes[2]);
  106. fclose($pipes[2]);
  107. if (!empty($error)) {
  108. throw new Exception($error);
  109. }
  110. proc_close($process);
  111. }
  112. }
  113. catch (Exception $e) {
  114. throw $e;
  115. }
  116. return $output_data;
  117. }
  118. }