/src/classes/class-breakpoints.php

https://github.com/nk-o/ghostkit · PHP · 415 lines · 203 code · 52 blank · 160 comment · 18 complexity · fe8347bcc14a506c97e0cab454a36a41 MD5 · raw file

  1. <?php
  2. /**
  3. * Breakpoints
  4. *
  5. * @package @@plugin_name
  6. */
  7. if ( ! function_exists( 'is_plugin_active' ) ) {
  8. require_once ABSPATH . 'wp-admin/includes/plugin.php';
  9. }
  10. // phpcs:ignore
  11. $pro_version = false;
  12. if ( is_plugin_active( 'ghostkit-pro/class-ghost-kit-pro.php' ) ) {
  13. // phpcs:ignore
  14. $pro_data = get_plugin_data( ABSPATH . 'wp-content/plugins/ghostkit-pro/class-ghost-kit-pro.php' );
  15. // phpcs:ignore
  16. $pro_version = isset( $pro_data['Version'] ) ? $pro_data['Version'] : false;
  17. }
  18. if ( $pro_version && version_compare( $pro_version, '1.6.2', '<=' ) ) {
  19. require_once $this->plugin_path . 'classes/class-breakpoints-fallback.php';
  20. }
  21. if ( ! class_exists( 'GhostKit_Breakpoints' ) ) {
  22. /**
  23. * GhostKit_Breakpoints class
  24. */
  25. // phpcs:ignore
  26. class GhostKit_Breakpoints {
  27. /**
  28. * Extra Small Default Breakpoint.
  29. *
  30. * @var int
  31. */
  32. protected static $default_xs = 576;
  33. /**
  34. * Mobile Default Breakpoint.
  35. *
  36. * @var int
  37. */
  38. protected static $default_sm = 768;
  39. /**
  40. * Tablet Breakpoint.
  41. *
  42. * @var int
  43. */
  44. protected static $default_md = 992;
  45. /**
  46. * Desktop Breakpoint.
  47. *
  48. * @var int
  49. */
  50. protected static $default_lg = 1200;
  51. /**
  52. * Database saved hash option Name.
  53. *
  54. * @var string
  55. */
  56. protected $database_saved_hash_option_name = 'ghostkit_saved_breakpoints_hash';
  57. /**
  58. * Plugin name.
  59. *
  60. * @var string
  61. */
  62. protected $plugin_name = '@@plugin_name';
  63. /**
  64. * Plugin version.
  65. *
  66. * @var string
  67. */
  68. protected $plugin_version = '@@plugin_version';
  69. /**
  70. * Scss Configurations.
  71. *
  72. * @var array
  73. */
  74. protected $scss_configs = array(
  75. 'gutenberg/style.scss',
  76. 'gutenberg/editor.scss',
  77. 'gutenberg/blocks/*/styles/style.scss',
  78. );
  79. /**
  80. * Compile Scss Configurations.
  81. *
  82. * @var array
  83. */
  84. protected $compile_scss_configs;
  85. /**
  86. * Background breakpoints processing.
  87. *
  88. * @var object
  89. */
  90. protected $breakpoints_background_process;
  91. /**
  92. * GhostKit_Breakpoints constructor.
  93. */
  94. public function __construct() {
  95. if ( ! class_exists( 'GhostKit_Breakpoints_Background' ) ) {
  96. // breakpoints background.
  97. require_once __DIR__ . '/class-breakpoints-background.php';
  98. }
  99. $this->compile_scss_configs = $this->get_compile_scss_configs();
  100. $this->breakpoints_background_process = new GhostKit_Breakpoints_Background();
  101. add_filter( 'style_loader_src', array( $this, 'change_style_src_to_compile' ), 10, 1 );
  102. add_action( 'gkt_before_assets_register', array( $this, 'maybe_compile_scss_files' ) );
  103. }
  104. /**
  105. * Get plugin path.
  106. *
  107. * @return string
  108. */
  109. public function get_plugin_path() {
  110. return ghostkit()->plugin_path;
  111. }
  112. /**
  113. * Get plugin url.
  114. *
  115. * @return string
  116. */
  117. public function get_plugin_url() {
  118. return ghostkit()->plugin_url;
  119. }
  120. /**
  121. * Get compile scss configurations.
  122. *
  123. * @return array
  124. */
  125. protected function get_compile_scss_configs() {
  126. $plugin_path = $this->get_plugin_path();
  127. $upload_dir = wp_upload_dir();
  128. $compile_scss_configs = array();
  129. $scss_paths = apply_filters( 'gkt_scss_paths', $plugin_path );
  130. $scss_configs = apply_filters( 'gkt_scss_configs', $this->scss_configs );
  131. foreach ( $scss_configs as $scss_config ) {
  132. if ( is_array( $scss_paths ) ) {
  133. foreach ( $scss_paths as $path ) {
  134. $compile_scss_configs = $this->get_parsed_scss_files( $compile_scss_configs, $path, $upload_dir, $scss_config );
  135. }
  136. } else {
  137. $compile_scss_configs = $this->get_parsed_scss_files( $compile_scss_configs, $scss_paths, $upload_dir, $scss_config );
  138. }
  139. }
  140. return $compile_scss_configs;
  141. }
  142. /**
  143. * Get parsed array of scss files
  144. *
  145. * @param array $compile_scss_configs - Array of config width scss files.
  146. * @param string $scss_path - Path to scss files.
  147. * @param string $upload_dir - Uploas WP dir.
  148. * @param string $scss_config - File search mask.
  149. * @return array
  150. */
  151. protected function get_parsed_scss_files( &$compile_scss_configs, $scss_path, $upload_dir, $scss_config ) {
  152. foreach ( glob( $scss_path . $scss_config ) as $template ) {
  153. $output_file = str_replace( $scss_path, $upload_dir['basedir'] . '/' . $this->plugin_name . '/', $template );
  154. $output_file = str_replace( '.scss', '.min.css', $output_file );
  155. $compile_scss_configs[] = array(
  156. 'input_file' => $template,
  157. 'output_file' => $output_file,
  158. );
  159. }
  160. return $compile_scss_configs;
  161. }
  162. /**
  163. * Change style src to compile css files.
  164. *
  165. * @param string $src - Url to style.
  166. * @return string
  167. */
  168. public function change_style_src_to_compile( $src ) {
  169. $plugin_url = $this->get_plugin_url();
  170. $breakpoints = self::get_breakpoints();
  171. $breakpoints_hash = $this->get_breakpoints_hash( $breakpoints );
  172. $default_breakpoints_hash = $this->get_default_breakpoints_hash();
  173. if ( $breakpoints_hash !== $default_breakpoints_hash ) {
  174. $is_plugin_file = strstr( $src, $plugin_url );
  175. if ( $is_plugin_file ) {
  176. $configs = $this->compile_scss_configs;
  177. $relative_uri = str_replace( $plugin_url, '', $is_plugin_file );
  178. $relative_path = str_replace( '?ver=' . $this->plugin_version, '', $relative_uri );
  179. $upload_dir = wp_upload_dir();
  180. $output_file = $upload_dir['basedir'] . '/' . $this->plugin_name . '/' . $relative_path;
  181. foreach ( $configs as $config ) {
  182. if (
  183. $config['output_file'] === $output_file &&
  184. file_exists( $output_file )
  185. ) {
  186. $src = $upload_dir['baseurl'] . '/' . $this->plugin_name . '/' . $relative_uri;
  187. }
  188. }
  189. }
  190. }
  191. return $src;
  192. }
  193. /**
  194. * Get Breakpoints.
  195. */
  196. public static function get_breakpoints() {
  197. $xs = self::get_breakpoint_xs();
  198. $xs = ( ! empty( $xs ) && $xs ) ? $xs : self::$default_xs;
  199. $sm = self::get_breakpoint_sm();
  200. $sm = ( ! empty( $sm ) && $sm ) ? $sm : self::$default_sm;
  201. $md = self::get_breakpoint_md();
  202. $md = ( ! empty( $md ) && $md ) ? $md : self::$default_md;
  203. $lg = self::get_breakpoint_lg();
  204. $lg = ( ! empty( $lg ) && $lg ) ? $lg : self::$default_lg;
  205. return array(
  206. 'xs' => $xs,
  207. 'sm' => $sm,
  208. 'md' => $md,
  209. 'lg' => $lg,
  210. );
  211. }
  212. /**
  213. * Get default breakpoints.
  214. *
  215. * @return array
  216. */
  217. public static function get_default_breakpoints() {
  218. return array(
  219. 'xs' => self::get_default_breakpoint_xs(),
  220. 'sm' => self::get_default_breakpoint_sm(),
  221. 'md' => self::get_default_breakpoint_md(),
  222. 'lg' => self::get_default_breakpoint_lg(),
  223. );
  224. }
  225. /**
  226. * Get breakpoints Hash
  227. *
  228. * @param array $breakpoints - Breakpoints.
  229. * @return string
  230. */
  231. protected function get_breakpoints_hash( $breakpoints ) {
  232. return md5(
  233. wp_json_encode(
  234. array_merge(
  235. $breakpoints,
  236. array(
  237. $this->plugin_version,
  238. )
  239. )
  240. )
  241. );
  242. }
  243. /**
  244. * Get default breakpoints Hash.
  245. *
  246. * @return string
  247. */
  248. protected function get_default_breakpoints_hash() {
  249. return $this->get_breakpoints_hash(
  250. array(
  251. 'xs' => self::$default_xs,
  252. 'sm' => self::$default_sm,
  253. 'md' => self::$default_md,
  254. 'lg' => self::$default_lg,
  255. )
  256. );
  257. }
  258. /**
  259. * Styles may need to be compiled if breakpoints have been changed.
  260. *
  261. * @return void
  262. */
  263. public function maybe_compile_scss_files() {
  264. $breakpoints = self::get_breakpoints();
  265. $breakpoints_hash = $this->get_breakpoints_hash( $breakpoints );
  266. $default_breakpoints_hash = $this->get_default_breakpoints_hash();
  267. $saved_breakpoints_hash = get_option( $this->database_saved_hash_option_name );
  268. if (
  269. $breakpoints_hash !== $saved_breakpoints_hash &&
  270. $breakpoints_hash !== $default_breakpoints_hash
  271. ) {
  272. $compile_scss_configs = $this->compile_scss_configs;
  273. $breakpoints = self::get_breakpoints();
  274. $variables = array(
  275. 'media-xs' => $breakpoints['xs'] . 'px',
  276. 'media-sm' => $breakpoints['sm'] . 'px',
  277. 'media-md' => $breakpoints['md'] . 'px',
  278. 'media-lg' => $breakpoints['lg'] . 'px',
  279. );
  280. foreach ( $compile_scss_configs as $compile_scss_config ) {
  281. $scss_config_arguments = array_merge(
  282. $compile_scss_config,
  283. array(
  284. 'variables' => $variables,
  285. )
  286. );
  287. if ( ! file_exists( $compile_scss_config['output_file'] ) ) {
  288. new GhostKit_Scss_Compiler( $scss_config_arguments );
  289. } else {
  290. $this->breakpoints_background_process->push_to_queue( $scss_config_arguments );
  291. }
  292. }
  293. $this->breakpoints_background_process->save()->dispatch();
  294. update_option( $this->database_saved_hash_option_name, $breakpoints_hash );
  295. }
  296. }
  297. /**
  298. * Get Default Extra Small Breakpoint.
  299. *
  300. * @return int
  301. */
  302. public static function get_default_breakpoint_xs() {
  303. return apply_filters( 'gkt_default_breakpoint_xs', self::$default_xs );
  304. }
  305. /**
  306. * Get Extra Small Breakpoint.
  307. *
  308. * @return int
  309. */
  310. public static function get_breakpoint_xs() {
  311. return apply_filters( 'gkt_breakpoint_xs', self::get_default_breakpoint_xs() );
  312. }
  313. /**
  314. * Get Default Mobile Breakpoint.
  315. *
  316. * @return int
  317. */
  318. public static function get_default_breakpoint_sm() {
  319. return apply_filters( 'gkt_default_breakpoint_sm', self::$default_sm );
  320. }
  321. /**
  322. * Get Mobile Breakpoint.
  323. *
  324. * @return int
  325. */
  326. public static function get_breakpoint_sm() {
  327. return apply_filters( 'gkt_breakpoint_sm', self::get_default_breakpoint_sm() );
  328. }
  329. /**
  330. * Get Default Tablet Breakpoint.
  331. *
  332. * @return int
  333. */
  334. public static function get_default_breakpoint_md() {
  335. return apply_filters( 'gkt_default_breakpoint_md', self::$default_md );
  336. }
  337. /**
  338. * Get Tablet Breakpoint.
  339. *
  340. * @return int
  341. */
  342. public static function get_breakpoint_md() {
  343. return apply_filters( 'gkt_breakpoint_md', self::get_default_breakpoint_md() );
  344. }
  345. /**
  346. * Get Default Desktop Breakpoint.
  347. *
  348. * @return int
  349. */
  350. public static function get_default_breakpoint_lg() {
  351. return apply_filters( 'gkt_default_breakpoint_lg', self::$default_lg );
  352. }
  353. /**
  354. * Get Desktop Breakpoint.
  355. *
  356. * @return int
  357. */
  358. public static function get_breakpoint_lg() {
  359. return apply_filters( 'gkt_breakpoint_lg', self::get_default_breakpoint_lg() );
  360. }
  361. }
  362. new GhostKit_Breakpoints();
  363. }