crayon-syntax-highlighter/util/theme-editor/theme_editor.php

880 lines
37 KiB
PHP
Raw Permalink Normal View History

2019-08-30 19:30:19 +02:00
<?php
class CrayonHTMLElement {
public $id;
public $class = '';
public $tag = 'div';
public $closed = FALSE;
public $contents = '';
public $attributes = array();
const CSS_INPUT_PREFIX = "crayon-theme-input-";
public static $borderStyles = array(
'none',
'hidden',
'dotted',
'dashed',
'solid',
'double',
'groove',
'ridge',
'inset',
'outset',
'inherit'
);
public function __construct($id) {
$this->id = $id;
}
public function addClass($class) {
$this->class .= ' ' . self::CSS_INPUT_PREFIX . $class;
}
public function addAttributes($atts) {
$this->attributes = array_merge($this->attributes, $atts);
}
public function attributeString() {
$str = '';
foreach ($this->attributes as $k => $v) {
$str .= "$k=\"$v\" ";
}
return $str;
}
public function __toString() {
return '<' . $this->tag . ' id="' . self::CSS_INPUT_PREFIX . $this->id . '" class="' . self::CSS_INPUT_PREFIX . $this->class . '" ' . $this->attributeString() . ($this->closed ? ' />' : ' >' . $this->contents . "</$this->tag>");
}
}
class CrayonHTMLInput extends CrayonHTMLElement {
public $name;
public $type;
public function __construct($id, $name = NULL, $value = '', $type = 'text') {
parent::__construct($id);
$this->tag = 'input';
$this->closed = TRUE;
if ($name === NULL) {
$name = CrayonUserResource::clean_name($id);
}
$this->name = $name;
$this->class .= $type;
$this->addAttributes(array(
'type' => $type,
'value' => $value
));
}
}
class CrayonHTMLSelect extends CrayonHTMLInput {
public $options;
public $selected = NULL;
public function __construct($id, $name = NULL, $value = '', $options = array()) {
parent::__construct($id, $name, 'select');
$this->tag = 'select';
$this->closed = FALSE;
$this->addOptions($options);
}
public function addOptions($options, $default = NULL) {
for ($i = 0; $i < count($options); $i++) {
$key = $options[$i];
$value = isset($options[$key]) ? $options[$key] : $key;
$this->options[$key] = $value;
}
if ($default === NULL && count($options) > 1) {
$this->attributes['data-default'] = $options[0];
} else {
$this->attributes['data-default'] = $default;
}
}
public function getOptionsString() {
$str = '';
foreach ($this->options as $k => $v) {
$selected = $this->selected == $k ? 'selected="selected"' : '';
$str .= "<option value=\"$k\" $selected>$v</option>";
}
return $str;
}
public function __toString() {
$this->contents = $this->getOptionsString();
return parent::__toString();
}
}
class CrayonHTMLSeparator extends CrayonHTMLElement {
public $name = '';
public function __construct($name) {
parent::__construct($name);
$this->name = $name;
}
}
class CrayonHTMLTitle extends CrayonHTMLSeparator {
}
class CrayonThemeEditorWP {
public static $attributes = NULL;
public static $attributeGroups = NULL;
public static $attributeGroupsInverse = NULL;
public static $attributeTypes = NULL;
public static $attributeTypesInverse = NULL;
public static $infoFields = NULL;
public static $infoFieldsInverse = NULL;
public static $settings = NULL;
public static $strings = NULL;
const ATTRIBUTE = 'attribute';
const RE_COMMENT = '#^\s*\/\*[\s\S]*?\*\/#msi';
public static function initFields() {
if (self::$infoFields === NULL) {
self::$infoFields = array(
// These are canonical and can't be translated, since they appear in the comments of the CSS
'name' => 'Name',
'description' => 'Description',
'version' => 'Version',
'author' => 'Author',
'url' => 'URL',
'original-author' => 'Original Author',
'notes' => 'Notes',
'maintainer' => 'Maintainer',
'maintainer-url' => 'Maintainer URL'
);
self::$infoFieldsInverse = CrayonUtil::array_flip(self::$infoFields);
// A map of CSS element name and property to name
self::$attributes = array();
// A map of CSS attribute to input type
self::$attributeGroups = array(
'color' => array('background', 'background-color', 'border-color', 'color', 'border-top-color', 'border-bottom-color', 'border-left-color', 'border-right-color'),
'size' => array('border-width'),
'border-style' => array('border-style', 'border-bottom-style', 'border-top-style', 'border-left-style', 'border-right-style')
);
self::$attributeGroupsInverse = CrayonUtil::array_flip(self::$attributeGroups);
// Mapping of input type to attribute group
self::$attributeTypes = array(
'select' => array('border-style', 'font-style', 'font-weight', 'text-decoration')
);
self::$attributeTypesInverse = CrayonUtil::array_flip(self::$attributeTypes);
}
}
public static function initSettings() {
CrayonSettingsWP::load_settings();
self::initFields();
self::initStrings();
if (self::$settings === NULL) {
self::$settings = array(
// Only things the theme editor needs
'cssThemePrefix' => CrayonThemes::CSS_PREFIX,
'cssInputPrefix' => CrayonHTMLElement::CSS_INPUT_PREFIX,
'attribute' => self::ATTRIBUTE,
'fields' => self::$infoFields,
'fieldsInverse' => self::$infoFieldsInverse,
'prefix' => 'crayon-theme-editor'
);
}
}
public static function initStrings() {
if (self::$strings === NULL) {
self::$strings = array(
// These appear only in the UI and can be translated
'userTheme' => crayon__("User-Defined Theme"),
'stockTheme' => crayon__("Stock Theme"),
'success' => crayon__("Success!"),
'fail' => crayon__("Failed!"),
'delete' => crayon__("Delete"),
'deleteThemeConfirm' => crayon__("Are you sure you want to delete the \"%s\" theme?"),
'deleteFail' => crayon__("Delete failed!"),
'duplicate' => crayon__("Duplicate"),
'newName' => crayon__("New Name"),
'duplicateFail' => crayon__("Duplicate failed!"),
'checkLog' => crayon__("Please check the log for details."),
'discardConfirm' => crayon__("Are you sure you want to discard all changes?"),
'editingTheme' => crayon__("Editing Theme: %s"),
'creatingTheme' => crayon__("Creating Theme: %s"),
'submit' => crayon__("Submit Your Theme"),
'submitText' => crayon__("Submit your User Theme for inclusion as a Stock Theme in Crayon! This will email me your theme - make sure it's considerably different from the stock themes :)"),
'message' => crayon__("Message"),
'submitMessage' => crayon__("Please include this theme in Crayon!"),
'submitSucceed' => crayon__("Submit was successful."),
'submitFail' => crayon__("Submit failed!"),
'borderStyles' => CrayonHTMLElement::$borderStyles
);
}
}
public static function admin_resources() {
global $CRAYON_VERSION;
self::initSettings();
$path = dirname(dirname(__FILE__));
wp_enqueue_script('cssjson_js', plugins_url(CRAYON_CSSJSON_JS, $path), $CRAYON_VERSION);
wp_enqueue_script('jquery_colorpicker_js', plugins_url(CRAYON_JS_JQUERY_COLORPICKER, $path), array('jquery', 'jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-tabs', 'jquery-ui-draggable', 'jquery-ui-dialog', 'jquery-ui-position', 'jquery-ui-mouse', 'jquery-ui-slider', 'jquery-ui-droppable', 'jquery-ui-selectable', 'jquery-ui-resizable'), $CRAYON_VERSION);
wp_enqueue_script('jquery_tinycolor_js', plugins_url(CRAYON_JS_TINYCOLOR, $path), array(), $CRAYON_VERSION);
if (CRAYON_MINIFY) {
wp_enqueue_script('crayon_theme_editor', plugins_url(CRAYON_THEME_EDITOR_JS, $path), array('jquery', 'crayon_js', 'crayon_admin_js', 'cssjson_js', 'jquery_colorpicker_js', 'jquery_tinycolor_js'), $CRAYON_VERSION);
} else {
wp_enqueue_script('crayon_theme_editor', plugins_url(CRAYON_THEME_EDITOR_JS, $path), array('jquery', 'crayon_util_js', 'crayon_admin_js', 'cssjson_js', 'jquery_colorpicker_js', 'jquery_tinycolor_js'), $CRAYON_VERSION);
}
wp_localize_script('crayon_theme_editor', 'CrayonThemeEditorSettings', self::$settings);
wp_localize_script('crayon_theme_editor', 'CrayonThemeEditorStrings', self::$strings);
wp_enqueue_style('crayon_theme_editor', plugins_url(CRAYON_THEME_EDITOR_STYLE, $path), array('wp-jquery-ui-dialog'), $CRAYON_VERSION);
wp_enqueue_style('jquery_colorpicker', plugins_url(CRAYON_CSS_JQUERY_COLORPICKER, $path), array(), $CRAYON_VERSION);
}
public static function form($inputs) {
$str = '<form class="' . self::$settings['prefix'] . '-form"><table>';
$sepCount = 0;
foreach ($inputs as $input) {
if ($input instanceof CrayonHTMLInput) {
$str .= self::formField($input->name, $input);
} else if ($input instanceof CrayonHTMLSeparator) {
$sepClass = '';
if ($input instanceof CrayonHTMLTitle) {
$sepClass .= ' title';
}
if ($sepCount == 0) {
$sepClass .= ' first';
}
$str .= '<tr class="separator' . $sepClass . '"><td colspan="2"><div class="content">' . $input->name . '</div></td></tr>';
$sepCount++;
} else if (is_array($input) && count($input) > 1) {
$name = $input[0];
$fields = '<table class="split-field"><tr>';
$percent = 100 / count($input);
for ($i = 1; $i < count($input); $i++) {
$class = $i == count($input) - 1 ? 'class="last"' : '';
$fields .= '<td ' . $class . ' style="width: ' . $percent . '%">' . $input[$i] . '</td>';
}
$fields .= '</tr></table>';
$str .= self::formField($name, $fields, 'split');
}
}
$str .= '</table></form>';
return $str;
}
public static function formField($name, $field, $class = '') {
return '<tr><td class="field ' . $class . '">' . $name . '</td><td class="value ' . $class . '">' . $field . '</td></tr>';
}
public static function content() {
self::initSettings();
$theme = CrayonResources::themes()->get_default();
$editing = false;
if (isset($_GET['curr_theme'])) {
$currTheme = CrayonResources::themes()->get($_GET['curr_theme']);
if ($currTheme) {
$theme = $currTheme;
}
}
if (isset($_GET['editing'])) {
$editing = CrayonUtil::str_to_bool($_GET['editing'], FALSE);
}
$tInformation = crayon__("Information");
$tHighlighting = crayon__("Highlighting");
$tFrame = crayon__("Frame");
$tLines = crayon__("Lines");
$tNumbers = crayon__("Line Numbers");
$tToolbar = crayon__("Toolbar");
$tBackground = crayon__("Background");
$tText = crayon__("Text");
$tBorder = crayon__("Border");
$tTopBorder = crayon__("Top Border");
$tBottomBorder = crayon__("Bottom Border");
$tBorderRight = crayon__("Right Border");
$tHover = crayon__("Hover");
$tActive = crayon__("Active");
$tPressed = crayon__("Pressed");
$tHoverPressed = crayon__("Pressed & Hover");
$tActivePressed = crayon__("Pressed & Active");
$tTitle = crayon__("Title");
$tButtons = crayon__("Buttons");
$tNormal = crayon__("Normal");
$tInline = crayon__("Inline");
$tStriped = crayon__("Striped");
$tMarked = crayon__("Marked");
$tStripedMarked = crayon__("Striped & Marked");
$tLanguage = crayon__("Language");
$top = '.crayon-top';
$bottom = '.crayon-bottom';
$hover = ':hover';
$active = ':active';
$pressed = '.crayon-pressed';
?>
<div
id="icon-options-general" class="icon32"></div>
<h2>
Crayon Syntax Highlighter
<?php crayon_e('Theme Editor'); ?>
</h2>
<h3 id="<?php echo self::$settings['prefix'] ?>-name">
<?php
// if ($editing) {
// echo sprintf(crayon__('Editing "%s" Theme'), $theme->name());
// } else {
// echo sprintf(crayon__('Creating Theme From "%s"'), $theme->name());
// }
?>
</h3>
<div id="<?php echo self::$settings['prefix'] ?>-info"></div>
<p>
<a id="crayon-editor-back" class="button-primary"><?php crayon_e("Back To Settings"); ?></a>
<a id="crayon-editor-save" class="button-primary"><?php crayon_e("Save"); ?></a>
<span id="crayon-editor-status"></span>
</p>
<?php //crayon_e('Use the Sidebar on the right to change the Theme of the Preview window.') ?>
<div id="crayon-editor-top-controls"></div>
<table id="crayon-editor-table" style="width: 100%;" cellspacing="5"
cellpadding="0">
<tr>
<td id="crayon-editor-preview-wrapper">
<div id="crayon-editor-preview"></div>
</td>
<div id="crayon-editor-preview-css"></div>
<td id="crayon-editor-control-wrapper">
<div id="crayon-editor-controls">
<ul>
<li title="<?php echo $tInformation ?>"><a class="crayon-tab-information" href="#tabs-1"></a></li>
<li title="<?php echo $tHighlighting ?>"><a class="crayon-tab-highlighting" href="#tabs-2"></a></li>
<li title="<?php echo $tFrame ?>"><a class="crayon-tab-frame" href="#tabs-3"></a></li>
<li title="<?php echo $tLines ?>"><a class="crayon-tab-lines" href="#tabs-4"></a></li>
<li title="<?php echo $tNumbers ?>"><a class="crayon-tab-numbers" href="#tabs-5"></a></li>
<li title="<?php echo $tToolbar ?>"><a class="crayon-tab-toolbar" href="#tabs-6"></a></li>
</ul>
<div id="tabs-1">
<?php
self::createAttributesForm(array(
new CrayonHTMLTitle($tInformation)
));
?>
<div id="tabs-1-contents"></div>
<!-- Auto-filled by theme_editor.js -->
</div>
<div id="tabs-2">
<?php
$highlight = ' .crayon-pre';
$elems = array(
'c' => crayon__("Comment"),
's' => crayon__("String"),
'p' => crayon__("Preprocessor"),
'ta' => crayon__("Tag"),
'k' => crayon__("Keyword"),
'st' => crayon__("Statement"),
'r' => crayon__("Reserved"),
't' => crayon__("Type"),
'm' => crayon__("Modifier"),
'i' => crayon__("Identifier"),
'e' => crayon__("Entity"),
'v' => crayon__("Variable"),
'cn' => crayon__("Constant"),
'o' => crayon__("Operator"),
'sy' => crayon__("Symbol"),
'n' => crayon__("Notation"),
'f' => crayon__("Faded"),
'h' => crayon__("HTML"),
'' => crayon__("Unhighlighted")
);
$atts = array(new CrayonHTMLTitle($tHighlighting));
foreach ($elems as $class => $name) {
$fullClass = $class != '' ? $highlight . ' .crayon-' . $class : $highlight;
$atts[] = array(
$name,
self::createAttribute($fullClass, 'color'),
self::createAttribute($fullClass, 'font-weight'),
self::createAttribute($fullClass, 'font-style'),
self::createAttribute($fullClass, 'text-decoration')
);
}
self::createAttributesForm($atts);
?>
</div>
<div id="tabs-3">
<?php
$inline = '-inline';
self::createAttributesForm(array(
new CrayonHTMLTitle($tFrame),
new CrayonHTMLSeparator($tNormal),
// self::createAttribute('', 'background', $tBackground),
array(
$tBorder,
self::createAttribute('', 'border-width'),
self::createAttribute('', 'border-color'),
self::createAttribute('', 'border-style')
),
new CrayonHTMLSeparator($tInline),
self::createAttribute($inline, 'background', $tBackground),
array(
$tBorder,
self::createAttribute($inline, 'border-width'),
self::createAttribute($inline, 'border-color'),
self::createAttribute($inline, 'border-style')
),
));
?>
</div>
<div id="tabs-4">
<?php
$stripedLine = ' .crayon-striped-line';
$markedLine = ' .crayon-marked-line';
$stripedMarkedLine = ' .crayon-marked-line.crayon-striped-line';
self::createAttributesForm(array(
new CrayonHTMLTitle($tLines),
new CrayonHTMLSeparator($tNormal),
self::createAttribute('', 'background', $tBackground),
new CrayonHTMLSeparator($tStriped),
self::createAttribute($stripedLine, 'background', $tBackground),
new CrayonHTMLSeparator($tMarked),
self::createAttribute($markedLine, 'background', $tBackground),
array(
$tBorder,
self::createAttribute($markedLine, 'border-width'),
self::createAttribute($markedLine, 'border-color'),
self::createAttribute($markedLine, 'border-style'),
),
self::createAttribute($markedLine . $top, 'border-top-style', $tTopBorder),
self::createAttribute($markedLine . $bottom, 'border-bottom-style', $tBottomBorder),
new CrayonHTMLSeparator($tStripedMarked),
self::createAttribute($stripedMarkedLine, 'background', $tBackground),
));
?>
</div>
<div id="tabs-5">
<?php
$nums = ' .crayon-table .crayon-nums';
$stripedNum = ' .crayon-striped-num';
$markedNum = ' .crayon-marked-num';
$stripedMarkedNum = ' .crayon-marked-num.crayon-striped-num';
self::createAttributesForm(array(
new CrayonHTMLTitle($tNumbers),
array(
$tBorderRight,
self::createAttribute($nums, 'border-right-width'),
self::createAttribute($nums, 'border-right-color'),
self::createAttribute($nums, 'border-right-style'),
),
new CrayonHTMLSeparator($tNormal),
self::createAttribute($nums, 'background', $tBackground),
self::createAttribute($nums, 'color', $tText),
new CrayonHTMLSeparator($tStriped),
self::createAttribute($stripedNum, 'background', $tBackground),
self::createAttribute($stripedNum, 'color', $tText),
new CrayonHTMLSeparator($tMarked),
self::createAttribute($markedNum, 'background', $tBackground),
self::createAttribute($markedNum, 'color', $tText),
array(
$tBorder,
self::createAttribute($markedNum, 'border-width'),
self::createAttribute($markedNum, 'border-color'),
self::createAttribute($markedNum, 'border-style'),
),
self::createAttribute($markedNum.$top, 'border-top-style', $tTopBorder),
self::createAttribute($markedNum.$bottom, 'border-bottom-style', $tBottomBorder),
new CrayonHTMLSeparator($tStripedMarked),
self::createAttribute($stripedMarkedNum, 'background', $tBackground),
self::createAttribute($stripedMarkedNum, 'color', $tText),
));
?>
</div>
<div id="tabs-6">
<?php
$toolbar = ' .crayon-toolbar';
$title = ' .crayon-title';
$button = ' .crayon-button';
$info = ' .crayon-info';
$language = ' .crayon-language';
self::createAttributesForm(array(
new CrayonHTMLTitle($tToolbar),
new CrayonHTMLSeparator($tFrame),
self::createAttribute($toolbar, 'background', $tBackground),
array(
$tBottomBorder,
self::createAttribute($toolbar, 'border-bottom-width'),
self::createAttribute($toolbar, 'border-bottom-color'),
self::createAttribute($toolbar, 'border-bottom-style'),
),
array(
$tTitle,
self::createAttribute($title, 'color'),
self::createAttribute($title, 'font-weight'),
self::createAttribute($title, 'font-style'),
self::createAttribute($title, 'text-decoration')
),
new CrayonHTMLSeparator($tButtons),
self::createAttribute($button, 'background-color', $tBackground),
self::createAttribute($button.$hover, 'background-color', $tHover),
self::createAttribute($button.$active, 'background-color', $tActive),
self::createAttribute($button.$pressed, 'background-color', $tPressed),
self::createAttribute($button.$pressed.$hover, 'background-color', $tHoverPressed),
self::createAttribute($button.$pressed.$active, 'background-color', $tActivePressed),
new CrayonHTMLSeparator($tInformation . ' ' . crayon__("(Used for Copy/Paste)")),
self::createAttribute($info, 'background', $tBackground),
array(
$tText,
self::createAttribute($info, 'color'),
self::createAttribute($info, 'font-weight'),
self::createAttribute($info, 'font-style'),
self::createAttribute($info, 'text-decoration')
),
array(
$tBottomBorder,
self::createAttribute($info, 'border-bottom-width'),
self::createAttribute($info, 'border-bottom-color'),
self::createAttribute($info, 'border-bottom-style'),
),
new CrayonHTMLSeparator($tLanguage),
array(
$tText,
self::createAttribute($language, 'color'),
self::createAttribute($language, 'font-weight'),
self::createAttribute($language, 'font-style'),
self::createAttribute($language, 'text-decoration')
),
self::createAttribute($language, 'background-color', $tBackground)
));
?>
</div>
</div>
</td>
</tr>
</table>
<?php
exit();
}
public static function createAttribute($element, $attribute, $name = NULL) {
$group = self::getAttributeGroup($attribute);
$type = self::getAttributeType($group);
if ($type == 'select') {
$input = new CrayonHTMLSelect($element . '_' . $attribute, $name);
if ($group == 'border-style') {
$input->addOptions(CrayonHTMLElement::$borderStyles);
} else if ($group == 'float') {
$input->addOptions(array(
'left',
'right',
'both',
'none',
'inherit'
));
} else if ($group == 'font-style') {
$input->addOptions(array(
'normal',
'italic',
'oblique',
'inherit'
));
} else if ($group == 'font-weight') {
$input->addOptions(array(
'normal',
'bold',
'bolder',
'lighter',
'100',
'200',
'300',
'400',
'500',
'600',
'700',
'800',
'900',
'inherit'
));
} else if ($group == 'text-decoration') {
$input->addOptions(array(
'none',
'underline',
'overline',
'line-through',
'blink',
'inherit'
));
}
} else {
$input = new CrayonHTMLInput($element . '_' . $attribute, $name);
}
$input->addClass(self::ATTRIBUTE);
$input->addAttributes(array(
'data-element' => $element,
'data-attribute' => $attribute,
'data-group' => $group
));
return $input;
}
public static function createAttributesForm($atts) {
echo self::form($atts);
}
/**
* 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();
}
public static function duplicate() {
CrayonSettingsWP::load_settings();
$oldID = $_POST['id'];
$oldPath = CrayonResources::themes()->path($oldID);
$_POST['css'] = file_get_contents($oldPath);
$_POST['delete'] = FALSE;
$_POST['allow_edit'] = FALSE;
$_POST['allow_edit_stock_theme'] = FALSE;
self::save();
}
public static function delete() {
CrayonSettingsWP::load_settings();
$id = $_POST['id'];
$dir = CrayonResources::themes()->dirpath_for_id($id);
if (is_dir($dir) && CrayonResources::themes()->exists($id)) {
try {
CrayonUtil::deleteDir($dir);
CrayonGlobalSettings::set(CrayonSettings::THEME, CrayonThemes::DEFAULT_THEME);
CrayonSettingsWP::save_settings();
echo 1;
} catch (Exception $e) {
CrayonLog::syslog($e->getMessage(), "THEME SAVE");
echo -2;
}
} else {
echo -1;
}
exit();
}
public static function submit() {
global $CRAYON_EMAIL;
CrayonSettingsWP::load_settings();
$id = $_POST['id'];
$message = $_POST['message'];
$dir = CrayonResources::themes()->dirpath_for_id($id);
$dest = $dir . 'tmp';
wp_mkdir_p($dest);
if (is_dir($dir) && CrayonResources::themes()->exists($id)) {
try {
$zipFile = CrayonUtil::createZip($dir, $dest, TRUE);
$result = CrayonUtil::emailFile(array(
'to' => $CRAYON_EMAIL,
'from' => get_bloginfo('admin_email'),
'subject' => 'Theme Editor Submission',
'message' => $message,
'file' => $zipFile
));
CrayonUtil::deleteDir($dest);
if ($result) {
echo 1;
} else {
echo -3;
}
} catch (Exception $e) {
CrayonLog::syslog($e->getMessage(), "THEME SUBMIT");
echo -2;
}
} else {
echo -1;
}
exit();
}
public static function getCSSInfo($css) {
$info = array();
preg_match(self::RE_COMMENT, $css, $matches);
if (count($matches)) {
$comment = $matches[0];
preg_match_all('#([^\r\n:]*[^\r\n\s:])\s*:\s*([^\r\n]+)#msi', $comment, $matches);
if (count($matches)) {
for ($i = 0; $i < count($matches[1]); $i++) {
$name = $matches[1][$i];
$value = $matches[2][$i];
$info[self::getFieldID($name)] = $value;
}
}
}
return $info;
}
public static function cssInfoToString($info) {
$str = "/*\n";
foreach ($info as $id => $value) {
$str .= self::getFieldName($id) . ': ' . $value . "\n";
}
$str .= "*/";
return $str;
}
public static function setCSSInfo($css, $info) {
return preg_replace(self::RE_COMMENT, self::cssInfoToString($info), $css);
}
public static function getFieldID($name) {
if (isset(self::$infoFieldsInverse[$name])) {
return self::$infoFieldsInverse[$name];
} else {
return CrayonUserResource::clean_id($name);
}
}
public static function getFieldName($id) {
self::initFields();
if (isset(self::$infoFields[$id])) {
return self::$infoFields[$id];
} else {
return CrayonUserResource::clean_name($id);
}
}
public static function getAttributeGroup($attribute) {
if (isset(self::$attributeGroupsInverse[$attribute])) {
return self::$attributeGroupsInverse[$attribute];
} else {
return $attribute;
}
}
public static function getAttributeType($group) {
if (isset(self::$attributeTypesInverse[$group])) {
return self::$attributeTypesInverse[$group];
} else {
return 'text';
}
}
}
?>