class.lessautoprefixer.inc 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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. try {
  40. $version_response = self::create(NULL)->proc_open(array('--version'));
  41. $version = preg_replace('/.*?([\d\.]+).*/', '$1', $version_response);
  42. }
  43. catch (Exception $e) {
  44. }
  45. return $version;
  46. }
  47. /**
  48. * Enable source maps for current file, and configure source map paths.
  49. *
  50. * @param bool $enabled
  51. * Set the source maps flag.
  52. */
  53. public function source_maps($enabled) {
  54. $this->source_maps_enabled = $enabled;
  55. }
  56. /**
  57. * Provides list to command line arguments for execution.
  58. *
  59. * @return array
  60. * Array of command line arguments.
  61. */
  62. protected function command_arguments() {
  63. $arguments = array();
  64. // Set service map flags.
  65. if ($this->source_maps_enabled) {
  66. $arguments[] = '--map';
  67. $arguments[] = '--inline-map';
  68. }
  69. // Input file should be last argument.
  70. $arguments[] = $this->input_file;
  71. return $arguments;
  72. }
  73. /**
  74. * Executes auto-prefixing of LESS output file.
  75. *
  76. * @return string
  77. * Compiled CSS.
  78. */
  79. public function compile() {
  80. return $this->proc_open($this->command_arguments());
  81. }
  82. protected function proc_open($command_arguments = array()) {
  83. $output_data = NULL;
  84. $command = implode(' ', array_merge(array(self::BASE_COMMAND), $command_arguments));
  85. // Handles for data exchange.
  86. $pipes = array(
  87. 0 => NULL, // STDIN
  88. 1 => NULL, // STDOUT
  89. 2 => NULL, // STDERR
  90. );
  91. // Sets permissions on $pipes.
  92. $descriptors = array(
  93. 0 => array('pipe', 'r'), // STDIN
  94. 1 => array('pipe', 'w'), // STDOUT
  95. 2 => array('pipe', 'w'), // STDERR
  96. );
  97. try {
  98. $process = proc_open($command, $descriptors, $pipes);
  99. if (is_resource($process)) {
  100. fclose($pipes[0]); // fclose() on STDIN executes $command, if program is expecting input from STDIN.
  101. $output_data = stream_get_contents($pipes[1]);
  102. fclose($pipes[1]);
  103. $error = stream_get_contents($pipes[2]);
  104. fclose($pipes[2]);
  105. if (!empty($error)) {
  106. throw new Exception($error);
  107. }
  108. proc_close($process);
  109. }
  110. }
  111. catch (Exception $e) {
  112. throw $e;
  113. }
  114. return $output_data;
  115. }
  116. }