function __construct($id, $name = NULL, $version = NULL)
 {
     parent::__construct($id, $name);
     $this->version($version);
 }
 /**
  * Saves the given theme id and css, making any necessary path and id changes to ensure the new theme is valid.
  * Echos 0 on failure, 1 on success and 2 on success and if paths have changed.
  */
 public static function save()
 {
     CrayonSettingsWP::load_settings();
     $oldID = stripslashes($_POST['id']);
     $name = stripslashes($_POST['name']);
     $css = stripslashes($_POST['css']);
     $change_settings = CrayonUtil::set_default($_POST['change_settings'], TRUE);
     $allow_edit = CrayonUtil::set_default($_POST['allow_edit'], TRUE);
     $allow_edit_stock_theme = CrayonUtil::set_default($_POST['allow_edit_stock_theme'], CRAYON_DEBUG);
     $delete = CrayonUtil::set_default($_POST['delete'], TRUE);
     $oldTheme = CrayonResources::themes()->get($oldID);
     if (!empty($oldID) && !empty($css) && !empty($name)) {
         // By default, expect a user theme to be saved - prevents editing stock themes
         // If in DEBUG mode, then allow editing stock themes.
         $user = $oldTheme !== NULL && $allow_edit_stock_theme ? $oldTheme->user() : TRUE;
         $oldPath = CrayonResources::themes()->path($oldID);
         $oldDir = CrayonResources::themes()->dirpath_for_id($oldID);
         // Create an instance to use functions, since late static binding is only available in 5.3 (PHP kinda sucks)
         $theme = CrayonResources::themes()->resource_instance('');
         $newID = $theme->clean_id($name);
         $name = CrayonResource::clean_name($newID);
         $newPath = CrayonResources::themes()->path($newID, $user);
         $newDir = CrayonResources::themes()->dirpath_for_id($newID, $user);
         $exists = CrayonResources::themes()->is_loaded($newID) || is_file($newPath) && is_file($oldPath);
         if ($exists && $oldPath != $newPath) {
             // Never allow overwriting a theme with a different id!
             echo -3;
             exit;
         }
         if ($oldPath == $newPath && $allow_edit === FALSE) {
             // Don't allow editing
             echo -4;
             exit;
         }
         // Create the new path if needed
         if (!is_dir($newDir)) {
             wp_mkdir_p($newDir);
             $imageSrc = $oldDir . 'images';
             if (is_dir($imageSrc)) {
                 try {
                     // Copy image folder
                     CrayonUtil::copyDir($imageSrc, $newDir . 'images', 'wp_mkdir_p');
                 } catch (Exception $e) {
                     CrayonLog::syslog($e->getMessage(), "THEME SAVE");
                 }
             }
         }
         $refresh = FALSE;
         $replaceID = $oldID;
         // Replace ids in the CSS
         if (!is_file($oldPath) || strpos($css, CrayonThemes::CSS_PREFIX . $oldID) === FALSE) {
             // The old path/id is no longer valid - something has gone wrong - we should refresh afterwards
             $refresh = TRUE;
         }
         // XXX This is case sensitive to avoid modifying text, but it means that CSS must be in lowercase
         $css = preg_replace('#(?<=' . CrayonThemes::CSS_PREFIX . ')' . $replaceID . '\\b#ms', $newID, $css);
         // Replace the name with the new one
         $info = self::getCSSInfo($css);
         $info['name'] = $name;
         $css = self::setCSSInfo($css, $info);
         $result = @file_put_contents($newPath, $css);
         $success = $result !== FALSE;
         if ($success && $oldPath !== $newPath) {
             if ($oldID !== CrayonThemes::DEFAULT_THEME && $delete) {
                 // Only delete the old path if it isn't the default theme
                 try {
                     // Delete the old path
                     CrayonUtil::deleteDir($oldDir);
                 } catch (Exception $e) {
                     CrayonLog::syslog($e->getMessage(), "THEME SAVE");
                 }
             }
             // Refresh
             echo 2;
         } else {
             if ($refresh) {
                 echo 2;
             } else {
                 if ($success) {
                     echo 1;
                 } else {
                     echo -2;
                 }
             }
         }
         // Set the new theme in settings
         if ($change_settings) {
             CrayonGlobalSettings::set(CrayonSettings::THEME, $newID);
             CrayonSettingsWP::save_settings();
         }
     } else {
         CrayonLog::syslog("{$oldID}={$oldID}\n\n{$name}={$name}", "THEME SAVE");
         echo -1;
     }
     exit;
 }