Child Theme Configurator - Version 1.6.5.2

Version Description

  • Fix: Empty functions file created causing inserted markers to be output to browser.
  • Fix: check for closed PHP tag in functions file prior to inserting markers
Download this release

Release Info

Developer lilaeamedia
Plugin Icon 128x128 Child Theme Configurator
Version 1.6.5.2
Comparing to
See all releases

Code changes from version 1.6.5.1 to 1.6.5.2

child-theme-configurator.php CHANGED
@@ -6,7 +6,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
6
  Plugin Name: Child Theme Configurator
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
  Description: Create a Child Theme and customize the stylesheet and templates. Fast CSS editor lets you search, preview and modify by selector, rule or value.
9
- Version: 1.6.5.1
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
@@ -20,7 +20,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
20
  define( 'LILAEAMEDIA_URL', "http://www.lilaeamedia.com" );
21
  defined( 'CHLD_THM_CFG_OPTIONS' ) or
22
  define( 'CHLD_THM_CFG_OPTIONS', 'chld_thm_cfg_options' );
23
- define( 'CHLD_THM_CFG_VERSION', '1.6.5.1' );
24
  define( 'CHLD_THM_CFG_MIN_WP_VERSION', '3.7' );
25
  defined( 'CHLD_THM_CFG_BPSEL' ) or
26
  define( 'CHLD_THM_CFG_BPSEL', '2500' );
6
  Plugin Name: Child Theme Configurator
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
  Description: Create a Child Theme and customize the stylesheet and templates. Fast CSS editor lets you search, preview and modify by selector, rule or value.
9
+ Version: 1.6.5.2
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
20
  define( 'LILAEAMEDIA_URL', "http://www.lilaeamedia.com" );
21
  defined( 'CHLD_THM_CFG_OPTIONS' ) or
22
  define( 'CHLD_THM_CFG_OPTIONS', 'chld_thm_cfg_options' );
23
+ define( 'CHLD_THM_CFG_VERSION', '1.6.5.2' );
24
  define( 'CHLD_THM_CFG_MIN_WP_VERSION', '3.7' );
25
  defined( 'CHLD_THM_CFG_BPSEL' ) or
26
  define( 'CHLD_THM_CFG_BPSEL', '2500' );
includes/class-ctc-css.php CHANGED
@@ -6,7 +6,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
6
  Class: ChildThemeConfiguratorCSS
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
  Description: Handles all CSS output, parsing, normalization
9
- Version: 1.6.5.1
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
@@ -1274,8 +1274,11 @@ class ChildThemeConfiguratorCSS {
1274
  if ( 'read' == $permission && !is_file( $stylesheet ) ):
1275
  $this->ctc()->debug( 'read: no file!', __FUNCTION__ );
1276
  return FALSE;
 
 
 
1277
  elseif ( 'search' == $permission && !is_dir( $stylesheet ) ):
1278
- $this->ctc()->debug( 'read: no dir!', __FUNCTION__ );
1279
  return FALSE;
1280
  endif;
1281
  // check if in themes dir;
6
  Class: ChildThemeConfiguratorCSS
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
  Description: Handles all CSS output, parsing, normalization
9
+ Version: 1.6.5.2
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
1274
  if ( 'read' == $permission && !is_file( $stylesheet ) ):
1275
  $this->ctc()->debug( 'read: no file!', __FUNCTION__ );
1276
  return FALSE;
1277
+ elseif ( 'write' == $permission && !is_dir( dirname( $stylesheet ) ) ):
1278
+ $this->ctc()->debug( 'write: no dir!', __FUNCTION__ );
1279
+ return FALSE;
1280
  elseif ( 'search' == $permission && !is_dir( $stylesheet ) ):
1281
+ $this->ctc()->debug( 'search: no dir!', __FUNCTION__ );
1282
  return FALSE;
1283
  endif;
1284
  // check if in themes dir;
includes/class-ctc-ui.php CHANGED
@@ -5,7 +5,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
5
  Class: Child_Theme_Configurator_UI
6
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
7
  Description: Handles the plugin User Interface
8
- Version: 1.6.5.1
9
  Author: Lilaea Media
10
  Author URI: http://www.lilaeamedia.com/
11
  Text Domain: chld_thm_cfg
5
  Class: Child_Theme_Configurator_UI
6
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
7
  Description: Handles the plugin User Interface
8
+ Version: 1.6.5.2
9
  Author: Lilaea Media
10
  Author URI: http://www.lilaeamedia.com/
11
  Text Domain: chld_thm_cfg
includes/class-ctc.php CHANGED
@@ -6,7 +6,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
6
  Class: Child_Theme_Configurator
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
  Description: Main Controller Class
9
- Version: 1.6.5.1
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
@@ -104,7 +104,7 @@ class ChildThemeConfiguratorAdmin {
104
  $this->ui->render();
105
  }
106
  function enqueue_scripts() {
107
- wp_enqueue_style( 'chld-thm-cfg-admin', CHLD_THM_CFG_URL . 'css/chld-thm-cfg.css', array(), '1.6.5.1' );
108
 
109
  // we need to use local jQuery UI Widget/Menu/Selectmenu 1.11.2 because selectmenu is not included in < 1.11.2
110
  // this will be updated in a later release to use WP Core scripts when it is widely adopted
@@ -519,7 +519,7 @@ class ChildThemeConfiguratorAdmin {
519
  $varname = end( $varparts );
520
  ${$varname} = empty( $_POST[ 'ctc_' . $configfield ] ) ? '' :
521
  sanitize_text_field( $_POST[ 'ctc_' . $configfield ] );
522
-
523
  endforeach;
524
 
525
  // legacy plugin extension needs parent/child values but this version disables the inputs
@@ -546,11 +546,6 @@ class ChildThemeConfiguratorAdmin {
546
  if ( empty( $name ) ):
547
  $name = ucfirst( $child );
548
  endif;
549
- if ( FALSE === $this->verify_child_dir( $child ) ):
550
- $this->errors[] = __( 'Your theme directories are not writable.', 'chld_thm_cfg' );
551
- add_action( 'admin_notices', array( $this, 'writable_notice' ) );
552
- endif;
553
-
554
  // if this is a shiny brand new child theme certain rules apply
555
  if ( 'new' == $type ):
556
  if ( empty( $template ) && empty( $name ) ):
@@ -564,6 +559,11 @@ class ChildThemeConfiguratorAdmin {
564
  endif;
565
  endif;
566
  endif;
 
 
 
 
 
567
  // if no errors so far, we are good to create child theme
568
  if ( empty( $this->errors ) ):
569
  $this->css = new ChildThemeConfiguratorCSS();
@@ -694,7 +694,7 @@ class ChildThemeConfiguratorAdmin {
694
  }
695
 
696
  function update_redirect( $msg = 1 ) {
697
- if ( empty( $this->is_ajax ) ):
698
  $ctcpage = apply_filters( 'chld_thm_cfg_admin_page', CHLD_THM_CFG_MENU );
699
  wp_safe_redirect(
700
  ( is_multisite() ?
@@ -706,10 +706,17 @@ class ChildThemeConfiguratorAdmin {
706
  }
707
 
708
  function verify_child_dir( $path ) {
709
- if ( !$this->fs ) return FALSE; // return if no filesystem access
 
 
 
 
710
  global $wp_filesystem;
711
  $themedir = $wp_filesystem->find_folder( get_theme_root() );
712
- if ( ! $wp_filesystem->is_writable( $themedir ) ) return FALSE;
 
 
 
713
  $childparts = explode( '/', $this->normalize_path( $path ) );
714
  while ( count( $childparts ) ):
715
  $subdir = array_shift( $childparts );
@@ -717,12 +724,15 @@ class ChildThemeConfiguratorAdmin {
717
  $themedir = trailingslashit( $themedir ) . $subdir;
718
  if ( ! $wp_filesystem->is_dir( $themedir ) ):
719
  if ( ! $wp_filesystem->mkdir( $themedir, FS_CHMOD_DIR ) ):
 
720
  return FALSE;
721
  endif;
722
  elseif ( ! $wp_filesystem->is_writable( $themedir ) ):
 
723
  return FALSE;
724
  endif;
725
  endwhile;
 
726
  return TRUE;
727
  }
728
 
@@ -732,8 +742,8 @@ class ChildThemeConfiguratorAdmin {
732
  // Exit if accessed directly
733
  if ( !defined( 'ABSPATH' ) ) exit;
734
  ";
735
- if ( FALSE === $this->write_child_file( 'functions.php', $contents )
736
- || FALSE === $this->write_child_file( 'style.css', $this->css->get_css_header() ) ) return FALSE;
737
  }
738
 
739
  function enqueue_parent_code(){
@@ -761,21 +771,50 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
761
  * but it does not use wp_filesystem API!!!???
762
  */
763
  function insert_with_markers( $filename, $marker, $insertion ) {
764
- if ( !$this->fs ) return FALSE; // return if no filesystem access
765
- // make sure file exists with php header
766
- $this->add_base_files( $this );
 
 
 
 
 
767
  global $wp_filesystem;
768
  if( !$wp_filesystem->exists( $this->fspath( $filename ) ) ):
769
- $markerdata = FALSE;
770
- else:
 
 
771
  // get_contents_array returns extra linefeeds so just split it ourself
772
  $markerdata = explode( "\n", $wp_filesystem->get_contents( $this->fspath( $filename ) ) );
773
- endif;
774
  $newfile = '';
 
 
775
  $foundit = false;
776
- if ( $markerdata ) {
 
777
  $state = true;
778
  foreach ( $markerdata as $n => $markerline ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
779
  if ( strpos( $markerline, '// BEGIN ' . $marker ) !== false )
780
  $state = false;
781
  if ( $state ):
@@ -794,13 +833,26 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
794
  $foundit = true;
795
  endif;
796
  }
797
- }
798
- if ( !$foundit ) {
 
 
 
 
 
 
 
 
 
 
 
 
799
  $newfile .= "\n// BEGIN {$marker}\n";
800
  foreach ( $insertion as $insertline )
801
  $newfile .= "{$insertline}\n";
802
  $newfile .= "// END {$marker}\n";
803
- }
 
804
  if ( FALSE === $wp_filesystem->put_contents( $this->fspath( $filename ), $newfile ) ) return FALSE;
805
  }
806
 
@@ -810,10 +862,10 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
810
  return FALSE; // return if no filesystem access
811
  endif;
812
  global $wp_filesystem;
813
- $file = $this->fspath( $this->css->is_file_ok( $this->css->get_child_target( $file ), 'write' ) );
 
814
  $this->debug( 'Writing to filesystem: ' . $file, __FUNCTION__ );
815
- if ( $file && !$wp_filesystem->exists( $file ) ):
816
- if ( FALSE === $wp_filesystem->put_contents( $file, $contents ) ):
817
  $this->debug( 'Filesystem write failed.', __FUNCTION__ );
818
  return FALSE;
819
  endif;
@@ -821,6 +873,10 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
821
  $this->debug( 'File exists.', __FUNCTION__ );
822
  return FALSE;
823
  endif;
 
 
 
 
824
  $this->debug( 'Filesystem write successful.', __FUNCTION__ );
825
  }
826
 
@@ -830,7 +886,10 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
830
  }
831
 
832
  function copy_parent_file( $file, $ext = 'php' ) {
833
- if ( !$this->fs ) return FALSE; // return if no filesystem access
 
 
 
834
  global $wp_filesystem;
835
  $parent_file = NULL;
836
  if ( 'screenshot' == $file ):
@@ -851,6 +910,7 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
851
  // return true if file already exists
852
  if ( $wp_filesystem->exists( $this->fspath( $child_file ) ) ) return TRUE;
853
  $child_dir = dirname( $this->theme_basename( '', $child_file ) );
 
854
  if ( $parent_file // sanity check
855
  && $child_file // sanity check
856
  && $this->verify_child_dir( $child_dir ) //create child subdir if necessary
@@ -859,14 +919,19 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
859
  }
860
 
861
  function delete_child_file( $file, $ext = 'php' ) {
862
- if ( !$this->fs ) return FALSE; // return if no filesystem access
 
 
 
863
  global $wp_filesystem;
864
  // verify file is in child theme and exists before removing.
865
  $file = ( 'img' == $ext ? $file : $file . '.' . $ext );
866
- $child_file = $this->fspath( $this->css->is_file_ok( $this->css->get_child_target( $file ), 'write' ) );
867
- if ( $wp_filesystem->exists( $child_file ) ):
868
- if ( !$wp_filesystem->delete( $child_file ) ) return FALSE;
869
  endif;
 
 
870
  }
871
 
872
  function get_files( $theme, $type = 'template' ) {
@@ -974,6 +1039,7 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
974
  $childpath = $fsthemedir . trailingslashit( $child ) . $childfile;
975
  $newpath = $fsthemedir . $newfile;
976
  if ( $copy ):
 
977
  if ( $this->verify_child_dir( is_dir( $file ) ? $newfile : dirname( $newfile ) ) ):
978
  if ( is_file( $file ) && !$wp_filesystem->copy( $childpath, $newpath ) ):
979
  $errors[] = 'could not copy ' . $newpath;
@@ -1043,6 +1109,7 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
1043
  $target_file = ( '' == $subdir ?
1044
  preg_replace( "%^.+(\.\w+)$%", "screenshot$1", basename( $source_file ) ) :
1045
  trailingslashit( $subdir ) . basename( $source_file ) );
 
1046
  if ( FALSE !== $this->verify_child_dir( trailingslashit( $this->css->get_prop( 'child' ) ) . $subdir ) ):
1047
  $source_path = $this->fspath( $this->uploads_fullpath( $source_file ) );
1048
  if ( $target_path = $this->css->is_file_ok( $this->css->get_child_target( $target_file ), 'write' ) ):
@@ -1200,6 +1267,7 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
1200
 
1201
  // sanitize the crap out of the target data -- it will be used to create paths
1202
  $path = $this->normalize_path( preg_replace( "%[^\w\\//\-]%", '', sanitize_text_field( $child . $path ) ) );
 
1203
  if ( ( 'dir' == $type && FALSE === $this->verify_child_dir( $path ) )
1204
  || ( 'dir' != $type && FALSE === $this->write_child_file( $path, '' ) ) ):
1205
  //$this->errors[] = __( 'Your theme directories are not writable.', 'chld_thm_cfg_plugins' );
6
  Class: Child_Theme_Configurator
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
  Description: Main Controller Class
9
+ Version: 1.6.5.2
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
104
  $this->ui->render();
105
  }
106
  function enqueue_scripts() {
107
+ wp_enqueue_style( 'chld-thm-cfg-admin', CHLD_THM_CFG_URL . 'css/chld-thm-cfg.css', array(), '1.6.5.2' );
108
 
109
  // we need to use local jQuery UI Widget/Menu/Selectmenu 1.11.2 because selectmenu is not included in < 1.11.2
110
  // this will be updated in a later release to use WP Core scripts when it is widely adopted
519
  $varname = end( $varparts );
520
  ${$varname} = empty( $_POST[ 'ctc_' . $configfield ] ) ? '' :
521
  sanitize_text_field( $_POST[ 'ctc_' . $configfield ] );
522
+ $this->debug( 'Extracting var ' . $varname . ' from ctc_' . $configfield . ' value: ' . ${$varname} , __FUNCTION__ );
523
  endforeach;
524
 
525
  // legacy plugin extension needs parent/child values but this version disables the inputs
546
  if ( empty( $name ) ):
547
  $name = ucfirst( $child );
548
  endif;
 
 
 
 
 
549
  // if this is a shiny brand new child theme certain rules apply
550
  if ( 'new' == $type ):
551
  if ( empty( $template ) && empty( $name ) ):
559
  endif;
560
  endif;
561
  endif;
562
+ if ( FALSE === $this->verify_child_dir( $child ) ):
563
+ $this->errors[] = __( 'Your theme directories are not writable.', 'chld_thm_cfg' );
564
+ add_action( 'admin_notices', array( $this, 'writable_notice' ) );
565
+ endif;
566
+
567
  // if no errors so far, we are good to create child theme
568
  if ( empty( $this->errors ) ):
569
  $this->css = new ChildThemeConfiguratorCSS();
694
  }
695
 
696
  function update_redirect( $msg = 1 ) {
697
+ if ( empty( $this->is_ajax ) && !$this->is_debug ):
698
  $ctcpage = apply_filters( 'chld_thm_cfg_admin_page', CHLD_THM_CFG_MENU );
699
  wp_safe_redirect(
700
  ( is_multisite() ?
706
  }
707
 
708
  function verify_child_dir( $path ) {
709
+ $this->debug( 'Verifying child dir: ' . $path, __FUNCTION__ );
710
+ if ( !$this->fs ):
711
+ $this->debug( 'No filesystem access.', __FUNCTION__ );
712
+ return FALSE; // return if no filesystem access
713
+ endif;
714
  global $wp_filesystem;
715
  $themedir = $wp_filesystem->find_folder( get_theme_root() );
716
+ if ( ! $wp_filesystem->is_writable( $themedir ) ):
717
+ $this->debug( 'Directory not writable: ' . $themedir, __FUNCTION__ );
718
+ return FALSE;
719
+ endif;
720
  $childparts = explode( '/', $this->normalize_path( $path ) );
721
  while ( count( $childparts ) ):
722
  $subdir = array_shift( $childparts );
724
  $themedir = trailingslashit( $themedir ) . $subdir;
725
  if ( ! $wp_filesystem->is_dir( $themedir ) ):
726
  if ( ! $wp_filesystem->mkdir( $themedir, FS_CHMOD_DIR ) ):
727
+ $this->debug( 'Could not make directory: ' . $themedir, __FUNCTION__ );
728
  return FALSE;
729
  endif;
730
  elseif ( ! $wp_filesystem->is_writable( $themedir ) ):
731
+ $this->debug( 'Directory not writable: ' . $themedir, __FUNCTION__ );
732
  return FALSE;
733
  endif;
734
  endwhile;
735
+ $this->debug( 'Child dir verified: ' . $themedir, __FUNCTION__ );
736
  return TRUE;
737
  }
738
 
742
  // Exit if accessed directly
743
  if ( !defined( 'ABSPATH' ) ) exit;
744
  ";
745
+ $this->write_child_file( 'functions.php', $contents );
746
+ $this->write_child_file( 'style.css', $this->css->get_css_header() );
747
  }
748
 
749
  function enqueue_parent_code(){
771
  * but it does not use wp_filesystem API!!!???
772
  */
773
  function insert_with_markers( $filename, $marker, $insertion ) {
774
+ if ( count( $this->errors ) ):
775
+ $this->debug( 'Errors detected, returning', __FUNCTION__ );
776
+ return FALSE;
777
+ endif;
778
+ if ( !$this->fs ):
779
+ $this->debug( 'No filesystem access.', __FUNCTION__ );
780
+ return FALSE; // return if no filesystem access
781
+ endif;
782
  global $wp_filesystem;
783
  if( !$wp_filesystem->exists( $this->fspath( $filename ) ) ):
784
+ // make sure file exists with php header
785
+ $this->debug( 'No functions file, creating...', __FUNCTION__ );
786
+ $this->add_base_files( $this );
787
+ endif;
788
  // get_contents_array returns extra linefeeds so just split it ourself
789
  $markerdata = explode( "\n", $wp_filesystem->get_contents( $this->fspath( $filename ) ) );
 
790
  $newfile = '';
791
+ $phpopen = 0;
792
+ $in_comment = 0;
793
  $foundit = false;
794
+ $lasttoken = '';
795
+ if ( $markerdata ):
796
  $state = true;
797
  foreach ( $markerdata as $n => $markerline ) {
798
+ // update open state
799
+ $openstars = 0;
800
+ $closestars = 0;
801
+ // remove double slash comment to end of line
802
+ $str = preg_replace( "/\/\/.*$/", '', $markerline );
803
+ preg_match_all("/(<\?|\?>|\*\/|\/\*)/", $str, $matches );
804
+ if ( $matches ):
805
+ foreach ( $matches[1] as $token ):
806
+ $lasttoken = $token;
807
+ if ( '/*' == $token ):
808
+ $in_comment = 1;
809
+ elseif ( '*/' == $token ):
810
+ $in_comment = 0;
811
+ elseif ( '<?' == $token && !$in_comment ):
812
+ $phpopen = 1;
813
+ elseif ( '?>' == $token && !$in_comment ):
814
+ $phpopen = 0;
815
+ endif;
816
+ endforeach;
817
+ endif;
818
  if ( strpos( $markerline, '// BEGIN ' . $marker ) !== false )
819
  $state = false;
820
  if ( $state ):
833
  $foundit = true;
834
  endif;
835
  }
836
+ else:
837
+ $this->debug( 'Could not parse functions file', __FUNCTION__ );
838
+ return FALSE;
839
+ endif;
840
+ if ( $foundit ):
841
+ $this->debug( 'Found marker, replaced inline', __FUNCTION__ );
842
+ else:
843
+ // verify there is no PHP close tag at end of file
844
+ if ( ! $phpopen ):
845
+ $this->debug( 'PHP not open', __FUNCTION__ );
846
+ $this->errors[] = 'A closing PHP tag was detected in Child theme functions file so "Parent Stylesheet Handling" option was not configured. Closing PHP at the end of the file is discouraged as it can cause premature HTTP headers. Please edit <code>functions.php</code> and remove the final <code>?&gt;</code> tag.';
847
+ return FALSE;
848
+ //$newfile .= '<?php' . LF;
849
+ endif;
850
  $newfile .= "\n// BEGIN {$marker}\n";
851
  foreach ( $insertion as $insertline )
852
  $newfile .= "{$insertline}\n";
853
  $newfile .= "// END {$marker}\n";
854
+ endif;
855
+ $this->debug( 'Writing new functions file...', __FUNCTION__ );
856
  if ( FALSE === $wp_filesystem->put_contents( $this->fspath( $filename ), $newfile ) ) return FALSE;
857
  }
858
 
862
  return FALSE; // return if no filesystem access
863
  endif;
864
  global $wp_filesystem;
865
+ if ( $file = $this->css->is_file_ok( $this->css->get_child_target( $file ), 'write' ) ):
866
+ if ( !$wp_filesystem->exists( $this->fspath( $file ) ) ):
867
  $this->debug( 'Writing to filesystem: ' . $file, __FUNCTION__ );
868
+ if ( FALSE === $wp_filesystem->put_contents( $this->fspath( $file ), $contents ) ):
 
869
  $this->debug( 'Filesystem write failed.', __FUNCTION__ );
870
  return FALSE;
871
  endif;
873
  $this->debug( 'File exists.', __FUNCTION__ );
874
  return FALSE;
875
  endif;
876
+ else:
877
+ $this->debug( 'No directory.', __FUNCTION__ );
878
+ return FALSE;
879
+ endif;
880
  $this->debug( 'Filesystem write successful.', __FUNCTION__ );
881
  }
882
 
886
  }
887
 
888
  function copy_parent_file( $file, $ext = 'php' ) {
889
+ if ( !$this->fs ):
890
+ $this->debug( 'No filesystem access.', __FUNCTION__ );
891
+ return FALSE; // return if no filesystem access
892
+ endif;
893
  global $wp_filesystem;
894
  $parent_file = NULL;
895
  if ( 'screenshot' == $file ):
910
  // return true if file already exists
911
  if ( $wp_filesystem->exists( $this->fspath( $child_file ) ) ) return TRUE;
912
  $child_dir = dirname( $this->theme_basename( '', $child_file ) );
913
+ $this->debug( 'Verifying child dir... ', __FUNCTION__ );
914
  if ( $parent_file // sanity check
915
  && $child_file // sanity check
916
  && $this->verify_child_dir( $child_dir ) //create child subdir if necessary
919
  }
920
 
921
  function delete_child_file( $file, $ext = 'php' ) {
922
+ if ( !$this->fs ):
923
+ $this->debug( 'No filesystem access.', __FUNCTION__ );
924
+ return FALSE; // return if no filesystem access
925
+ endif;
926
  global $wp_filesystem;
927
  // verify file is in child theme and exists before removing.
928
  $file = ( 'img' == $ext ? $file : $file . '.' . $ext );
929
+ if ( $child_file = $this->css->is_file_ok( $this->css->get_child_target( $file ), 'write' ) ):
930
+ if ( $wp_filesystem->exists( $this->fspath( $child_file ) ) )
931
+ if ( $wp_filesystem->delete( $this->fspath( $child_file ) ) ) return TRUE;
932
  endif;
933
+ $this->errors[] = __( 'Could not delete file.', 'chld_thm_cfg' );
934
+ $this->debug( 'Could not delete file', __FUNCTION__ );
935
  }
936
 
937
  function get_files( $theme, $type = 'template' ) {
1039
  $childpath = $fsthemedir . trailingslashit( $child ) . $childfile;
1040
  $newpath = $fsthemedir . $newfile;
1041
  if ( $copy ):
1042
+ $this->debug( 'Verifying child dir... ', __FUNCTION__ );
1043
  if ( $this->verify_child_dir( is_dir( $file ) ? $newfile : dirname( $newfile ) ) ):
1044
  if ( is_file( $file ) && !$wp_filesystem->copy( $childpath, $newpath ) ):
1045
  $errors[] = 'could not copy ' . $newpath;
1109
  $target_file = ( '' == $subdir ?
1110
  preg_replace( "%^.+(\.\w+)$%", "screenshot$1", basename( $source_file ) ) :
1111
  trailingslashit( $subdir ) . basename( $source_file ) );
1112
+ $this->debug( 'Verifying child dir... ', __FUNCTION__ );
1113
  if ( FALSE !== $this->verify_child_dir( trailingslashit( $this->css->get_prop( 'child' ) ) . $subdir ) ):
1114
  $source_path = $this->fspath( $this->uploads_fullpath( $source_file ) );
1115
  if ( $target_path = $this->css->is_file_ok( $this->css->get_child_target( $target_file ), 'write' ) ):
1267
 
1268
  // sanitize the crap out of the target data -- it will be used to create paths
1269
  $path = $this->normalize_path( preg_replace( "%[^\w\\//\-]%", '', sanitize_text_field( $child . $path ) ) );
1270
+ $this->debug( 'Verifying child dir... ', __FUNCTION__ );
1271
  if ( ( 'dir' == $type && FALSE === $this->verify_child_dir( $path ) )
1272
  || ( 'dir' != $type && FALSE === $this->write_child_file( $path, '' ) ) ):
1273
  //$this->errors[] = __( 'Your theme directories are not writable.', 'chld_thm_cfg_plugins' );
js/chld-thm-cfg.js CHANGED
@@ -2,7 +2,7 @@
2
  * Script: chld-thm-cfg.js
3
  * Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
4
  * Description: Handles jQuery, AJAX and other UI
5
- * Version: 1.6.5.1
6
  * Author: Lilaea Media
7
  * Author URI: http://www.lilaeamedia.com/
8
  * License: GPLv2
2
  * Script: chld-thm-cfg.js
3
  * Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
4
  * Description: Handles jQuery, AJAX and other UI
5
+ * Version: 1.6.5.2
6
  * Author: Lilaea Media
7
  * Author URI: http://www.lilaeamedia.com/
8
  * License: GPLv2
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
4
  Tags: child theme, customize, CSS, responsive, css editor, theme generator, stylesheet, customizer
5
  Requires at least: 3.9
6
  Tested up to: 4.1
7
- Stable tag: 1.6.5.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -256,6 +256,10 @@ https://www.youtube.com/watch?v=iBiiAgsK4G4
256
  7. Files tab
257
 
258
  == Changelog ==
 
 
 
 
259
  = 1.6.5.1 =
260
  * Fix: undefined constant LILAEAMEDIA_URL
261
  * Fix: logic to determine whether to display config notice
@@ -460,7 +464,7 @@ https://www.youtube.com/watch?v=iBiiAgsK4G4
460
  * Initial release.
461
 
462
  == Upgrade Notice ==
463
- 1.6.5.1 Fixes an undefined constant.
464
 
465
  == Override Parent Styles ==
466
 
4
  Tags: child theme, customize, CSS, responsive, css editor, theme generator, stylesheet, customizer
5
  Requires at least: 3.9
6
  Tested up to: 4.1
7
+ Stable tag: 1.6.5.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
256
  7. Files tab
257
 
258
  == Changelog ==
259
+ = 1.6.5.2 =
260
+ * Fix: Empty functions file created causing inserted markers to be output to browser.
261
+ * Fix: check for closed PHP tag in functions file prior to inserting markers
262
+
263
  = 1.6.5.1 =
264
  * Fix: undefined constant LILAEAMEDIA_URL
265
  * Fix: logic to determine whether to display config notice
464
  * Initial release.
465
 
466
  == Upgrade Notice ==
467
+ 1.6.5.2 Fixes a major bug in the creation of the child theme functions.php file. See changelog for details.
468
 
469
  == Override Parent Styles ==
470