Child Theme Creator by Orbisius - Version 1.4.1

Version Description

  • The previous version got released prematurely. So sorry!
Download this release

Release Info

Developer lordspace
Plugin Icon wp plugin Child Theme Creator by Orbisius
Version 1.4.1
Comparing to
See all releases

Code changes from version 1.4.0 to 1.4.1

addons/clipboard/assets/main.js ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Used for the Snippet Library
3
+ */
4
+ jQuery(document).ready(function($) {
5
+ try {
6
+ var clipboard = new Clipboard('.orb_ctc_copy_btn');
7
+
8
+ // Change the button's label temporarily.
9
+ clipboard.on('success', function(e) {
10
+ // by default the copied text/container is highlighted and looks weird.
11
+ e.clearSelection();
12
+ var btn = $(e.trigger);
13
+ var old_label = btn.text();
14
+
15
+ btn.text('Copied!');
16
+
17
+ setTimeout(function () {
18
+ btn.text(old_label);
19
+ }, 1500);
20
+ });
21
+
22
+ clipboard.on('error', function(e) {
23
+ alert('copy failed');
24
+ });
25
+ } catch (e) {
26
+ console && console.log("orbisius child theme creator addon: Clipboard.js wasn't loaded or there was a conflict");
27
+ }
28
+ }); // (jQuery)
addons/clipboard/assets/main.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(document).ready(function(o){try{var e=new Clipboard(".orb_ctc_copy_btn");e.on("success",function(e){e.clearSelection();var t=o(e.trigger),c=t.text();t.text("Copied!"),setTimeout(function(){t.text(c)},1500)}),e.on("error",function(o){alert("copy failed")})}catch(o){console&&console.log("orbisius child theme creator addon: Clipboard.js wasn't loaded or there was a conflict")}});
addons/clipboard/init.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $c = new orb_ctc_addon_clipboard();
4
+ add_action('orbisius_child_theme_creator_admin_enqueue_scripts', [ $c, 'admin_enqueue_scripts' ]);
5
+
6
+ class orb_ctc_addon_clipboard {
7
+ function admin_enqueue_scripts() {
8
+ wp_register_script( 'orb_ctc_addon_clipboard',
9
+ apply_filters('orbisius_child_theme_creator_filter_asset_src', "addons/clipboard/share/clipboard-js/dist/clipboard.min.js"),
10
+ array('jquery', ),
11
+ apply_filters('orbisius_child_theme_creator_filter_asset_src',
12
+ "addons/clipboard/share/clipboard-js/dist/clipboard.min.js",
13
+ [ 'last_mod' => 1 ]
14
+ ),
15
+ true
16
+ );
17
+ wp_enqueue_script( 'orb_ctc_addon_clipboard' );
18
+
19
+ wp_register_script( 'orb_ctc_addon_clipboard_main',
20
+ apply_filters('orbisius_child_theme_creator_filter_asset_src', "addons/clipboard/assets/main.js"),
21
+ array('jquery', 'orb_ctc_addon_clipboard', ),
22
+ apply_filters('orbisius_child_theme_creator_filter_asset_src',
23
+ "addons/clipboard/assets/main.js",
24
+ [ 'last_mod' => 1 ]
25
+ ),
26
+ true
27
+ );
28
+ wp_enqueue_script( 'orb_ctc_addon_clipboard_main' );
29
+ }
30
+ }
addons/clipboard/share/clipboard-js/dist/clipboard.min.js ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ /*!
2
+ * clipboard.js v1.7.1
3
+ * https://zenorocha.github.io/clipboard.js
4
+ *
5
+ * Licensed MIT © Zeno Rocha
6
+ */
7
+ !function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Clipboard=t()}}(function(){var t,e,n;return function t(e,n,o){function i(a,c){if(!n[a]){if(!e[a]){var l="function"==typeof require&&require;if(!c&&l)return l(a,!0);if(r)return r(a,!0);var s=new Error("Cannot find module '"+a+"'");throw s.code="MODULE_NOT_FOUND",s}var u=n[a]={exports:{}};e[a][0].call(u.exports,function(t){var n=e[a][1][t];return i(n||t)},u,u.exports,t,e,n,o)}return n[a].exports}for(var r="function"==typeof require&&require,a=0;a<o.length;a++)i(o[a]);return i}({1:[function(t,e,n){function o(t,e){for(;t&&t.nodeType!==i;){if("function"==typeof t.matches&&t.matches(e))return t;t=t.parentNode}}var i=9;if("undefined"!=typeof Element&&!Element.prototype.matches){var r=Element.prototype;r.matches=r.matchesSelector||r.mozMatchesSelector||r.msMatchesSelector||r.oMatchesSelector||r.webkitMatchesSelector}e.exports=o},{}],2:[function(t,e,n){function o(t,e,n,o,r){var a=i.apply(this,arguments);return t.addEventListener(n,a,r),{destroy:function(){t.removeEventListener(n,a,r)}}}function i(t,e,n,o){return function(n){n.delegateTarget=r(n.target,e),n.delegateTarget&&o.call(t,n)}}var r=t("./closest");e.exports=o},{"./closest":1}],3:[function(t,e,n){n.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},n.nodeList=function(t){var e=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===e||"[object HTMLCollection]"===e)&&"length"in t&&(0===t.length||n.node(t[0]))},n.string=function(t){return"string"==typeof t||t instanceof String},n.fn=function(t){return"[object Function]"===Object.prototype.toString.call(t)}},{}],4:[function(t,e,n){function o(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!c.string(e))throw new TypeError("Second argument must be a String");if(!c.fn(n))throw new TypeError("Third argument must be a Function");if(c.node(t))return i(t,e,n);if(c.nodeList(t))return r(t,e,n);if(c.string(t))return a(t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function i(t,e,n){return t.addEventListener(e,n),{destroy:function(){t.removeEventListener(e,n)}}}function r(t,e,n){return Array.prototype.forEach.call(t,function(t){t.addEventListener(e,n)}),{destroy:function(){Array.prototype.forEach.call(t,function(t){t.removeEventListener(e,n)})}}}function a(t,e,n){return l(document.body,t,e,n)}var c=t("./is"),l=t("delegate");e.exports=o},{"./is":3,delegate:2}],5:[function(t,e,n){function o(t){var e;if("SELECT"===t.nodeName)t.focus(),e=t.value;else if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName){var n=t.hasAttribute("readonly");n||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),n||t.removeAttribute("readonly"),e=t.value}else{t.hasAttribute("contenteditable")&&t.focus();var o=window.getSelection(),i=document.createRange();i.selectNodeContents(t),o.removeAllRanges(),o.addRange(i),e=o.toString()}return e}e.exports=o},{}],6:[function(t,e,n){function o(){}o.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){function o(){i.off(t,o),e.apply(n,arguments)}var i=this;return o._=e,this.on(t,o,n)},emit:function(t){var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,i=n.length;for(o;o<i;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],i=[];if(o&&e)for(var r=0,a=o.length;r<a;r++)o[r].fn!==e&&o[r].fn._!==e&&i.push(o[r]);return i.length?n[t]=i:delete n[t],this}},e.exports=o},{}],7:[function(e,n,o){!function(i,r){if("function"==typeof t&&t.amd)t(["module","select"],r);else if(void 0!==o)r(n,e("select"));else{var a={exports:{}};r(a,i.select),i.clipboardAction=a.exports}}(this,function(t,e){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var i=n(e),r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},a=function(){function t(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,n,o){return n&&t(e.prototype,n),o&&t(e,o),e}}(),c=function(){function t(e){o(this,t),this.resolveOptions(e),this.initSelection()}return a(t,[{key:"resolveOptions",value:function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.action=e.action,this.container=e.container,this.emitter=e.emitter,this.target=e.target,this.text=e.text,this.trigger=e.trigger,this.selectedText=""}},{key:"initSelection",value:function t(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function t(){var e=this,n="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return e.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[n?"right":"left"]="-9999px";var o=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=o+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=(0,i.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function t(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function t(){this.selectedText=(0,i.default)(this.target),this.copyText()}},{key:"copyText",value:function t(){var e=void 0;try{e=document.execCommand(this.action)}catch(t){e=!1}this.handleResult(e)}},{key:"handleResult",value:function t(e){this.emitter.emit(e?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function t(){this.trigger&&this.trigger.focus(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function t(){this.removeFake()}},{key:"action",set:function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=e,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function t(){return this._action}},{key:"target",set:function t(e){if(void 0!==e){if(!e||"object"!==(void 0===e?"undefined":r(e))||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=e}},get:function t(){return this._target}}]),t}();t.exports=c})},{select:5}],8:[function(e,n,o){!function(i,r){if("function"==typeof t&&t.amd)t(["module","./clipboard-action","tiny-emitter","good-listener"],r);else if(void 0!==o)r(n,e("./clipboard-action"),e("tiny-emitter"),e("good-listener"));else{var a={exports:{}};r(a,i.clipboardAction,i.tinyEmitter,i.goodListener),i.clipboard=a.exports}}(this,function(t,e,n,o){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function a(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function c(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function l(t,e){var n="data-clipboard-"+t;if(e.hasAttribute(n))return e.getAttribute(n)}var s=i(e),u=i(n),f=i(o),d="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},h=function(){function t(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,n,o){return n&&t(e.prototype,n),o&&t(e,o),e}}(),p=function(t){function e(t,n){r(this,e);var o=a(this,(e.__proto__||Object.getPrototypeOf(e)).call(this));return o.resolveOptions(n),o.listenClick(t),o}return c(e,t),h(e,[{key:"resolveOptions",value:function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof e.action?e.action:this.defaultAction,this.target="function"==typeof e.target?e.target:this.defaultTarget,this.text="function"==typeof e.text?e.text:this.defaultText,this.container="object"===d(e.container)?e.container:document.body}},{key:"listenClick",value:function t(e){var n=this;this.listener=(0,f.default)(e,"click",function(t){return n.onClick(t)})}},{key:"onClick",value:function t(e){var n=e.delegateTarget||e.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new s.default({action:this.action(n),target:this.target(n),text:this.text(n),container:this.container,trigger:n,emitter:this})}},{key:"defaultAction",value:function t(e){return l("action",e)}},{key:"defaultTarget",value:function t(e){var n=l("target",e);if(n)return document.querySelector(n)}},{key:"defaultText",value:function t(e){return l("text",e)}},{key:"destroy",value:function t(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],n="string"==typeof e?[e]:e,o=!!document.queryCommandSupported;return n.forEach(function(t){o=o&&!!document.queryCommandSupported(t)}),o}}]),e}(u.default);t.exports=p})},{"./clipboard-action":7,"good-listener":4,"tiny-emitter":6}]},{},[8])(8)});
addons/clipboard/share/clipboard-js/readme.md ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # clipboard.js
2
+
3
+ [![Build Status](http://img.shields.io/travis/zenorocha/clipboard.js/master.svg?style=flat)](https://travis-ci.org/zenorocha/clipboard.js)
4
+ ![Killing Flash](https://img.shields.io/badge/killing-flash-brightgreen.svg?style=flat)
5
+
6
+ > Modern copy to clipboard. No Flash. Just 3kb gzipped.
7
+
8
+ <a href="https://clipboardjs.com/"><img width="728" src="https://cloud.githubusercontent.com/assets/398893/16165747/a0f6fc46-349a-11e6-8c9b-c5fd58d9099c.png" alt="Demo"></a>
9
+
10
+ ## Why
11
+
12
+ Copying text to the clipboard shouldn't be hard. It shouldn't require dozens of steps to configure or hundreds of KBs to load. But most of all, it shouldn't depend on Flash or any bloated framework.
13
+
14
+ That's why clipboard.js exists.
15
+
16
+ ## Install
17
+
18
+ You can get it on npm.
19
+
20
+ ```
21
+ npm install clipboard --save
22
+ ```
23
+
24
+ Or if you're not into package management, just [download a ZIP](https://github.com/zenorocha/clipboard.js/archive/master.zip) file.
25
+
26
+ ## Setup
27
+
28
+ First, include the script located on the `dist` folder or load it from [a third-party CDN provider](https://github.com/zenorocha/clipboard.js/wiki/CDN-Providers).
29
+
30
+ ```html
31
+ <script src="dist/clipboard.min.js"></script>
32
+ ```
33
+
34
+ Now, you need to instantiate it by [passing a DOM selector](https://github.com/zenorocha/clipboard.js/blob/master/demo/constructor-selector.html#L18), [HTML element](https://github.com/zenorocha/clipboard.js/blob/master/demo/constructor-node.html#L16-L17), or [list of HTML elements](https://github.com/zenorocha/clipboard.js/blob/master/demo/constructor-nodelist.html#L18-L19).
35
+
36
+ ```js
37
+ new Clipboard('.btn');
38
+ ```
39
+
40
+ Internally, we need to fetch all elements that matches with your selector and attach event listeners for each one. But guess what? If you have hundreds of matches, this operation can consume a lot of memory.
41
+
42
+ For this reason we use [event delegation](http://stackoverflow.com/questions/1687296/what-is-dom-event-delegation) which replaces multiple event listeners with just a single listener. After all, [#perfmatters](https://twitter.com/hashtag/perfmatters).
43
+
44
+ # Usage
45
+
46
+ We're living a _declarative renaissance_, that's why we decided to take advantage of [HTML5 data attributes](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes) for better usability.
47
+
48
+ ### Copy text from another element
49
+
50
+ A pretty common use case is to copy content from another element. You can do that by adding a `data-clipboard-target` attribute in your trigger element.
51
+
52
+ The value you include on this attribute needs to match another's element selector.
53
+
54
+ <a href="https://clipboardjs.com/#example-target"><img width="473" alt="example-2" src="https://cloud.githubusercontent.com/assets/398893/9983467/a4946aaa-5fb1-11e5-9780-f09fcd7ca6c8.png"></a>
55
+
56
+ ```html
57
+ <!-- Target -->
58
+ <input id="foo" value="https://github.com/zenorocha/clipboard.js.git">
59
+
60
+ <!-- Trigger -->
61
+ <button class="btn" data-clipboard-target="#foo">
62
+ <img src="assets/clippy.svg" alt="Copy to clipboard">
63
+ </button>
64
+ ```
65
+
66
+ ### Cut text from another element
67
+
68
+ Additionally, you can define a `data-clipboard-action` attribute to specify if you want to either `copy` or `cut` content.
69
+
70
+ If you omit this attribute, `copy` will be used by default.
71
+
72
+ <a href="https://clipboardjs.com/#example-action"><img width="473" alt="example-3" src="https://cloud.githubusercontent.com/assets/398893/10000358/7df57b9c-6050-11e5-9cd1-fbc51d2fd0a7.png"></a>
73
+
74
+ ```html
75
+ <!-- Target -->
76
+ <textarea id="bar">Mussum ipsum cacilds...</textarea>
77
+
78
+ <!-- Trigger -->
79
+ <button class="btn" data-clipboard-action="cut" data-clipboard-target="#bar">
80
+ Cut to clipboard
81
+ </button>
82
+ ```
83
+
84
+ As you may expect, the `cut` action only works on `<input>` or `<textarea>` elements.
85
+
86
+ ### Copy text from attribute
87
+
88
+ Truth is, you don't even need another element to copy its content from. You can just include a `data-clipboard-text` attribute in your trigger element.
89
+
90
+ <a href="https://clipboardjs.com/#example-text"><img width="147" alt="example-1" src="https://cloud.githubusercontent.com/assets/398893/10000347/6e16cf8c-6050-11e5-9883-1c5681f9ec45.png"></a>
91
+
92
+ ```html
93
+ <!-- Trigger -->
94
+ <button class="btn" data-clipboard-text="Just because you can doesn't mean you should — clipboard.js">
95
+ Copy to clipboard
96
+ </button>
97
+ ```
98
+
99
+ ## Events
100
+
101
+ There are cases where you'd like to show some user feedback or capture what has been selected after a copy/cut operation.
102
+
103
+ That's why we fire custom events such as `success` and `error` for you to listen and implement your custom logic.
104
+
105
+ ```js
106
+ var clipboard = new Clipboard('.btn');
107
+
108
+ clipboard.on('success', function(e) {
109
+ console.info('Action:', e.action);
110
+ console.info('Text:', e.text);
111
+ console.info('Trigger:', e.trigger);
112
+
113
+ e.clearSelection();
114
+ });
115
+
116
+ clipboard.on('error', function(e) {
117
+ console.error('Action:', e.action);
118
+ console.error('Trigger:', e.trigger);
119
+ });
120
+ ```
121
+
122
+ For a live demonstration, go to this [site](https://clipboardjs.com/) and open your console.
123
+
124
+ ## Tooltips
125
+
126
+ Each application has different design needs, that's why clipboard.js does not include any CSS or built-in tooltip solution.
127
+
128
+ The tooltips you see on the [demo site](https://clipboardjs.com/) were built using [GitHub's Primer](http://primercss.io/tooltips/). You may want to check that out if you're looking for a similar look and feel.
129
+
130
+ ## Advanced Options
131
+
132
+ If you don't want to modify your HTML, there's a pretty handy imperative API for you to use. All you need to do is declare a function, do your thing, and return a value.
133
+
134
+ For instance, if you want to dynamically set a `target`, you'll need to return a Node.
135
+
136
+ ```js
137
+ new Clipboard('.btn', {
138
+ target: function(trigger) {
139
+ return trigger.nextElementSibling;
140
+ }
141
+ });
142
+ ```
143
+
144
+ If you want to dynamically set a `text`, you'll return a String.
145
+
146
+ ```js
147
+ new Clipboard('.btn', {
148
+ text: function(trigger) {
149
+ return trigger.getAttribute('aria-label');
150
+ }
151
+ });
152
+ ```
153
+
154
+ For use in Bootstrap Modals or with any other library that changes the focus you'll want to set the focused element as the `container` value.
155
+
156
+ ```js
157
+ new Clipboard('.btn', {
158
+ container: document.getElementById('modal')
159
+ });
160
+ ```
161
+
162
+ Also, if you are working with single page apps, you may want to manage the lifecycle of the DOM more precisely. Here's how you clean up the events and objects that we create.
163
+
164
+ ```js
165
+ var clipboard = new Clipboard('.btn');
166
+ clipboard.destroy();
167
+ ```
168
+
169
+ ## Browser Support
170
+
171
+ This library relies on both [Selection](https://developer.mozilla.org/en-US/docs/Web/API/Selection) and [execCommand](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) APIs. The first one is [supported by all browsers](http://caniuse.com/#search=selection) while the second one is supported in the following browsers.
172
+
173
+ | <img src="https://clipboardjs.com/assets/images/chrome.png" width="48px" height="48px" alt="Chrome logo"> | <img src="https://clipboardjs.com/assets/images/edge.png" width="48px" height="48px" alt="Edge logo"> | <img src="https://clipboardjs.com/assets/images/firefox.png" width="48px" height="48px" alt="Firefox logo"> | <img src="https://clipboardjs.com/assets/images/ie.png" width="48px" height="48px" alt="Internet Explorer logo"> | <img src="https://clipboardjs.com/assets/images/opera.png" width="48px" height="48px" alt="Opera logo"> | <img src="https://clipboardjs.com/assets/images/safari.png" width="48px" height="48px" alt="Safari logo"> |
174
+ |:---:|:---:|:---:|:---:|:---:|:---:|
175
+ | 42+ ✔ | 12+ ✔ | 41+ ✔ | 9+ ✔ | 29+ ✔ | 10+ ✔ |
176
+
177
+ The good news is that clipboard.js gracefully degrades if you need to support older browsers. All you have to do is show a tooltip saying `Copied!` when `success` event is called and `Press Ctrl+C to copy` when `error` event is called because the text is already selected.
178
+
179
+ You can also check if clipboard.js is supported or not by running `Clipboard.isSupported()`, that way you can hide copy/cut buttons from the UI.
180
+
181
+ ## Bonus
182
+
183
+ A browser extension that adds a "copy to clipboard" button to every code block on *GitHub, MDN, Gist, StackOverflow, StackExchange, npm, and even Medium.*
184
+
185
+ Install for [Chrome](https://chrome.google.com/webstore/detail/codecopy/fkbfebkcoelajmhanocgppanfoojcdmg) and [Firefox](https://addons.mozilla.org/en-US/firefox/addon/codecopy/).
186
+
187
+ ## License
188
+
189
+ [MIT License](http://zenorocha.mit-license.org/) © Zeno Rocha
addons/cloud_lib/assets/custom.css ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Snippet Library styles */
2
+
3
+ .orb_cloud_lib_wrapper {
4
+ /*margin: 1em 0;*/
5
+ }
6
+
7
+ .orb_cloud_lib_wrapper span.label {
8
+ font-weight: bold;
9
+ color: #3c7504; /* #336600 */
10
+ margin-bottom: 5px;
11
+ margin-top: 10px;
12
+ display: inline-block;
13
+ }
14
+
15
+ .orb_cloud_lib_wrapper span.descr {
16
+ font-size: 14px;
17
+ margin-bottom: 5px;
18
+ display: inline-block;
19
+ }
20
+
21
+ .orb_ctc_ext_cloud_lib_search .selector {
22
+ width: 70%;
23
+ }
24
+
25
+ .orb_cloud_lib_wrapper .half_text {
26
+ width: 50%;
27
+ }
28
+
29
+ /* jQuery UI tweaks / overrides */
30
+ .orb_cloud_lib_wrapper .ui-autocomplete-loading {
31
+ background: url('images/loader.gif') no-repeat right center
32
+ }
33
+
34
+ .orb_cloud_lib_wrapper .ui-widget-header {
35
+ border: 0;
36
+ background: inherit;
37
+ }
38
+
39
+ .orb_cloud_lib_wrapper .ui-tabs .ui-tabs-nav {
40
+ padding: 2px;
41
+ }
42
+
43
+ .orb_cloud_lib_wrapper .tabcontent {
44
+ padding: 5px !important;
45
+ margin: 0 5px !important;
46
+ }
47
+
48
+ .orb_cloud_lib_wrapper .ui-widget-content {
49
+ padding: 0;
50
+ }
51
+ /* /jQuery UI tweaks / overrides */
52
+
53
+ .orb_cloud_lib_wrapper .text_75p {
54
+ width: 75%;
55
+ }
56
+
57
+ .orb_cloud_lib_wrapper .app_hide {
58
+ display: none;
59
+ }
60
+
61
+ .orb_cloud_lib_wrapper h3 {
62
+ margin: 0.5em 0;
63
+ }
64
+
65
+ .orb_cloud_lib_wrapper .nav-tab-wrapper {
66
+ margin: 0px !important;
67
+ padding: 0px !important;
68
+ }
69
+
70
+ /*.ui-dialog.edit_snippet, .ui-dialog.view_snippet {
71
+ min-height: 300px !important;
72
+ background: white;
73
+ border: 1px solid #ccc;
74
+ padding: 10px;
75
+ min-width: 400px !important;
76
+ }*/
77
+
78
+ .orb_cloud_lib_wrapper .app_hide {
79
+ display: none;
80
+ }
81
+
82
+ .orb_cloud_lib_wrapper .manage_snippets {
83
+ /*border: 1px solid #ccc;*/
84
+ /*margin: 10px 0;*/
85
+ /*padding: 3px 5px;*/
86
+ }
87
+
88
+
89
+ .orb_cloud_lib_wrapper .delete_snippet_title {
90
+ font-size: 14px;
91
+ font-weight: bold;
92
+ font-style: italic;
93
+ }
94
+
95
+ .orb_cloud_lib_wrapper .edit_title, .orb_cloud_lib_wrapper .view_title {
96
+ width: 100%;
97
+ margin-bottom: 10px;
98
+ border-radius: 5px;
99
+ min-width: 330px !important;
100
+ }
101
+
102
+ .orb_cloud_lib_wrapper .edit_content, .orb_cloud_lib_wrapper .view_content {
103
+ width: 100%;
104
+ min-height: 300px;
105
+ border-radius: 5px;
106
+ min-width: 330px !important;
107
+ }
108
+
109
+ .orb_cloud_lib_wrapper #edit_snippet h3, .orb_cloud_lib_wrapper #view_snippet h3{
110
+ margin-top: 0px;
111
+ }
112
+
113
+ .orb_cloud_lib_wrapper .manage_snippets h3 {
114
+ /*font-weight: bolder;
115
+ color: red;
116
+ text-decoration: underline;*/
117
+ padding-left: 10px;
118
+ }
119
+
120
+ .orb_cloud_lib_wrapper .button.snippet_edit_view_btn,
121
+ .orb_cloud_lib_wrapper .button.snippet_view_btn,
122
+ .orb_cloud_lib_wrapper .button.snippet_edit_btn,
123
+ .orb_cloud_lib_wrapper .button.snippet_delete_btn {
124
+ color: white;
125
+ }
126
+
127
+ .orb_cloud_lib_wrapper .button.snippet_view_btn {
128
+ background-image: linear-gradient(#1e8cbe, #0074a2);
129
+ }
130
+
131
+ .orb_cloud_lib_wrapper .button.snippet_edit_btn, .orb_cloud_lib_wrapper .button.snippet_edit_view_btn {
132
+ /*background-image: linear-gradient(#3c7504, #336600);*/
133
+ background-image: linear-gradient(#4f8916, #244900);
134
+ }
135
+
136
+ .orb_cloud_lib_wrapper .button.snippet_delete_btn {
137
+ background-image: linear-gradient(#e50202, #750303);
138
+ }
139
+
140
+ .orb_cloud_lib_wrapper .manage_snippets_table_wrapper {
141
+ overflow: auto;
142
+ font-size: 14px;
143
+ max-height: 350px;
144
+ }
145
+
146
+ .orb_cloud_lib_wrapper .manage_snippets_table_wrapper table tr td {
147
+ /*border-bottom: 1px solid #d8d8d8;*/
148
+ padding: 0;
149
+ margin-bottom: 5px;
150
+ font-size: 14px;
151
+ }
152
+
153
+ .orb_cloud_lib_wrapper .manage_snippets_table_wrapper table tr td.td_title {
154
+ font-size: 14px;
155
+ }
156
+
157
+ .orb_cloud_lib_wrapper .hover_row:hover {
158
+ background: #ffff99;
159
+ }
160
+
161
+ .orb_cloud_lib_wrapper .manage_snippets_table_wrapper table tr .cmd_row {
162
+ width: 45%;
163
+ text-align: right;
164
+ vertical-align: middle;
165
+ }
166
+
167
+ /*https://css-tricks.com/snippets/css/truncate-string-with-ellipsis/*/
168
+ .orb_cloud_lib_wrapper .truncate {
169
+ width: 250px;
170
+ white-space: nowrap;
171
+ overflow: hidden;
172
+ text-overflow: ellipsis;
173
+ }
174
+
175
+ .orb_cloud_lib_wrapper .alt_row {
176
+ background: #eee;
177
+ }
addons/cloud_lib/assets/custom.js ADDED
@@ -0,0 +1,574 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Used for the Snippet Library
3
+ */
4
+ jQuery(document).ready(function($) {
5
+ $('.orb_ctc_ext_cloud_lib_account_log_out').on('click', function (e) {
6
+ e.preventDefault();
7
+
8
+ var params = {};
9
+ var res_container = $('.orb_ctc_ext_cloud_lib_account').find('.result');
10
+ res_container.html('Please, wait ...');
11
+
12
+ $.ajax({
13
+ type : 'post',
14
+ url: ajaxurl + '?action=orb_ctc_addon_cloud_lib_log_out',
15
+ data: params,
16
+ success: function(json) {
17
+ if (json.status) {
18
+ res_container.html('Please, wait');
19
+ window.location.reload();
20
+ } else {
21
+ res_container.html(json.msg);
22
+ }
23
+ }
24
+ });
25
+ } );
26
+
27
+ $('.orb_ctc_signup_form').on('submit', function (e) {
28
+ e.preventDefault();
29
+ var params = $(this).serialize();
30
+
31
+ if ($('.orb_ctc_pass').val() != $('.orb_ctc_pass2').val() ) {
32
+ alert('Error: Passwords do not match');
33
+ return false;
34
+ }
35
+
36
+ var submit_btn = $(this).find(':submit');
37
+ var res_container = $('.orb_ctc_ext_cloud_lib_signup_wrapper').find('.result');
38
+ res_container.html('Please, wait');
39
+ submit_btn.hide();
40
+
41
+ $.ajax({
42
+ type : 'post',
43
+ url: ajaxurl + '?action=orb_ctc_addon_cloud_lib_signup',
44
+ data: params,
45
+ success: function(json) {
46
+ if (json.status) {
47
+ res_container.html('Please, wait');
48
+ window.location.reload();
49
+ } else {
50
+ var msg = json.msg || "There was an error with the registration. Contact us and report if you think this is a glitch.";
51
+ res_container.html(msg);
52
+ submit_btn.show();
53
+ }
54
+ }
55
+ });
56
+
57
+ return false;
58
+ })
59
+
60
+ $('.orb_ctc_ext_cloud_lib_edit_snippet_form').on('submit', function (e) {
61
+ e.preventDefault();
62
+
63
+ var id = $('.edit_id').val().trim() || 0;
64
+ var new_title = $('.edit_title').val().trim();
65
+ var new_content = $('.edit_content').val().trim();
66
+ snippet_update(id, new_title, new_content);
67
+
68
+ return false;
69
+ });
70
+
71
+ $('.orb_ctc_login_form').on('submit', function (e) {
72
+ e.preventDefault();
73
+ var params = $(this).serialize();
74
+
75
+ var submit_btn = $(this).find(':submit');
76
+ var res_container = $('.orb_ctc_ext_cloud_lib_login_wrapper').find('.result');
77
+ res_container.html('Please, wait');
78
+ submit_btn.hide();
79
+
80
+ $.ajax({
81
+ type : 'post',
82
+ url: ajaxurl + '?action=orb_ctc_addon_cloud_lib_login',
83
+ data: params,
84
+ success: function(json) {
85
+ if (json.status) {
86
+ res_container.html('Please, wait');
87
+ window.location.reload();
88
+ } else {
89
+ var msg = json.msg || "Login details are incorrect.";
90
+ res_container.html(msg);
91
+ submit_btn.show();
92
+ }
93
+ }
94
+ });
95
+
96
+ return false;
97
+ })
98
+ /**
99
+ * Snippets search autocomplete suggestions
100
+ *
101
+ * Returns suggestions from remote source
102
+ * Suggestions are based on the characters typed in the input field
103
+ *
104
+ * Expects JSON array
105
+ * @see https://stackoverflow.com/questions/9656523/jquery-autocomplete-with-callback-ajax-json
106
+ */
107
+ $( "#search_text" ).autocomplete( {
108
+ minLength: 3,
109
+ open: function() {
110
+ $( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
111
+ },
112
+ close: function() {
113
+ $( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
114
+ },
115
+ source: function (request, response) {
116
+ $.ajax({
117
+ type : 'post',
118
+ url: ajaxurl,
119
+ data: {
120
+ action: "orb_ctc_addon_cloud_lib_autocomplete",
121
+ term: request.term,
122
+ },
123
+ success: function(json) {
124
+ response($.map(json.data, function(item) {
125
+ return {
126
+ value: item.id,
127
+ label: item.title
128
+ };
129
+ }));
130
+ },
131
+ select: function (event, ui) {
132
+ // return false;
133
+ }
134
+ });
135
+ },
136
+ });
137
+
138
+ /**
139
+ * Search for a snippet button
140
+ */
141
+ $('#snippet_search_btn').on("click", function() {
142
+ var search = $("#search_text").val().trim();
143
+
144
+ if (search !== '') {
145
+ search_snippets(search);
146
+ } else {
147
+ $("#search_text").focus();
148
+ }
149
+ });
150
+
151
+ /**
152
+ * Press enter to search for a snippet
153
+ */
154
+ $('#search_text').keypress(function(e) {
155
+ if (e.keyCode == 13 || e.which == 13) {
156
+ // e.preventDefault();
157
+ // sendSelected(this.value);
158
+ // $(this).autocomplete('close');
159
+ var search = $("#search_text").val().trim();
160
+
161
+ if (search !== '') {
162
+ search_snippets(search);
163
+ } else {
164
+ $("#search_text").focus();
165
+ }
166
+ }
167
+ });
168
+
169
+ /**
170
+ * Search for a snippet button
171
+ *
172
+ * On click: searches for a snippet title matching the criteria from the input field
173
+ *
174
+ * On success: shows a new text box with the returned data - content and title
175
+ *
176
+ */
177
+ //$('#snippet_search_btn').on("click", function() {
178
+ $( "#search_text" ).on( "autocompleteselect", function( event, ui ) {
179
+ /**
180
+ * Holds the value of the input field
181
+ */
182
+ //var search = $("#search_text").val().trim();
183
+ var search = ui.item.label;
184
+
185
+ if (search !== '') {
186
+ search_snippets(search);
187
+ } else {
188
+ $("#search_text").focus();
189
+ }
190
+ });
191
+
192
+ function search_snippets (search) {
193
+ $.ajax({
194
+ //dataType: "json",
195
+ type : "post",
196
+ url: ajaxurl,
197
+ data: {
198
+ action: "orb_ctc_addon_cloud_lib_search",
199
+ "search":search
200
+ },
201
+ //success: function (data) {
202
+ success: function(json) {
203
+ if (json.status) {
204
+ if (json.data.length > 0) {
205
+ $.map(json.data, function(item) {
206
+ if (item != '[]') {
207
+ $('.found_snippet').show();
208
+ $("#found_snippet_text").val(item.content).focus();
209
+ $("#found_snippet_title").val(item.title).focus();
210
+ }
211
+ });
212
+ }
213
+ }
214
+ }
215
+ });
216
+ }
217
+
218
+ /**
219
+ * Add a new snippet button
220
+ *
221
+ * On click: Displays title and text fields
222
+ *
223
+ */
224
+ $('#new_snippet_btn').on("click", function() {
225
+ $('.new_snippet_wrapper').show("slow");
226
+ });
227
+
228
+ // When title is entered and the Enter key is pressed submit the form.
229
+ $('#add_snippet_title').on("keypress", function(e) {
230
+ if (e.keyCode == 13 || e.which == 13) {
231
+ e.preventDefault();
232
+ $('#snippet_save_btn').trigger('click');
233
+ return false;
234
+ } else {
235
+ return true;
236
+ }
237
+ });
238
+
239
+ // When CTRL + Enter is pressed submit the add snippet form
240
+ // https://stackoverflow.com/questions/1684196/ctrlenter-jquery-in-textarea
241
+ // https://stackoverflow.com/questions/7445151/jquery-document-keydown-issues
242
+ $(document).on('keydown', '.add_snippet_text', function(e) {
243
+ if (e.ctrlKey && (e.keyCode == 13 || e.which == 13)) {
244
+ e.preventDefault();
245
+ $('#snippet_save_btn').trigger('click');
246
+ return false;
247
+ } else {
248
+ return true;
249
+ }
250
+ });
251
+
252
+ // just enter and no control key -> jump to content
253
+ $(document).on('keydown', '.edit_title', function(e) {
254
+ if (!e.ctrlKey && ( e.keyCode == 13 || e.which == 13)) {
255
+ $('.edit_content').focus();
256
+ return false;
257
+ } else {
258
+ return true;
259
+ }
260
+ });
261
+
262
+ // When CTRL + Enter is pressed submit the add snippet form
263
+ // https://stackoverflow.com/questions/1684196/ctrlenter-jquery-in-textarea
264
+ // https://stackoverflow.com/questions/7445151/jquery-document-keydown-issues
265
+
266
+ // @todo handle CTRL+S ??? while in the text area to save
267
+ // https://stackoverflow.com/questions/93695/best-cross-browser-method-to-capture-ctrls-with-jquery
268
+ $(document).on('keydown', '.edit_title,.edit_content', function(e) {
269
+ if (e.ctrlKey && (e.keyCode == 13 || e.which == 13)) {
270
+ e.preventDefault();
271
+ $("#edit_snippet").dialog('close');
272
+ $('.orb_ctc_ext_cloud_lib_edit_snippet_form').trigger('submit');
273
+ return false;
274
+ } else {
275
+ return true;
276
+ }
277
+ });
278
+
279
+ /**
280
+ * Save a new snippet button
281
+ *
282
+ * On click: If title is missing, cannot proceed
283
+ * If text is missing, asks for confirmation to proceed
284
+ *
285
+ */
286
+ $('.orb_ctc_ext_cloud_lib_add_new_snippet_form').on("submit", function(e) {
287
+ e.preventDefault();
288
+ //$('#snippet_save_btn').trigger('click');
289
+ return false;
290
+ });
291
+
292
+ $('#snippet_save_btn').on("click", function(e) {
293
+ var title = $('#add_snippet_title').val().trim();
294
+ var text = $('#add_snippet_text').val().trim();
295
+ snippet_update(0, title, text);
296
+ });
297
+
298
+ /**
299
+ * Delete a snippet by id button
300
+ *
301
+ */
302
+ $('#manage_snippets_table').on("click", '.snippet_delete_btn', function() {
303
+ var id = $(this).closest('tr').data('id');
304
+ //var title = $(this).closest('tr').data('title');
305
+ var title = $(this).closest('tr').children('td.title_cell').children('.snippet_title').text();
306
+
307
+ $('.delete_snippet_title').text(title);
308
+
309
+ $("#snippet_confirm_dialog_delete").dialog( {
310
+ dialogClass: 'snippet_confirm_dialog_delete',
311
+ modal: true,
312
+ resizable: false,
313
+ draggable: false,
314
+ buttons: [{
315
+ text: "Yes",
316
+ "class": 'button-primary',
317
+ click: function() {
318
+ $(this).dialog("close");
319
+ delete_snippet(id);
320
+ }
321
+ },
322
+ {
323
+ text: "No",
324
+ "class": 'button',
325
+ click: function() {
326
+ $(this).dialog("close");
327
+ }
328
+ }],
329
+ close: function(event, ui) {
330
+ $('.snippet_delete_btn').blur();
331
+ }
332
+ });
333
+ });
334
+
335
+ /**
336
+ * We subtract 1 because we have 1 hidden row.
337
+ * We don't filter by visibility because when a different tab is
338
+ * shown those a technically hidden.
339
+ * @returns {Number}
340
+ */
341
+ function get_snippet_count() {
342
+ return $('#manage_snippets_table .snippet_row').length - 1;
343
+ }
344
+
345
+ /**
346
+ * Delete snippet by id
347
+ *
348
+ * @param id
349
+ *
350
+ */
351
+ function delete_snippet(id) {
352
+ $(".snippet_row_" + id).remove();
353
+
354
+ // if there aren't any visible rows (i.e. excluding the 0 row that we use for cloning)
355
+ if ($('#manage_snippets_table .snippet_row:visible').length <= 0) {
356
+ $('#no_snippets_row').show();
357
+ } else {
358
+ $('#no_snippets_row').hide();
359
+ }
360
+
361
+ $.ajax({
362
+ url: ajaxurl,
363
+ data: {
364
+ id: id,
365
+ action: "orb_ctc_addon_cloud_lib_delete"
366
+ },
367
+ success: function (json) {
368
+ // update max items via js
369
+ $('.usage_items').text(get_snippet_count());
370
+
371
+ if (json.status) {
372
+ // the row is deleted anyways so nothing to do.
373
+ // just have some coffee.
374
+ } else {
375
+ alert(json.msg);
376
+ }
377
+ }
378
+ });
379
+ }
380
+
381
+ /**
382
+ * Edit / view window combined
383
+ *
384
+ */
385
+ $('#manage_snippets_table').on("click", '.snippet_edit_view_btn', function() {
386
+ var row = $(this).closest('.snippet_row');
387
+ var id = $(row).data('id') || 0;
388
+ var title_el = $(row).find('.snippet_title');
389
+ var title = title_el.html().trim();
390
+ var content_el = $(row).find('.snippet_content');
391
+ var content = content_el.html().trim();
392
+
393
+ // decode entities: browsers will encode '&' and other chars. We want the chars unencoded i.e. not as &amp;
394
+ // https://stackoverflow.com/questions/1147359/how-to-decode-html-entities-using-jquery
395
+ title = $("<textarea/>").html(title).val();
396
+ content = $("<textarea/>").html(content).val();
397
+
398
+ $('.edit_id').val(id);
399
+ $('.edit_title').val(title);
400
+ $('.edit_content').val(content);
401
+
402
+ var orb_ctc_cloud_lib_edit_snippet_dlg = $("#edit_snippet").dialog( {
403
+ dialogClass: 'edit_snippet',
404
+ modal: true,
405
+ autoOpen: true,
406
+ // autoOpen: false,
407
+ show : false,
408
+ width : 'auto',
409
+ resizable: true,
410
+ minWidth: 300,
411
+ minHeight: 300,
412
+ position: { my: "center", at: "center", of: window },
413
+ buttons: [
414
+ {
415
+ text: 'Save Changes',
416
+ class: 'button-primary',
417
+ click: function() {
418
+ $('.orb_ctc_ext_cloud_lib_edit_snippet_form').trigger('submit');
419
+ $(this).dialog("close");
420
+ }
421
+ },
422
+ {
423
+ text: 'Close',
424
+ class: 'button',
425
+ click: function() {
426
+ $(this).dialog('close');
427
+ }
428
+ }
429
+ ],
430
+ close: function(event, ui) {
431
+ $('.snippet_edit_view_btn').blur(); //???
432
+ }
433
+ });
434
+ });
435
+
436
+ function snippet_update(id, title, text) {
437
+ id = parseInt(id);
438
+ id = id || 0;
439
+ var $row_to_update = '';
440
+
441
+ // in edit for show msg
442
+ var res_container = $('.new_snippet_wrapper').find('.result');
443
+ res_container.html('Please, wait ...');
444
+
445
+ if (id <= 0) {
446
+ $('#no_snippets_row').hide();
447
+ $row_to_update = $('#manage_snippets_table .snippet_row:first').clone();
448
+ $row_to_update.show();
449
+
450
+ // newest snippets go first.
451
+ $('#manage_snippets_table').prepend($row_to_update);
452
+
453
+ // update max items via js
454
+ $('.usage_items').text(get_snippet_count());
455
+ } else {
456
+ $row_to_update = $('.snippet_row_' + id);
457
+ }
458
+
459
+ var submit_btn = $('.new_snippet_wrapper').find(':submit');
460
+ submit_btn.hide();
461
+
462
+ $row_to_update.find('.snippet_title').html('Please, wait...');
463
+ $row_to_update.find('.snippet_content').empty().hide();
464
+
465
+ $.ajax({
466
+ url: ajaxurl,
467
+ data: {
468
+ id : id,
469
+ title : title,
470
+ text : text,
471
+ action: "orb_ctc_addon_cloud_lib_cloud_update"
472
+ },
473
+ success: function (json) {
474
+ res_container.html(json.msg);
475
+ submit_btn.show();
476
+
477
+ if (json.status) {
478
+ $row_to_update.data('id', json.data.id);
479
+ $row_to_update.prop('id', json.data.id);
480
+ $row_to_update.find('.snippet_title').html(title);
481
+ $row_to_update.removeClass('snippet_row_0');
482
+ $row_to_update.addClass('snippet_row_' + json.data.id);
483
+ $row_to_update.find('.snippet_content').html(text);
484
+ $row_to_update.find('.snippet_content').show();
485
+
486
+ setTimeout(function () {
487
+ res_container.empty();
488
+ $('.orb_ctc_ext_cloud_lib_add_new_snippet_form').trigger('reset');
489
+ $('.orb_ctc_ext_cloud_lib_add_new_snippet_form .add_snippet_text').focus();
490
+ }, 2500);
491
+ } else {
492
+
493
+ }
494
+ }
495
+ });
496
+ }
497
+
498
+ /**
499
+ * View snippet button
500
+ *
501
+ * Displays View snippet window
502
+ *
503
+ */
504
+ $('.snippet_view_btn').on("click", function() {
505
+
506
+ //var id = $(this).parents('tr').data('id');
507
+ //var title = $(this).parents('tr').data('title');
508
+ var title = $(this).parents('tr').children('td.title_cell').children('.snippet_title').text();
509
+ //var content = $(this).parents('tr').data('content');
510
+ var content = $(this).parents('tr').children('td.title_cell').children('.snippet_content').text();
511
+
512
+ $('.view_title').val(title);
513
+ $('.view_content').val(content);
514
+ //$('.edit_snippet').show();
515
+
516
+ $("#view_snippet").dialog( {
517
+ dialogClass: 'view_snippet',
518
+ modal: true,
519
+ resizable: false,
520
+ buttons: [{
521
+ text: "Copy",
522
+ "class": 'button-primary',
523
+ click: function() {
524
+ $(this).dialog("close");
525
+ //todo make copy button actually work
526
+ }
527
+ },
528
+ {
529
+ text: "Close",
530
+ "class": 'button',
531
+ click: function() {
532
+ $(this).dialog("close");
533
+ }
534
+ }],
535
+ close: function(event, ui) {
536
+ }
537
+ });
538
+ });
539
+
540
+ // https://api.jqueryui.com/tabs/
541
+ // https://stackoverflow.com/questions/3641154/jquery-trapping-tab-select-event
542
+ $( '.orb_ctc_addon_cloud_lib_tabs' ).tabs({
543
+ heightStyle: "auto", // All panels will be set to the height of the tallest panel.
544
+ activate : function(event, ui) {
545
+ if (ui.newPanel.selector == '#orb_ctc_ext_cloud_lib_add') {
546
+ if ($('#add_snippet_title').val().trim() == '') {
547
+ $('#add_snippet_title').focus();
548
+ } else {
549
+ $('#add_snippet_text').focus();
550
+ }
551
+ } else if (ui.newPanel.selector == '#orb_ctc_ext_cloud_lib_signup') {
552
+ if ($('#orb_ctc_email').val() == '') {
553
+ $('#orb_ctc_email').focus();
554
+ } else {
555
+ $('#orb_ctc_pass2').focus();
556
+ }
557
+ } else if (ui.newPanel.selector == '#orb_ctc_ext_cloud_lib_login') {
558
+ if ($('#orb_ctc_login_email').val() == '') {
559
+ $('#orb_ctc_login_email').focus();
560
+ } else {
561
+ $('#orb_ctc_login_pass').focus();
562
+ }
563
+ }
564
+ }
565
+ })
566
+ // https://stackoverflow.com/questions/436587/jquery-ui-tabs-automatic-height
567
+ .css({
568
+ 'min-height': '250px',
569
+ 'overflow': 'auto'
570
+ });
571
+
572
+ // update max items via js
573
+ $('.usage_items').text(get_snippet_count());
574
+ });
addons/cloud_lib/assets/custom.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .orb_cloud_lib_wrapper span.label{font-weight:700;color:#3c7504;margin-bottom:5px;margin-top:10px;display:inline-block}.orb_cloud_lib_wrapper span.descr{font-size:14px;margin-bottom:5px;display:inline-block}.orb_ctc_ext_cloud_lib_search .selector{width:70%}.orb_cloud_lib_wrapper .half_text{width:50%}.orb_cloud_lib_wrapper .ui-autocomplete-loading{background:url(images/loader.gif) right center no-repeat}.orb_cloud_lib_wrapper .ui-widget-header{border:0;background:inherit}.orb_cloud_lib_wrapper .ui-tabs .ui-tabs-nav{padding:2px}.orb_cloud_lib_wrapper .tabcontent{padding:5px!important;margin:0 5px!important}.orb_cloud_lib_wrapper .ui-widget-content{padding:0}.orb_cloud_lib_wrapper .text_75p{width:75%}.orb_cloud_lib_wrapper h3{margin:.5em 0}.orb_cloud_lib_wrapper .nav-tab-wrapper{margin:0!important;padding:0!important}.orb_cloud_lib_wrapper .app_hide{display:none}.orb_cloud_lib_wrapper .delete_snippet_title{font-size:14px;font-weight:700;font-style:italic}.orb_cloud_lib_wrapper .edit_title,.orb_cloud_lib_wrapper .view_title{width:100%;margin-bottom:10px;border-radius:5px;min-width:330px!important}.orb_cloud_lib_wrapper .edit_content,.orb_cloud_lib_wrapper .view_content{width:100%;min-height:300px;border-radius:5px;min-width:330px!important}.orb_cloud_lib_wrapper #edit_snippet h3,.orb_cloud_lib_wrapper #view_snippet h3{margin-top:0}.orb_cloud_lib_wrapper .manage_snippets h3{padding-left:10px}.orb_cloud_lib_wrapper .button.snippet_delete_btn,.orb_cloud_lib_wrapper .button.snippet_edit_btn,.orb_cloud_lib_wrapper .button.snippet_edit_view_btn,.orb_cloud_lib_wrapper .button.snippet_view_btn{color:#fff}.orb_cloud_lib_wrapper .button.snippet_view_btn{background-image:linear-gradient(#1e8cbe,#0074a2)}.orb_cloud_lib_wrapper .button.snippet_edit_btn,.orb_cloud_lib_wrapper .button.snippet_edit_view_btn{background-image:linear-gradient(#4f8916,#244900)}.orb_cloud_lib_wrapper .button.snippet_delete_btn{background-image:linear-gradient(#e50202,#750303)}.orb_cloud_lib_wrapper .manage_snippets_table_wrapper{overflow:auto;font-size:14px;max-height:350px}.orb_cloud_lib_wrapper .manage_snippets_table_wrapper table tr td{padding:0;margin-bottom:5px;font-size:14px}.orb_cloud_lib_wrapper .manage_snippets_table_wrapper table tr td.td_title{font-size:14px}.orb_cloud_lib_wrapper .hover_row:hover{background:#ff9}.orb_cloud_lib_wrapper .manage_snippets_table_wrapper table tr .cmd_row{width:45%;text-align:right;vertical-align:middle}.orb_cloud_lib_wrapper .truncate{width:250px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.orb_cloud_lib_wrapper .alt_row{background:#eee}
addons/cloud_lib/assets/custom.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(document).ready(function(t){function e(e){t.ajax({type:"post",url:ajaxurl,data:{action:"orb_ctc_addon_cloud_lib_search",search:e},success:function(e){e.status&&e.data.length>0&&t.map(e.data,function(e){"[]"!=e&&(t(".found_snippet").show(),t("#found_snippet_text").val(e.content).focus(),t("#found_snippet_title").val(e.title).focus())})}})}function i(){return t("#manage_snippets_table .snippet_row").length-1}function n(e){t(".snippet_row_"+e).remove(),t("#manage_snippets_table .snippet_row:visible").length<=0?t("#no_snippets_row").show():t("#no_snippets_row").hide(),t.ajax({url:ajaxurl,data:{id:e,action:"orb_ctc_addon_cloud_lib_delete"},success:function(e){t(".usage_items").text(i()),e.status||alert(e.msg)}})}function o(e,n,o){e=(e=parseInt(e))||0;var s="",a=t(".new_snippet_wrapper").find(".result");a.html("Please, wait ..."),e<=0?(t("#no_snippets_row").hide(),(s=t("#manage_snippets_table .snippet_row:first").clone()).show(),t("#manage_snippets_table").prepend(s),t(".usage_items").text(i())):s=t(".snippet_row_"+e);var l=t(".new_snippet_wrapper").find(":submit");l.hide(),s.find(".snippet_title").html("Please, wait..."),s.find(".snippet_content").empty().hide(),t.ajax({url:ajaxurl,data:{id:e,title:n,text:o,action:"orb_ctc_addon_cloud_lib_cloud_update"},success:function(e){a.html(e.msg),l.show(),e.status&&(s.data("id",e.data.id),s.prop("id",e.data.id),s.find(".snippet_title").html(n),s.removeClass("snippet_row_0"),s.addClass("snippet_row_"+e.data.id),s.find(".snippet_content").html(o),s.find(".snippet_content").show(),setTimeout(function(){a.empty(),t(".orb_ctc_ext_cloud_lib_add_new_snippet_form").trigger("reset"),t(".orb_ctc_ext_cloud_lib_add_new_snippet_form .add_snippet_text").focus()},2500))}})}t(".orb_ctc_ext_cloud_lib_account_log_out").on("click",function(e){e.preventDefault();var i={},n=t(".orb_ctc_ext_cloud_lib_account").find(".result");n.html("Please, wait ..."),t.ajax({type:"post",url:ajaxurl+"?action=orb_ctc_addon_cloud_lib_log_out",data:i,success:function(t){t.status?(n.html("Please, wait"),window.location.reload()):n.html(t.msg)}})}),t(".orb_ctc_signup_form").on("submit",function(e){e.preventDefault();var i=t(this).serialize();if(t(".orb_ctc_pass").val()!=t(".orb_ctc_pass2").val())return alert("Error: Passwords do not match"),!1;var n=t(this).find(":submit"),o=t(".orb_ctc_ext_cloud_lib_signup_wrapper").find(".result");return o.html("Please, wait"),n.hide(),t.ajax({type:"post",url:ajaxurl+"?action=orb_ctc_addon_cloud_lib_signup",data:i,success:function(t){if(t.status)o.html("Please, wait"),window.location.reload();else{var e=t.msg||"There was an error with the registration. Contact us and report if you think this is a glitch.";o.html(e),n.show()}}}),!1}),t(".orb_ctc_ext_cloud_lib_edit_snippet_form").on("submit",function(e){return e.preventDefault(),o(t(".edit_id").val().trim()||0,t(".edit_title").val().trim(),t(".edit_content").val().trim()),!1}),t(".orb_ctc_login_form").on("submit",function(e){e.preventDefault();var i=t(this).serialize(),n=t(this).find(":submit"),o=t(".orb_ctc_ext_cloud_lib_login_wrapper").find(".result");return o.html("Please, wait"),n.hide(),t.ajax({type:"post",url:ajaxurl+"?action=orb_ctc_addon_cloud_lib_login",data:i,success:function(t){if(t.status)o.html("Please, wait"),window.location.reload();else{var e=t.msg||"Login details are incorrect.";o.html(e),n.show()}}}),!1}),t("#search_text").autocomplete({minLength:3,open:function(){t(this).removeClass("ui-corner-all").addClass("ui-corner-top")},close:function(){t(this).removeClass("ui-corner-top").addClass("ui-corner-all")},source:function(e,i){t.ajax({type:"post",url:ajaxurl,data:{action:"orb_ctc_addon_cloud_lib_autocomplete",term:e.term},success:function(e){i(t.map(e.data,function(t){return{value:t.id,label:t.title}}))},select:function(t,e){}})}}),t("#snippet_search_btn").on("click",function(){var i=t("#search_text").val().trim();""!==i?e(i):t("#search_text").focus()}),t("#search_text").keypress(function(i){if(13==i.keyCode||13==i.which){var n=t("#search_text").val().trim();""!==n?e(n):t("#search_text").focus()}}),t("#search_text").on("autocompleteselect",function(i,n){var o=n.item.label;""!==o?e(o):t("#search_text").focus()}),t("#new_snippet_btn").on("click",function(){t(".new_snippet_wrapper").show("slow")}),t("#add_snippet_title").on("keypress",function(e){return 13!=e.keyCode&&13!=e.which||(e.preventDefault(),t("#snippet_save_btn").trigger("click"),!1)}),t(document).on("keydown",".add_snippet_text",function(e){return!e.ctrlKey||13!=e.keyCode&&13!=e.which||(e.preventDefault(),t("#snippet_save_btn").trigger("click"),!1)}),t(document).on("keydown",".edit_title",function(e){return!!(e.ctrlKey||13!=e.keyCode&&13!=e.which)||(t(".edit_content").focus(),!1)}),t(document).on("keydown",".edit_title,.edit_content",function(e){return!e.ctrlKey||13!=e.keyCode&&13!=e.which||(e.preventDefault(),t("#edit_snippet").dialog("close"),t(".orb_ctc_ext_cloud_lib_edit_snippet_form").trigger("submit"),!1)}),t(".orb_ctc_ext_cloud_lib_add_new_snippet_form").on("submit",function(t){return t.preventDefault(),!1}),t("#snippet_save_btn").on("click",function(e){o(0,t("#add_snippet_title").val().trim(),t("#add_snippet_text").val().trim())}),t("#manage_snippets_table").on("click",".snippet_delete_btn",function(){var e=t(this).closest("tr").data("id"),i=t(this).closest("tr").children("td.title_cell").children(".snippet_title").text();t(".delete_snippet_title").text(i),t("#snippet_confirm_dialog_delete").dialog({dialogClass:"snippet_confirm_dialog_delete",modal:!0,resizable:!1,draggable:!1,buttons:[{text:"Yes",class:"button-primary",click:function(){t(this).dialog("close"),n(e)}},{text:"No",class:"button",click:function(){t(this).dialog("close")}}],close:function(e,i){t(".snippet_delete_btn").blur()}})}),t("#manage_snippets_table").on("click",".snippet_edit_view_btn",function(){var e=t(this).closest(".snippet_row"),i=t(e).data("id")||0,n=t(e).find(".snippet_title").html().trim(),o=t(e).find(".snippet_content").html().trim();n=t("<textarea/>").html(n).val(),o=t("<textarea/>").html(o).val(),t(".edit_id").val(i),t(".edit_title").val(n),t(".edit_content").val(o);t("#edit_snippet").dialog({dialogClass:"edit_snippet",modal:!0,autoOpen:!0,show:!1,width:"auto",resizable:!0,minWidth:300,minHeight:300,position:{my:"center",at:"center",of:window},buttons:[{text:"Save Changes",class:"button-primary",click:function(){t(".orb_ctc_ext_cloud_lib_edit_snippet_form").trigger("submit"),t(this).dialog("close")}},{text:"Close",class:"button",click:function(){t(this).dialog("close")}}],close:function(e,i){t(".snippet_edit_view_btn").blur()}})}),t(".snippet_view_btn").on("click",function(){var e=t(this).parents("tr").children("td.title_cell").children(".snippet_title").text(),i=t(this).parents("tr").children("td.title_cell").children(".snippet_content").text();t(".view_title").val(e),t(".view_content").val(i),t("#view_snippet").dialog({dialogClass:"view_snippet",modal:!0,resizable:!1,buttons:[{text:"Copy",class:"button-primary",click:function(){t(this).dialog("close")}},{text:"Close",class:"button",click:function(){t(this).dialog("close")}}],close:function(t,e){}})}),t(".orb_ctc_addon_cloud_lib_tabs").tabs({heightStyle:"auto",activate:function(e,i){"#orb_ctc_ext_cloud_lib_add"==i.newPanel.selector?""==t("#add_snippet_title").val().trim()?t("#add_snippet_title").focus():t("#add_snippet_text").focus():"#orb_ctc_ext_cloud_lib_signup"==i.newPanel.selector?""==t("#orb_ctc_email").val()?t("#orb_ctc_email").focus():t("#orb_ctc_pass2").focus():"#orb_ctc_ext_cloud_lib_login"==i.newPanel.selector&&(""==t("#orb_ctc_login_email").val()?t("#orb_ctc_login_email").focus():t("#orb_ctc_login_pass").focus())}}).css({"min-height":"250px",overflow:"auto"}),t(".usage_items").text(i())});
addons/cloud_lib/assets/images/loader.gif ADDED
Binary file
addons/cloud_lib/assets/images/ui-icons_444444_256x240.png ADDED
Binary file
addons/cloud_lib/assets/images/ui-icons_555555_256x240.png ADDED
Binary file
addons/cloud_lib/assets/images/ui-icons_777620_256x240.png ADDED
Binary file
addons/cloud_lib/assets/images/ui-icons_777777_256x240.png ADDED
Binary file
addons/cloud_lib/assets/images/ui-icons_cc0000_256x240.png ADDED
Binary file
addons/cloud_lib/assets/images/ui-icons_ffffff_256x240.png ADDED
Binary file
addons/cloud_lib/init.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+
3
+ require_once( __DIR__ . '/lib/snippet_lib.php' );
4
+ require_once( __DIR__ . '/modules/cloud.php' );
addons/cloud_lib/lib/snippet_lib.php ADDED
@@ -0,0 +1,929 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ define('ORBISIUS_CHILD_THEME_CREATOR_EXT_CLOUD_LIB_MAX_ITEMS', 25);
4
+
5
+ /**
6
+ * Autocomplete
7
+ * Search for a snippet
8
+ * Add a snippet
9
+ *
10
+ */
11
+ class orbisius_ctc_cloud_lib {
12
+ /**
13
+ * @var string Url of remote API. The plugin will dynamically pick one
14
+ */
15
+ public $api_url = '';
16
+ public $live_api_url = 'https://orbisius.com/';
17
+ // public $dev_api_url = 'http://orb-ctc.qsandbox.com/';
18
+ public $dev_api_url = 'http://orbclub.com.clients.com/';
19
+ public $staging_api_url = 'http://orb-ctc.qsandbox.com/';
20
+ private $tabs = [];
21
+
22
+ public function __construct() {
23
+ if ( 0&&!empty( $_SERVER['DEV_ENV'])) {
24
+ $this->api_url = $this->dev_api_url;
25
+ } elseif ( !empty($_SERVER['HTTP_HOST'])
26
+ && 1) { // (stripos($_SERVER['HTTP_HOST'], '.clients.com') !== false)
27
+ $this->api_url = $this->staging_api_url;
28
+ } elseif ( !empty($_SERVER['HTTP_HOST'])
29
+ && (stripos($_SERVER['HTTP_HOST'], '.qsandbox.com') !== false)) {
30
+ $this->api_url = $this->staging_api_url;
31
+ } else {
32
+ $this->api_url = $this->live_api_url;
33
+ }
34
+
35
+ // We need to initialize the tabs here because we're using __ method
36
+ // for future internationalization.
37
+ $tabs = [
38
+ [
39
+ 'id' => 'orb_ctc_ext_cloud_lib_manage',
40
+ 'label' => __( 'Manage', 'orbisius-child-theme-creator' ),
41
+ ],
42
+ // Turning off the search for now. The users will use manage tab instead.
43
+ // [
44
+ // 'id' => 'orb_ctc_ext_cloud_lib_search',
45
+ // 'label' => __( 'Search', 'orbisius-child-theme-creator' ),
46
+ // ],
47
+ [
48
+ 'id' => 'orb_ctc_ext_cloud_lib_add',
49
+ 'label' => __( 'Add', 'orbisius-child-theme-creator' ),
50
+ ],
51
+ [
52
+ 'id' => 'orb_ctc_ext_cloud_lib_signup',
53
+ 'label' => __( 'Sign Up', 'orbisius-child-theme-creator' ),
54
+ ],
55
+ [
56
+ 'id' => 'orb_ctc_ext_cloud_lib_login',
57
+ 'label' => __( 'Login', 'orbisius-child-theme-creator' ),
58
+ ],
59
+ [
60
+ 'id' => 'orb_ctc_ext_cloud_lib_account',
61
+ 'label' => __( 'Account', 'orbisius-child-theme-creator' ),
62
+ ],
63
+ [
64
+ 'id' => 'orb_ctc_ext_cloud_lib_contact',
65
+ 'label' => __( 'Contact', 'orbisius-child-theme-creator' ),
66
+ ],
67
+ [
68
+ 'id' => 'orb_ctc_ext_cloud_lib_about',
69
+ 'label' => __( 'About', 'orbisius-child-theme-creator' ),
70
+ ],
71
+ ];
72
+
73
+ $this->tabs = $tabs;
74
+ }
75
+
76
+ public function get_api_url() {
77
+ return $this->api_url;
78
+ }
79
+
80
+ /**
81
+ * Add snippet librabry actions
82
+ */
83
+ public function enqueue_assets() {
84
+ wp_enqueue_script( 'jquery-ui-dialog' );
85
+ wp_enqueue_script( 'jquery-ui-autocomplete' );
86
+ wp_enqueue_script('jquery-ui-tabs');
87
+
88
+ $wp_scripts = wp_scripts();
89
+ wp_enqueue_style('orbisius_ctc_cloud_lib_jquery_ui',
90
+ '//ajax.googleapis.com/ajax/libs/jqueryui/' . $wp_scripts->registered['jquery-ui-core']->ver . '/themes/smoothness/jquery-ui.min.css',
91
+ false,
92
+ '1.0',
93
+ false
94
+ );
95
+
96
+ wp_register_script( 'orbisius_ctc_cloud_lib',
97
+ apply_filters('orbisius_child_theme_creator_filter_asset_src', "/addons/cloud_lib/assets/custom.js" ),
98
+ array('jquery', ),
99
+ apply_filters('orbisius_child_theme_creator_filter_asset_src',
100
+ "/addons/cloud_lib/assets/custom.js",
101
+ [ 'last_mod' => 1 ]
102
+ ),
103
+ true
104
+ );
105
+ wp_enqueue_script( 'orbisius_ctc_cloud_lib' );
106
+
107
+ //Custom styles for snippet library
108
+ wp_register_style('orbisius_ctc_cloud_lib',
109
+ apply_filters('orbisius_child_theme_creator_filter_asset_src', "/addons/cloud_lib/assets/custom.css" ),
110
+ null,
111
+ apply_filters('orbisius_child_theme_creator_filter_asset_src',
112
+ "/addons/cloud_lib/assets/custom.css",
113
+ [ 'last_mod' => 1 ]
114
+ ),
115
+ false
116
+ );
117
+ wp_enqueue_style('orbisius_ctc_cloud_lib');
118
+ }
119
+
120
+ /**
121
+ * Add snippet librabry actions
122
+ */
123
+ public function admin_init() {
124
+ add_action( 'orbisius_child_theme_creator_admin_enqueue_scripts', [$this, 'enqueue_assets'] );
125
+
126
+ // Snippet search ajax hook
127
+ add_action( 'wp_ajax_orb_ctc_addon_cloud_lib_signup', [$this, 'process_signup'] );
128
+ // add_action( 'wp_ajax_nopriv_orb_ctc_addon_cloud_lib_signup', [$this, 'process_signup'] );
129
+
130
+ // Log in
131
+ add_action( 'wp_ajax_orb_ctc_addon_cloud_lib_login', [$this, 'process_login'] );
132
+ // add_action( 'wp_ajax_nopriv_orb_ctc_addon_cloud_lib_login', [$this, 'process_login'] );
133
+
134
+ // Log out
135
+ add_action( 'wp_ajax_orb_ctc_addon_cloud_lib_log_out', [$this, 'process_log_out'] );
136
+ add_action( 'wp_ajax_nopriv_orb_ctc_addon_cloud_lib_log_out', [$this, 'process_log_out'] );
137
+
138
+ add_action( 'wp_ajax_orb_ctc_addon_cloud_lib_autocomplete', [$this, 'cloud_autocomplete'] );
139
+ // add_action( 'wp_ajax_nopriv_orb_ctc_addon_cloud_lib_autocomplete', [$this, 'cloud_autocomplete'] );
140
+
141
+ // Snippet search ajax hook
142
+ add_action( 'wp_ajax_orb_ctc_addon_cloud_lib_search', [$this, 'cloud_search'] );
143
+ // add_action( 'wp_ajax_nopriv_orb_ctc_addon_cloud_lib_search', [$this, 'cloud_search'] );
144
+
145
+ // Update a Snippet ajax hook
146
+ add_action( 'wp_ajax_orb_ctc_addon_cloud_lib_cloud_update', [$this, 'cloud_update'] );
147
+ // add_action( 'wp_ajax_nopriv_cloud_update', [$this, 'cloud_update'] );
148
+
149
+ // Delete a Snippet ajax hook
150
+ add_action( 'wp_ajax_orb_ctc_addon_cloud_lib_delete', [$this, 'cloud_delete'] );
151
+ // add_action( 'wp_ajax_nopriv_orb_ctc_addon_cloud_lib_delete', [$this, 'cloud_delete'] );
152
+ //
153
+ add_action( 'orbisius_child_theme_creator_addon_cloud_lib_action_auth_success', [$this, 'process_successful_auth'] );
154
+ }
155
+
156
+ /**
157
+ * Makes a request to API and get response
158
+ * @return JSON array response from the api
159
+ */
160
+ public function call($url, $req_params = []) {
161
+ // Prepend user's api key if any.
162
+ if (empty($req_params['orb_cloud_lib_data']['api_key'])) {
163
+ $user_api = orbisius_child_theme_creator_user::get_instance();
164
+ $api_key = $user_api->api_key();
165
+
166
+ if (!empty($api_key)) {
167
+ $req_params['orb_cloud_lib_data']['api_key'] = $api_key;
168
+ }
169
+ }
170
+
171
+ $res = new orbisius_child_theme_creator_result();
172
+
173
+ $wp_req_params = [
174
+ 'method' => 'POST', 'sslverify' => false,
175
+ 'timeout' => 20,
176
+ 'redirection' => 5,
177
+ 'blocking' => true,
178
+ 'body' => $req_params,
179
+ ];
180
+
181
+ $response = wp_remote_post($url, $wp_req_params);
182
+
183
+ if ( is_wp_error( $response ) ) {
184
+ $res->msg( $response->get_error_message() );
185
+ } else {
186
+ $json_str = wp_remote_retrieve_body($response);
187
+ $api_res = new orbisius_child_theme_creator_result($json_str);
188
+ $res->status(1); // current connection is OK.
189
+ $res->data('result', $api_res); // this is what API said. This could be status:0
190
+ }
191
+
192
+ return $res;
193
+ }
194
+
195
+ /**
196
+ * Signs up the user.
197
+ */
198
+ public function process_login() {
199
+ $pass = orbisius_child_theme_creator_get('orb_ctc_pass');
200
+ $email = orbisius_child_theme_creator_get('orb_ctc_email');
201
+
202
+ $params = [
203
+ 'orb_cloud_lib_data' => [
204
+ 'cmd' => 'user.login',
205
+ 'pass' => $pass,
206
+ 'email' => $email,
207
+ ]
208
+ ];
209
+
210
+ $req_res = $this->call($this->api_url, $params);
211
+
212
+ if ($req_res->is_success()) {
213
+ $api_res = $req_res->data('result');
214
+
215
+ $ctx = [
216
+ 'api_res' => $api_res,
217
+ ];
218
+
219
+ if ($api_res->is_success()) {
220
+ do_action('orbisius_child_theme_creator_addon_cloud_lib_action_auth_success', $ctx);
221
+ } else {
222
+ do_action('orbisius_child_theme_creator_addon_cloud_lib_action_auth_error', $ctx);
223
+ }
224
+ }
225
+
226
+ wp_send_json($req_res->is_success() ? $req_res->data('result') : $req_res->to_array());
227
+ }
228
+
229
+ /**
230
+ * This is called after login and register to update some meta info about plan & api key
231
+ * @param array $ctx
232
+ */
233
+ public function process_successful_auth($ctx) {
234
+ $api_res = $ctx['api_res'];
235
+ $user_api = orbisius_child_theme_creator_user::get_instance();
236
+
237
+ $api_key = $api_res->data('api_key');
238
+
239
+ if (!empty($api_key)) {
240
+ $user_api->api_key($api_key);
241
+ }
242
+
243
+ $email = $api_res->data('email');
244
+
245
+ if ( !empty($email)) {
246
+ $user_api->email($email);
247
+ }
248
+
249
+ $plan_data = $api_res->data('plan_data');
250
+
251
+ if (!empty($plan_data)) {
252
+ $plan_data = $user_api->plan($plan_data);
253
+ }
254
+ }
255
+
256
+ /**
257
+ * Deletes the api key saved in the current user's meta
258
+ */
259
+ public function process_log_out() {
260
+ $user_api = orbisius_child_theme_creator_user::get_instance();
261
+ $user_api->clear_account_data();
262
+
263
+ $req_res = new orbisius_child_theme_creator_result();
264
+ $req_res->status(1);
265
+ $req_res->data('result', new orbisius_child_theme_creator_result(1));
266
+
267
+ wp_send_json($req_res->is_success() ? $req_res->data('result') : $req_res->to_array());
268
+ }
269
+
270
+ /**
271
+ * Signs up the user.
272
+ */
273
+ public function process_signup() {
274
+ $pass = orbisius_child_theme_creator_get('orb_ctc_pass');
275
+ $email = orbisius_child_theme_creator_get('orb_ctc_email');
276
+
277
+ $params = [
278
+ 'orb_cloud_lib_data' => [
279
+ 'cmd' => 'user.register',
280
+ 'pass' => $pass,
281
+ 'email' => $email,
282
+ ]
283
+ ];
284
+
285
+ $req_res = $this->call($this->api_url, $params);
286
+
287
+ if ($req_res->is_success()) {
288
+ $api_res = $req_res->data('result');
289
+
290
+ $ctx = [
291
+ 'api_res' => $api_res,
292
+ ];
293
+
294
+ if ($api_res->is_success()) {
295
+ do_action('orbisius_child_theme_creator_addon_cloud_lib_action_auth_success', $ctx);
296
+ } else {
297
+ do_action('orbisius_child_theme_creator_addon_cloud_lib_action_auth_error', $ctx);
298
+ }
299
+ }
300
+
301
+ wp_send_json($req_res->is_success() ? $req_res->data('result') : $req_res->to_array());
302
+ }
303
+
304
+ /**
305
+ * Gets autocomplete suggestions from API based on data sent to the API
306
+ * @return JSON API's response
307
+ */
308
+ public function cloud_autocomplete() {
309
+ if (!empty($_REQUEST['term'])) {
310
+ $search_for = sanitize_text_field($_REQUEST['term']);
311
+
312
+ $params = [
313
+ 'orb_cloud_lib_data' => [
314
+ 'cmd' => 'item.list',
315
+ 'query' => $search_for,
316
+ ]
317
+ ];
318
+
319
+ $req_res = $this->call($this->api_url, $params);
320
+ wp_send_json($req_res->is_success() ? $req_res->data('result') : $req_res->to_array());
321
+ }
322
+ }
323
+
324
+ /**
325
+ * Sends search request to API
326
+ *@return JSON API's response
327
+ */
328
+ public function cloud_search() {
329
+ if (!empty($_REQUEST['search'])) {
330
+ $search_for = sanitize_text_field($_REQUEST['search']);
331
+
332
+ $params = [
333
+ 'orb_cloud_lib_data' => [
334
+ 'cmd' => 'item.list',
335
+ 'query' => $search_for,
336
+ ]
337
+ ];
338
+
339
+ $req_res = $this->call($this->api_url, $params);
340
+ wp_send_json($req_res->is_success() ? $req_res->data('result') : $req_res->to_array());
341
+ }
342
+ }
343
+
344
+ /**
345
+ * Updates a snippet by ID
346
+ * MUST send an ID to the API
347
+ * @return JSON array with API's response
348
+ */
349
+ public function cloud_update() {
350
+ $snippet_id = (int) orbisius_child_theme_creator_get('id');
351
+ $snippet_title = orbisius_child_theme_creator_get('title');
352
+ $snippet_text = orbisius_child_theme_creator_get('text');
353
+
354
+ $params = [
355
+ 'orb_cloud_lib_data' => [
356
+ 'cmd' => $snippet_id ? 'item.update' : 'item.add',
357
+ 'id' => $snippet_id,
358
+ 'title' => $snippet_title,
359
+ 'content' => $snippet_text,
360
+ ]
361
+ ];
362
+
363
+ $req_res = $this->call($this->api_url, $params);
364
+ wp_send_json($req_res->is_success() ? $req_res->data('result') : $req_res->to_array());
365
+ }
366
+
367
+ /**
368
+ * Deletes snippet by id
369
+ *
370
+ * MUST send an ID to the API
371
+ */
372
+ public function cloud_delete() {
373
+ if (!empty($_REQUEST['id'])) {
374
+ $id = sanitize_text_field($_REQUEST['id']);
375
+ $params = [
376
+ 'orb_cloud_lib_data' => [
377
+ 'cmd' => 'item.delete',
378
+ 'id' => $id,
379
+ ]
380
+ ];
381
+
382
+ $req_res = $this->call($this->api_url, $params);
383
+ wp_send_json($req_res->is_success() ? $req_res->data('result') : $req_res);
384
+ }
385
+ }
386
+
387
+ /**
388
+ *
389
+ * @return string
390
+ */
391
+ public function get_current_tab_id() {
392
+ // $this->tabs[0]['id']
393
+ $cur_tab_id = empty($_REQUEST['tab']) ? '' : wp_kses( $_REQUEST['tab'], [] );
394
+
395
+ if (empty($cur_tab_id)) {
396
+ $user_api = orbisius_child_theme_creator_user::get_instance();
397
+ $api_key = $user_api->api_key();
398
+
399
+ if (empty($api_key)) {
400
+ $cur_tab_id = 'orb_ctc_ext_cloud_lib_about';
401
+ } else {
402
+ $cur_tab_id = 'orb_ctc_ext_cloud_lib_manage';
403
+ }
404
+ }
405
+
406
+ return $cur_tab_id;
407
+ }
408
+
409
+ /**
410
+ *
411
+ */
412
+ public function render_tabs() {
413
+ $url = admin_url( 'themes.php?page=orbisius_child_theme_creator_theme_editor_action' );
414
+ $cur_tab_id = $this->get_current_tab_id();
415
+ ?>
416
+ <div id="orb_ctc_addon_cloud_lib_tabs" class="orb_ctc_addon_cloud_lib_tabs">
417
+ <div class="nav-tab-wrapper">
418
+ <ul>
419
+ <?php foreach ( $this->tabs as $tab_rec ) : ?>
420
+ <?php
421
+ if (!$this->should_render_tab($tab_rec)) {
422
+ continue;
423
+ }
424
+
425
+ $tab_url = add_query_arg( 'tab', $tab_rec['id'], $url );
426
+ $extra_tab_css = $tab_rec['id'] == $cur_tab_id ? 'ui-state-default ui-tabs-active' : ''; // nav-tab-active
427
+ ?>
428
+ <li class="nav-tab2 <?php echo $extra_tab_css;?>"><a href="<?php echo '#' . $tab_rec['id']; ?>"><?php echo $tab_rec['label'];?></a></li>
429
+ <?php endforeach; ?>
430
+ </ul>
431
+ </div>
432
+ <?php
433
+ }
434
+
435
+ /**
436
+ *
437
+ * @param str $tab_id
438
+ */
439
+ public function render_tab_content( $tab_id = '' ) {
440
+ $tab_id = empty($tab_id) ? $this->get_current_tab_id() : $tab_id;
441
+
442
+ $method_name = 'render_tab_content_' . $tab_id;
443
+
444
+ if (method_exists( $this, $method_name)) {
445
+ $this->$method_name();
446
+ } else {
447
+ echo "<!-- OCTC:Error: Invalid tab method. -->";
448
+ }
449
+ }
450
+
451
+ public function render_tab_content_orb_ctc_ext_cloud_lib_search() {
452
+ ?>
453
+ <!-- Search Snippets -->
454
+ <div id="orb_ctc_ext_cloud_lib_search" class="tabcontent orb_ctc_ext_cloud_lib_search">
455
+ <span class="descr">Start typing the title of your snippet to see suggestions</span>
456
+ <br />
457
+ <input class="selector" id="search_text"></input>
458
+ <input class="button button-primary" type="button" id="snippet_search_btn" value="Search" />
459
+
460
+ <div class="found_snippet app_hide">
461
+ <span class="label">Title:</span>
462
+ <input class="widefat" type="text" id="found_snippet_title"></textarea>
463
+ <br />
464
+ <span class="label">Snippet:</span>
465
+ <textarea class="widefat" id="found_snippet_text"></textarea>
466
+ </div>
467
+ </div>
468
+
469
+ <!-- /Search Snippets -->
470
+ <?php
471
+ }
472
+
473
+ /**
474
+ *
475
+ */
476
+ public function render_tab_content_orb_ctc_ext_cloud_lib_add() {
477
+ ?>
478
+ <!-- New Snippet -->
479
+ <div id="orb_ctc_ext_cloud_lib_add" class="tabcontent orb_ctc_ext_cloud_lib_add">
480
+ <div id="new_snippet_wrapper" class="new_snippet_wrapper">
481
+ <form method="POST" id="orb_ctc_ext_cloud_lib_add_new_snippet_form" class="orb_ctc_ext_cloud_lib_add_new_snippet_form">
482
+ Title/label<br/>
483
+ <input type="text" id="add_snippet_title"
484
+ required=""
485
+ class="add_snippet_title widefat"
486
+ autocomplete="off"
487
+ value=""
488
+ placeholder="Title" />
489
+ <br /><br />
490
+ Code/license key/content<br/>
491
+ <textarea id="add_snippet_text" class="widefat add_snippet_text"
492
+ required="" placeholder="Snippet content"></textarea>
493
+ <br /><br />
494
+ <input type="submit" id="snippet_save_btn"
495
+ class="button button-primary snippet_save_btn" value="Save Changes" />
496
+ </form>
497
+
498
+ <div class="result"></div>
499
+ </div>
500
+ <!-- /New Snippet -->
501
+
502
+ <!-- Confirm dialog save snippet -->
503
+ <div id="snippet_confirm_dialog" title="" class="snippet_confirm_dialog app_hide">
504
+ <p>Are you sure you want to save a snippet without any content?</p>
505
+ </div>
506
+ <!-- /Confirm dialog save snippet -->
507
+ </div>
508
+ <?php
509
+ }
510
+
511
+ /**
512
+ * Manage snippets tab view
513
+ *
514
+ * Shows all available snippets with View, Edit and Delete button
515
+ */
516
+ public function render_tab_content_orb_ctc_ext_cloud_lib_manage() {
517
+ $all_snippets = $this->get_user_snippets();
518
+
519
+ ?>
520
+ <div id="orb_ctc_ext_cloud_lib_manage" class="tabcontent orb_ctc_ext_cloud_lib_manage">
521
+ <!-- Manage snippets -->
522
+ <div class="manage_snippets">
523
+ <!--<h3>My Snippets</h3>-->
524
+ <div class="manage_snippets_table_wrapper">
525
+ <table id="manage_snippets_table" class="widefat manage_snippets_table">
526
+ <?php
527
+ $no_items_css = '';
528
+
529
+ if (empty($all_snippets)) {
530
+ $all_snippets = [];
531
+ } else {
532
+ $no_items_css = 'app_hide';
533
+ }
534
+
535
+ // We prepend a blan row which will be hidden if the ID is 0.
536
+ // It will used when adding a new item. The row will be cloned.
537
+ $all_snippets = array_merge( [ $this->get_blank_snippet() ], $all_snippets);
538
+ ?>
539
+
540
+ <tr id="no_snippets_row" class="no_snippets_row no_snippets_alert <?php echo $no_items_css;?>">
541
+ <td colspan="2">
542
+ <span id="no_snippets_alert">You don't haven any snippets.</span>
543
+ </td>
544
+ </tr>
545
+
546
+ <?php foreach( $all_snippets as $idx => $rec) : ?>
547
+ <tr id="snippet_<?php echo esc_attr($rec['id']); ?>"
548
+ class="hover_row snippet_row snippet_row_<?php echo esc_attr($rec['id']); ?>
549
+ <?php echo $idx % 2 == 1 ? 'alt_row' : ''; ?>
550
+ <?php echo empty($rec['id']) ? 'app_hide' :''; ?>"
551
+ data-id="<?php echo esc_attr($rec['id']); ?>">
552
+ <td id="td_title" class="title_cell">
553
+ <div class="snippet_title truncate">
554
+ <?php echo esc_attr($rec['title']); ?>
555
+ </div>
556
+ <div id="snippet_content_<?php echo esc_attr($rec['id']);?>"
557
+ class="truncate snippet_content snippet_content_<?php echo esc_attr($rec['id']);?>"><?php
558
+ echo esc_attr($rec['content']);
559
+ ?></div>
560
+ </td>
561
+ <td class="cmd_row">
562
+ <button class="button orb_ctc_copy_btn"
563
+ data-clipboard-action="copy"
564
+ data-clipboard-target="#snippet_content_<?php echo esc_attr($rec['id']);?>"
565
+ >Copy</button>
566
+ <input class="button snippet_edit_view_btn" type="button" value="Edit">
567
+ <input class="button snippet_delete_btn" type="button" value="X">
568
+ </td>
569
+ </tr>
570
+ <?php endforeach; ?>
571
+ </table>
572
+ </div>
573
+
574
+ <div id="orb_ctc_ext_cloud_lib_edit" class="tabcontent orb_ctc_ext_cloud_lib_edit">
575
+ <div id="edit_snippet_wrapper" class="edit_snippet_wrapper">
576
+ <form method="POST" id="orb_ctc_ext_cloud_lib_edit_snippet_form" class="orb_ctc_ext_cloud_lib_edit_snippet_form">
577
+ <!-- Edit snippet window -->
578
+ <div id="edit_snippet" class="edit_snippet app_hide" title="Edit Snippet">
579
+ <input type="hidden" id="edit_id" class="edit_id" name="id" value="0"/>
580
+ <input type="text" id="edit_title" class="edit_title" name="title" autocomplete="off" />
581
+ <br />
582
+ <textarea id="edit_content" class="edit_content" name="content"></textarea>
583
+ <br />
584
+ <br />
585
+ </div>
586
+ </form>
587
+ </div>
588
+ </div>
589
+ <!-- /Edit snippet window -->
590
+
591
+ <!-- View snippet window -->
592
+ <div id="view_snippet" class="view_snippet app_hide">
593
+ <h3>View Snippet</h3>
594
+ <input class="view_title">
595
+ <br />
596
+ <textarea class="view_content"></textarea>
597
+ <br />
598
+ <br />
599
+ <!-- /View snippet window -->
600
+ </div>
601
+ <!-- /View snippet window -->
602
+ </div>
603
+ <!-- /Manage snippets -->
604
+
605
+ <!-- Delete snippet confirm dialog -->
606
+ <div id="snippet_confirm_dialog_delete" class="snippet_confirm_dialog_delete app_hide" title="Delete">
607
+ <p>Are you sure you want to delete this snippet with title <span class="delete_snippet_title"></span>?</p>
608
+ </div>
609
+ <!-- /Delete snippet confirm dialog -->
610
+ </div>
611
+ <?php
612
+ }
613
+
614
+ /**
615
+ * About tab view
616
+ *
617
+ * Shows all available snippets with View, Edit and Delete button
618
+ */
619
+ public function render_tab_content_orb_ctc_ext_cloud_lib_signup() {
620
+ ?>
621
+ <div id="orb_ctc_ext_cloud_lib_signup" class="tabcontent">
622
+ <div id="orb_ctc_ext_cloud_lib_signup_wrapper" class="orb_ctc_ext_cloud_lib_signup_wrapper">
623
+ <!--<h3>Sign Up</h3>-->
624
+ <div class="">
625
+ <form name="orb_ctc_signup_form" id="orb_ctc_signup_form" class="orb_ctc_signup_form" method="post">
626
+ <p>
627
+ <label for="orb_ctc_email">Email Address<br />
628
+ <input type="email" name="orb_ctc_email" id="orb_ctc_email" class="input orb_ctc_email" value="" size="42" required="" /></label>
629
+ </p>
630
+ <p>
631
+ <label for="orb_ctc_pass">Password<br />
632
+ <input type="password" name="orb_ctc_pass" id="orb_ctc_pass"
633
+ class="input orb_ctc_pass" value="" size="42" required="" /></label>
634
+ </p>
635
+ <p>
636
+ <label for="orb_ctc_pass">Password (repeat)<br />
637
+ <input type="password" name="orb_ctc_pass2" id="orb_ctc_pass2"
638
+ class="input orb_ctc_pass2" value="" size="42" required="" /></label>
639
+ </p>
640
+ <p class="submit">
641
+ <input type="submit" name="orb_ctc_signup_submit" id="orb_ctc_signup_submit"
642
+ class="button button-primary button-large" value="Sign Up" />
643
+ </p>
644
+ </form>
645
+
646
+ <div class="result">
647
+
648
+ </div>
649
+ </div>
650
+ </div> <!-- /orb_ctc_ext_cloud_lib_signup_wrapper -->
651
+ </div>
652
+ <?php
653
+ }
654
+
655
+ /**
656
+ * About tab view
657
+ *
658
+ * Shows all available snippets with View, Edit and Delete button
659
+ */
660
+ public function render_tab_content_orb_ctc_ext_cloud_lib_login() {
661
+ ?>
662
+ <div id="orb_ctc_ext_cloud_lib_login" class="tabcontent">
663
+ <div id="orb_ctc_ext_cloud_lib_login_wrapper" class="orb_ctc_ext_cloud_lib_login_wrapper">
664
+ <!--<h3>Log in</h3>-->
665
+ <div class="">
666
+ <form name="orb_ctc_login_form" id="orb_ctc_login_form" class="orb_ctc_login_form" method="post">
667
+ <p>
668
+ <label for="orb_ctc_login_email">Email Address<br />
669
+ <input type="email" name="orb_ctc_email" id="orb_ctc_login_email" class="input" value="" size="42" required="" /></label>
670
+ </p>
671
+ <p>
672
+ <label for="orb_ctc_login_pass">Password<br />
673
+ <input type="password" name="orb_ctc_pass" id="orb_ctc_login_pass"
674
+ class="input" value="" size="42" required="" /></label>
675
+ </p>
676
+ <p class="submit">
677
+ <input type="submit" name="orb_ctc_login_submit" id="orb_ctc_login_submit"
678
+ class="button button-primary button-large" value="Log in" />
679
+ </p>
680
+ </form>
681
+
682
+ <div class="result">
683
+
684
+ </div>
685
+ </div>
686
+ </div> <!-- /orb_ctc_ext_cloud_lib_login_wrapper -->
687
+ </div>
688
+ <?php
689
+ }
690
+
691
+ /**
692
+ * About tab view
693
+ *
694
+ * Shows all available snippets with View, Edit and Delete button
695
+ */
696
+ public function render_tab_content_orb_ctc_ext_cloud_lib_account() {
697
+ $user_api = orbisius_child_theme_creator_user::get_instance();
698
+ $email = $user_api->email();
699
+ $api_key = '';
700
+
701
+ if (isset($_REQUEST['load_orb_cloud_api_key'])) {
702
+ $api_key = $user_api->api_key();
703
+ }
704
+ $plan_data = $user_api->plan();
705
+
706
+ ?>
707
+ <div id="orb_ctc_ext_cloud_lib_account" class="tabcontent orb_ctc_ext_cloud_lib_account">
708
+ <div class="orb_ctc_ext_cloud_lib_account_wrapper">
709
+ <!--<h3>Account</h3>-->
710
+ <div class="email_wrapper">
711
+ Email: <?php echo $email; ?>
712
+ </div>
713
+
714
+ <?php if (!empty($api_key)) : ?>
715
+ <div class="api_key_wrapper">
716
+ Orbisius API Key: <?php echo $api_key; ?>
717
+ </div>
718
+ <?php endif; ?>
719
+
720
+ <?php if (!empty($plan_data)) : ?>
721
+ <div class="api_orb_plan">
722
+ <?php foreach ($plan_data as $key => $value) {
723
+ $val_fmt = $value;
724
+
725
+ if ($key == 'price') {
726
+ $val_fmt = $value <= 0 ? 'Free plan' : $value;
727
+ }
728
+
729
+ if ($key == 'max_items') {
730
+ $val_fmt = $this->get_max_snippets();
731
+ }
732
+
733
+ $key_fmt = preg_replace('#[\-\_]+#si', ' ', $key);
734
+ $key_fmt = ucwords($key_fmt);
735
+ echo esc_attr($key_fmt) . ": <span id='$key' class='$key'>" . esc_attr($val_fmt) . "</span><br />\n";
736
+ }
737
+ ?>
738
+ Orbisius API URL (system): <?php echo $this->get_api_url(); ?>
739
+ </div> <!-- /api_orb_plan -->
740
+ <?php endif; ?>
741
+
742
+ <hr/>
743
+ <div class="api_orb_pricing">
744
+ <a href="//orbisius.com/plans/?utm_source=ctc&utm_medium=cloud_lib"
745
+ target="_blank"
746
+ title="See plans [new window/tab]"
747
+ class="button button-primary">Upgrade / See plans</a>
748
+ |
749
+ <?php
750
+
751
+ // This info is passed to the content link.
752
+ // See the title of the contact link so the user doesn't have to re-enter that info.
753
+ $e = [
754
+ 'site' => site_url(),
755
+ 'email' => $email,
756
+ 'api_key' => $api_key,
757
+ ];
758
+ ?>
759
+ <a href="//orbisius.com/contact/quick-contact/?utm_source=ctc&utm_medium=cloud_lib&<?php echo http_build_query($e);?>"
760
+ target="_blank"
761
+ title="Contact us with a suggestion, bug report etc. This link includes your email, API key, site url so you don't have to enter it again to get support. [new window/tab]"
762
+ class="button">Contact Us</a>
763
+ |
764
+ <a href='#' id='orb_ctc_ext_cloud_lib_account_log_out'
765
+ title="Logs you out and remove Orbisius cloud account data from ths WordPress installation."
766
+ class="button orb_ctc_ext_cloud_lib_account_log_out"> Log out</a>
767
+ </div>
768
+
769
+ <div class="result">
770
+ </div>
771
+ </div> <!-- /orb_ctc_ext_cloud_lib_account_wrapper -->
772
+ </div>
773
+ <?php
774
+ }
775
+
776
+ public function get_max_snippets() {
777
+ return ORBISIUS_CHILD_THEME_CREATOR_EXT_CLOUD_LIB_MAX_ITEMS;
778
+ }
779
+
780
+ /**
781
+ * About tab view
782
+ *
783
+ * Shows all available snippets with View, Edit and Delete button
784
+ */
785
+ public function render_tab_content_orb_ctc_ext_cloud_lib_about() {
786
+ ?>
787
+ <div id="orb_ctc_ext_cloud_lib_about" class="tabcontent">
788
+ <div class="orb_ctc_ext_cloud_lib_about_wrapper">
789
+ <!--<h3>About</h3>-->
790
+ <div class="">
791
+ Orbisius Cloud library enables you to store your snippets, license keys etc in the Orbisius Cloud Library.
792
+ You can access those snippets from other WordPress installations.
793
+ With your free Orbisius account and you can store up to
794
+ <?php echo $this->get_max_snippets();?> snippets for free.
795
+ </div>
796
+ </div> <!-- /orb_ctc_ext_cloud_lib_about_wrapper -->
797
+ </div>
798
+ <?php
799
+ }
800
+
801
+ /**
802
+ * Contact tab view
803
+ */
804
+ public function render_tab_content_orb_ctc_ext_cloud_lib_contact() {
805
+ $e = [
806
+ 'tab' => 'contact',
807
+ ];
808
+ ?>
809
+ <div id="orb_ctc_ext_cloud_lib_contact" class="tabcontent">
810
+ <div class="orb_ctc_ext_cloud_lib_contact_wrapper">
811
+ <!--<h3>About</h3>-->
812
+ <div class="">
813
+ Please, report any glitches you may find. We'd really appreciate it.
814
+ <a href="//orbisius.com/contact/quick-contact/?utm_source=ctc&utm_medium=cloud_lib&<?php echo http_build_query($e);?>"
815
+ target="_blank"
816
+ title="Contact us with a suggestion, bug report etc. This link includes your email, API key, site url so you don't have to enter it again to get support. [new window/tab]"
817
+ class="button-primary">Contact Us</a>
818
+
819
+ you can also email us at: <a href="mailto:help@orbisius.com?subject=ctc cloud lib feedback" class="">help@orbisius.com</a>
820
+ </div>
821
+ </div> <!-- /orb_ctc_ext_cloud_lib_contact_wrapper -->
822
+ </div>
823
+ <?php
824
+ }
825
+
826
+ /**
827
+ *
828
+ * @return array
829
+ */
830
+ public function get_blank_snippet() {
831
+ $arr = [
832
+ 'id' => 0,
833
+ 'title' => '',
834
+ 'content' => '',
835
+ ];
836
+
837
+ return $arr;
838
+ }
839
+
840
+ /**
841
+ * Manage snippets tab
842
+ * Displays all present snippets
843
+ *
844
+ * @return array decoded response from API
845
+ */
846
+ public function get_user_snippets() {
847
+ $params = [
848
+ 'orb_cloud_lib_data' => [
849
+ 'cmd' => 'item.list',
850
+ ]
851
+ ];
852
+
853
+ $req_res = $this->call($this->api_url, $params);
854
+ $snippets = [];
855
+
856
+ if ( $req_res->is_success() ) {
857
+ $api_result = $req_res->data('result');
858
+ $snippets = $api_result->data();
859
+ }
860
+
861
+ $snippets = empty($snippets) ? [] : $snippets;
862
+
863
+ return $snippets;
864
+ }
865
+
866
+ /**
867
+ *
868
+ * @param str $json_api_response
869
+ * @return array
870
+ */
871
+ public function decode_response($json_api_response) {
872
+ $def_res = new orbisius_child_theme_creator_result();
873
+ $json = empty($json_api_response) || ! is_scalar($json_api_response)
874
+ ? $def_res->to_array()
875
+ : json_decode( $json_api_response, true );
876
+ return $json;
877
+ }
878
+
879
+ /**
880
+ * Performs some checks to decide which tabs to show when the user hasn't
881
+ * joined Orbisius.
882
+ * if the api key exists skip signup tab if it doesn't leave only about & signup tabs
883
+ * @param array $tab_rec
884
+ */
885
+ public function should_render_tab($tab_rec = []) {
886
+ $user_api = orbisius_child_theme_creator_user::get_instance();
887
+ $api_key = $user_api->api_key();
888
+ $render = 1;
889
+
890
+ if (!empty($api_key)) {
891
+ if (preg_match('#signup|login#si', $tab_rec['id'])) {
892
+ $render = 0;
893
+ }
894
+ } else {
895
+ if (!preg_match('#signup|login|about|contact#si', $tab_rec['id'])) {
896
+ $render = 0;
897
+ }
898
+ }
899
+
900
+ return $render;
901
+ }
902
+
903
+ /**
904
+ *
905
+ * @param array $ctx
906
+ */
907
+ public function render_ui($ctx = []) {
908
+ $place = empty($ctx['place']) ? 'left' : $ctx['place'];
909
+ $user_api = orbisius_child_theme_creator_user::get_instance();
910
+ $api_key = $user_api->api_key();
911
+ ?>
912
+ <div id="orb_cloud_lib_wrapper_<?php echo $place;?>" class="orb_cloud_lib_wrapper orb_cloud_lib_wrapper_<?php echo $place;?>">
913
+ <div class="snippet_wrapper">
914
+ <h3>Orbisius Cloud Library</h3>
915
+ <?php $this->render_tabs(); ?>
916
+ <?php
917
+ foreach ( $this->tabs as $tab_rec ) {
918
+ if (!$this->should_render_tab($tab_rec)) {
919
+ continue;
920
+ }
921
+
922
+ $this->render_tab_content( $tab_rec['id'] );
923
+ }
924
+ ?>
925
+ </div>
926
+ </div> <!-- /Snippet Library Wrapper -->
927
+ <?php
928
+ }
929
+ }
addons/cloud_lib/modules/cloud.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $obj = new orbisius_ctc_cloud_lib();
4
+
5
+ add_action( 'admin_init', array( $obj, 'admin_init' ) );
6
+ add_action( 'orbisius_child_theme_creator_editors_ext_action_left_start', [ $obj, 'render_ui' ] );
7
+
addons/init.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (file_exists( ORBISIUS_CHILD_THEME_CREATOR_BASE_DIR . '/addons/cloud_lib/init.php' ) ) {
4
+ require_once( ORBISIUS_CHILD_THEME_CREATOR_BASE_DIR . '/addons/cloud_lib/init.php' );
5
+ }
6
+
7
+ require_once( ORBISIUS_CHILD_THEME_CREATOR_BASE_DIR . '/addons/clipboard/init.php' );
8
+
lib/000_singleton.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Allows sub classes to have a convenient get_instance method.
5
+ */
6
+ class orbisius_child_theme_creator_singleton {
7
+
8
+ /**
9
+ * Singleton pattern i.e. we have only one instance of this obj
10
+ *
11
+ * @staticvar type $instance
12
+ * @return \cls
13
+ */
14
+ public static function get_instance() {
15
+ static $instance = null;
16
+
17
+ // This will make the calling class to be instantiated.
18
+ // no need each sub class to define this method.
19
+ if (is_null($instance)) {
20
+ $instance = new static();
21
+ }
22
+
23
+ return $instance;
24
+ }
25
+ }
lib/result.php ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class orbisius_child_theme_creator_result {
4
+ // I put them as public even though I need them private.
5
+ // reason: private fields don't appear in a JSON output
6
+ public $msg = '';
7
+ public $code = '';
8
+ public $status = 0;
9
+ public $data = array();
10
+
11
+ /**
12
+ * Populates the internal variables from contr params.
13
+ * @param str/array $json
14
+ */
15
+ public function __construct( $json = '' ) {
16
+ if ( ! empty( $json ) ) {
17
+ if ( is_numeric( $json ) ) { // set the initial status
18
+ $this->status = (int) $json;
19
+ } elseif ( is_string( $json ) ) {
20
+ $json = json_decode( $json, true );
21
+ } elseif ( is_object( $json ) ) {
22
+ $json = (array) $json;
23
+ }
24
+
25
+ if ( is_array( $json ) ) {
26
+ foreach ( $json as $key => $value ) {
27
+ $this->$key = $value;
28
+ }
29
+ }
30
+ }
31
+ }
32
+
33
+ public function status( $new_status = null ) {
34
+ if ( ! is_null( $new_status ) ) {
35
+ $this->status = $new_status;
36
+ }
37
+
38
+ return $this->status;
39
+ }
40
+
41
+ /**
42
+ * returns or sets a message
43
+ * @param str $msg
44
+ * @return str
45
+ */
46
+ public function code($code = '') {
47
+ if (!empty($code)) {
48
+ $this->code = $code;
49
+ }
50
+
51
+ return $this->code;
52
+ }
53
+
54
+ /**
55
+ * Alias to msg
56
+ * @param str $new_message
57
+ * @return str
58
+ */
59
+ public function message( $new_message = null ) {
60
+ return $this->msg($new_message);
61
+ }
62
+
63
+ /**
64
+ * returns or sets a message
65
+ * @param str $msg
66
+ * @return str
67
+ */
68
+ public function msg($msg = '') {
69
+ if (!empty($msg)) {
70
+ $this->msg = trim( $msg );
71
+ }
72
+
73
+ return $this->msg;
74
+ }
75
+
76
+ public function success() {
77
+ return !empty($this->status);
78
+ }
79
+
80
+ public function is_success() {
81
+ return !empty($this->status);
82
+ }
83
+
84
+ public function error() {
85
+ return empty($this->status);
86
+ }
87
+
88
+ public function is_error() {
89
+ return empty($this->status);
90
+ }
91
+
92
+ const OVERRIDE_FLAG = 2;
93
+ const DONT_OVERRIDE_FLAG = 4;
94
+
95
+ /**
96
+ * Extracts data from the params and populates the internal data array.
97
+ * It's useful when storing data from another request
98
+ *
99
+ * @param str/array/obj $json
100
+ * @param int $flag
101
+ */
102
+ public function populate_data($json, $flag = self::DONT_OVERRIDE_FLAG ) {
103
+ if ( is_string( $json ) ) {
104
+ $json = json_decode( $json, true );
105
+ } else if ( is_object( $json ) ) {
106
+ $json = (array) $json;
107
+ }
108
+
109
+ if ( is_array( $json ) ) {
110
+ foreach ( $json as $key => $value ) {
111
+ if ( isset( $this->data[$key] ) && ( $flag & self::DONT_OVERRIDE_FLAG ) ) {
112
+ continue;
113
+ }
114
+
115
+ $this->data[$key] = $value;
116
+ }
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Data container.
122
+ *
123
+ * @param str $key
124
+ * @param str $val
125
+ * @return mixed
126
+ */
127
+ public function data($key = '', $val = null) {
128
+ if (is_array($key)) { // when we pass an array -> override all
129
+ $this->data = empty($this->data) ? $key : array_merge($this->data, $key);
130
+ } elseif (!empty($key)) {
131
+ if (!is_null($val)) { // add/update a value
132
+ $this->data[$key] = $val;
133
+ }
134
+
135
+ return isset($this->data[$key]) ? $this->data[$key] : null;
136
+ } else { // nothing return all data
137
+ $val = $this->data;
138
+ }
139
+
140
+ return $val;
141
+ }
142
+
143
+ public function to_array() {
144
+ $var = $this;
145
+ return (array) $var;
146
+ }
147
+ }
148
+
lib/user.php ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class orbisius_child_theme_creator_user extends orbisius_child_theme_creator_singleton {
4
+ private $api_meta_key = '_orb_ctc_cloud_api_key';
5
+ private $meta_cloud_plan = '_orb_ctc_cloud_plan';
6
+ private $meta_cloud_email = '_orb_ctc_cloud_email';
7
+
8
+ /**
9
+ *
10
+ * @param str/opt $key
11
+ * @return str
12
+ */
13
+ public function api_key($key = null) {
14
+ static $val = null;
15
+
16
+ if (!is_null($val) && is_null($key)) { // get
17
+ return $val;
18
+ }
19
+
20
+ $user_id = $this->get_user_id();
21
+
22
+ if (!empty($key)) {
23
+ $up_status = update_user_meta($user_id, $this->api_meta_key, $key);
24
+ $val = get_user_meta($user_id, $this->api_meta_key, true);
25
+ } elseif (!is_null($key)) { // empty string so delete
26
+ delete_user_meta($user_id, $this->api_meta_key);
27
+ $val = null;
28
+ } else {
29
+ $val = get_user_meta($user_id, $this->api_meta_key, true);
30
+ }
31
+
32
+ return $val;
33
+ }
34
+
35
+ /**
36
+ *
37
+ * @param str/opt $data
38
+ * @return str
39
+ */
40
+ public function plan($data = null) {
41
+ static $val = null;
42
+
43
+ if (!is_null($val) && is_null($data)) { // get
44
+ return $val;
45
+ }
46
+
47
+ $user_id = $this->get_user_id();
48
+
49
+ if (!empty($data)) {
50
+ $up_status = update_user_meta($user_id, $this->meta_cloud_plan, $data);
51
+ $val = get_user_meta($user_id, $this->meta_cloud_plan, true);
52
+ } elseif (!is_null($data)) { // empty string so delete
53
+ delete_user_meta($user_id, $this->meta_cloud_plan);
54
+ $val = null;
55
+ } else {
56
+ $val = get_user_meta($user_id, $this->meta_cloud_plan, true);
57
+ }
58
+
59
+ return $val;
60
+ }
61
+
62
+ /**
63
+ *
64
+ * @param str/opt $key
65
+ * @return str
66
+ */
67
+ public function email($key = null) {
68
+ static $val = null;
69
+
70
+ if (!is_null($val) && is_null($key)) { // get
71
+ return $val;
72
+ }
73
+
74
+ $user_id = $this->get_user_id();
75
+
76
+ if (!empty($key)) {
77
+ $up_status = update_user_meta($user_id, $this->meta_cloud_email, $key);
78
+ $val = get_user_meta($user_id, $this->meta_cloud_email, true);
79
+ } elseif (!is_null($key)) { // empty string so delete
80
+ delete_user_meta($user_id, $this->meta_cloud_email);
81
+ $val = null;
82
+ } else {
83
+ $val = get_user_meta($user_id, $this->meta_cloud_email, true);
84
+ }
85
+
86
+ return $val;
87
+ }
88
+
89
+ /**
90
+ *
91
+ * @param str/opt $key
92
+ * @return str
93
+ */
94
+ public function get_user_id() {
95
+ $user_id = get_current_user_id();
96
+ return $user_id;
97
+ }
98
+
99
+ /**
100
+ * Clears some plan related info so it's fresh for next time.
101
+ */
102
+ public function clear_account_data() {
103
+ $this->plan('');
104
+ $this->email('');
105
+ $this->api_key('');
106
+ }
107
+
108
+ }
nbproject/private/private.xml CHANGED
@@ -1,6 +1,6 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <project-private xmlns="http://www.netbeans.org/ns/project-private/1">
3
- <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="21">
4
  <file>
5
  <url>assets/main.js</url>
6
  <bookmark id="19">
@@ -13,72 +13,108 @@
13
  <url>orbisius-child-theme-creator.php</url>
14
  <bookmark id="20">
15
  <name/>
16
- <line>98</line>
17
  <key/>
18
  </bookmark>
19
  <bookmark id="21">
20
  <name/>
21
- <line>689</line>
22
  <key/>
23
  </bookmark>
24
  <bookmark id="15">
25
  <name/>
26
- <line>1432</line>
27
  <key/>
28
  </bookmark>
29
  <bookmark id="16">
30
  <name/>
31
- <line>1573</line>
32
  <key/>
33
  </bookmark>
34
  <bookmark id="6">
35
  <name/>
36
- <line>1647</line>
37
  <key/>
38
  </bookmark>
39
  <bookmark id="14">
40
  <name/>
41
- <line>1725</line>
42
  <key/>
43
  </bookmark>
44
  <bookmark id="12">
45
  <name/>
46
- <line>2182</line>
47
  <key/>
48
  </bookmark>
49
  <bookmark id="9">
50
  <name/>
51
- <line>2187</line>
52
  <key/>
53
  </bookmark>
54
  <bookmark id="5">
55
  <name/>
56
- <line>2229</line>
57
  <key/>
58
  </bookmark>
59
  <bookmark id="18">
60
  <name/>
61
- <line>2239</line>
62
  <key/>
63
  </bookmark>
64
  <bookmark id="4">
65
  <name/>
66
- <line>2344</line>
67
  <key/>
68
  </bookmark>
69
  <bookmark id="17">
70
  <name/>
71
- <line>2377</line>
72
  <key/>
73
  </bookmark>
74
  <bookmark id="13">
75
  <name/>
76
- <line>2559</line>
77
  <key/>
78
  </bookmark>
79
  <bookmark id="3">
80
  <name/>
81
- <line>2604</line>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  <key/>
83
  </bookmark>
84
  </file>
@@ -98,7 +134,11 @@
98
  <file>file:/C:/Copy/Dropbox/cloud/projects/default/htdocs/wordpress313/wp-content/plugins/orbisius-child-theme-creator/readme.txt</file>
99
  </group>
100
  <group>
101
- <file>file:/C:/Copy/Dropbox/cloud/projects/default/htdocs/wordpress313/wp-content/plugins/orbisius-child-theme-creator/orbisius-child-theme-creator.php</file>
 
 
 
 
102
  </group>
103
  </open-files>
104
  </project-private>
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <project-private xmlns="http://www.netbeans.org/ns/project-private/1">
3
+ <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="33">
4
  <file>
5
  <url>assets/main.js</url>
6
  <bookmark id="19">
13
  <url>orbisius-child-theme-creator.php</url>
14
  <bookmark id="20">
15
  <name/>
16
+ <line>105</line>
17
  <key/>
18
  </bookmark>
19
  <bookmark id="21">
20
  <name/>
21
+ <line>696</line>
22
  <key/>
23
  </bookmark>
24
  <bookmark id="15">
25
  <name/>
26
+ <line>1464</line>
27
  <key/>
28
  </bookmark>
29
  <bookmark id="16">
30
  <name/>
31
+ <line>1605</line>
32
  <key/>
33
  </bookmark>
34
  <bookmark id="6">
35
  <name/>
36
+ <line>1679</line>
37
  <key/>
38
  </bookmark>
39
  <bookmark id="14">
40
  <name/>
41
+ <line>1757</line>
42
  <key/>
43
  </bookmark>
44
  <bookmark id="12">
45
  <name/>
46
+ <line>2214</line>
47
  <key/>
48
  </bookmark>
49
  <bookmark id="9">
50
  <name/>
51
+ <line>2219</line>
52
  <key/>
53
  </bookmark>
54
  <bookmark id="5">
55
  <name/>
56
+ <line>2261</line>
57
  <key/>
58
  </bookmark>
59
  <bookmark id="18">
60
  <name/>
61
+ <line>2271</line>
62
  <key/>
63
  </bookmark>
64
  <bookmark id="4">
65
  <name/>
66
+ <line>2378</line>
67
  <key/>
68
  </bookmark>
69
  <bookmark id="17">
70
  <name/>
71
+ <line>2410</line>
72
  <key/>
73
  </bookmark>
74
  <bookmark id="13">
75
  <name/>
76
+ <line>2592</line>
77
  <key/>
78
  </bookmark>
79
  <bookmark id="3">
80
  <name/>
81
+ <line>2637</line>
82
+ <key/>
83
+ </bookmark>
84
+ </file>
85
+ <file>
86
+ <url>addons/cloud_lib/assets/custom.js</url>
87
+ <bookmark id="29">
88
+ <name/>
89
+ <line>285</line>
90
+ <key/>
91
+ </bookmark>
92
+ <bookmark id="30">
93
+ <name/>
94
+ <line>364</line>
95
+ <key/>
96
+ </bookmark>
97
+ <bookmark id="33">
98
+ <name/>
99
+ <line>404</line>
100
+ <key/>
101
+ </bookmark>
102
+ </file>
103
+ <file>
104
+ <url>addons/cloud_lib/lib/snippet_lib.php</url>
105
+ <bookmark id="28">
106
+ <name/>
107
+ <line>329</line>
108
+ <key/>
109
+ </bookmark>
110
+ <bookmark id="27">
111
+ <name/>
112
+ <line>329</line>
113
+ <key/>
114
+ </bookmark>
115
+ <bookmark id="26">
116
+ <name/>
117
+ <line>457</line>
118
  <key/>
119
  </bookmark>
120
  </file>
134
  <file>file:/C:/Copy/Dropbox/cloud/projects/default/htdocs/wordpress313/wp-content/plugins/orbisius-child-theme-creator/readme.txt</file>
135
  </group>
136
  <group>
137
+ <file>file:/C:/Copy/Dropbox/cloud/projects/default/htdocs/wordpress313/wp-content/plugins/orbisius-child-theme-creator/addons/cloud_lib/assets/custom.js</file>
138
+ <file>file:/C:/Copy/Dropbox/cloud/projects/default/htdocs/wordpress313/wp-content/plugins/orbisius-child-theme-creator/addons/cloud_lib/lib/snippet_lib.php</file>
139
+ <file>file:/C:/Copy/Dropbox/cloud/projects/default/htdocs/wordpress313/wp-content/plugins/orbisius-child-theme-creator/addons/cloud_lib/assets/custom.css</file>
140
+ <file>file:/C:/Copy/Dropbox/cloud/projects/default/htdocs/wordpress313/wp-content/plugins/orbisius-child-theme-creator/docs/snippets.txt</file>
141
+ <file>file:/C:/Copy/Dropbox/cloud/projects/default/htdocs/wordpress313/wp-content/plugins/orbisius-child-theme-creator/lib/user.php</file>
142
  </group>
143
  </open-files>
144
  </project-private>
orbisius-child-theme-creator.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Orbisius Child Theme Creator
4
  Plugin URI: http://orbisius.com/products/wordpress-plugins/orbisius-child-theme-creator/
5
  Description: This plugin allows you to quickly create child themes from any theme that you have currently installed on your site/blog.
6
- Version: 1.4.0
7
  Author: Svetoslav Marinov (Slavi)
8
  Author URI: http://orbisius.com
9
  */
@@ -25,6 +25,7 @@
25
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26
  */
27
 
 
28
  define( 'ORBISIUS_CHILD_THEME_CREATOR_MAIN_PLUGIN_FILE', __FILE__ );
29
 
30
  // Set up plugin
@@ -45,7 +46,13 @@ add_action( 'wp_ajax_nopriv_orbisius_ctc_theme_editor_ajax', 'orbisius_ctc_theme
45
 
46
  register_activation_hook( __FILE__, 'orbisius_child_theme_creator_on_activate' );
47
 
48
- require_once( __DIR__ . '/addons/cloud_lib/init.php' );
 
 
 
 
 
 
49
 
50
  /**
51
  * Adds admin bar items for easy access to the theme creator and editor
@@ -259,6 +266,38 @@ function orbisius_child_theme_creator_set_options($opts = array(), $override = 0
259
  return $opts;
260
  }
261
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262
  /**
263
  * @package Orbisius Child Theme Creator
264
  * @since 1.0
@@ -271,7 +310,7 @@ function orbisius_child_theme_creator_admin_enqueue_scripts($current_page = '')
271
  return ;
272
  }
273
 
274
- $suffix = empty($_SERVER['DEV_ENV']) ? '.min' : '';
275
 
276
  wp_register_style('orbisius_child_theme_creator', plugins_url("/assets/main{$suffix}.css", __FILE__), false,
277
  filemtime( plugin_dir_path( __FILE__ ) . "/assets/main{$suffix}.css" ) );
@@ -282,7 +321,7 @@ function orbisius_child_theme_creator_admin_enqueue_scripts($current_page = '')
282
  filemtime( plugin_dir_path( __FILE__ ) . "/assets/main{$suffix}.js" ), true);
283
  wp_enqueue_script( 'orbisius_child_theme_creator' );
284
 
285
- do_action( 'orbisius_child_theme_creator_admin_enqueue_scripts', [] );
286
  }
287
 
288
  /**
@@ -1352,13 +1391,38 @@ function orbisius_child_theme_creator_tools_action() {
1352
  * If you must unslash, consider only doing it to your own data which isn't used by others:
1353
  * @see http://codex.wordpress.org/Function_Reference/stripslashes_deep
1354
  */
1355
- function orbisius_child_theme_creator_get_request() {
1356
  $req = $_REQUEST;
1357
  $req = stripslashes_deep($req);
1358
 
 
 
 
 
 
1359
  return $req;
1360
  }
1361
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1362
  /**
1363
  * adds some HTML comments in the page so people would know that this plugin powers their site.
1364
  */
@@ -2198,7 +2262,7 @@ function orbisius_ctc_theme_editor() {
2198
 
2199
  <?php
2200
  $buff = $theme_1_file = $theme_2_file = '';
2201
- $req = orbisius_ctc_theme_editor_get_request();
2202
 
2203
  $current_theme = wp_get_theme();
2204
 
@@ -2256,111 +2320,112 @@ function orbisius_ctc_theme_editor() {
2256
  </span>
2257
 
2258
  <div id="theme_1_file_contents_container">
2259
- <textarea id="theme_1_file_contents" name="theme_1_file_contents" rows="22" class="widefat"></textarea>
2260
  </div>
2261
 
2262
  <div class="orbisius_ctc_theme_editor_theme_1_primary_buttons primary_buttons">
2263
  <button type='submit' class='button button-primary' id="theme_1_submit" name="theme_1_submit">Save Changes</button>
2264
  <span class="status"></span>
2265
  </div>
 
2266
 
2267
- <hr />
2268
- <div class="orbisius_ctc_theme_editor_theme_1_secondary_buttons secondary_buttons">
2269
- <button type="button" class='button' id="theme_1_new_file_btn" name="theme_1_new_file_btn">New File</button>
2270
- <button type="button" class='button' id="theme_1_syntax_chk_btn" name="theme_1_syntax_chk_btn">PHP Syntax Check</button>
2271
- <button type="button" class='button' id="theme_1_send_btn" name="theme_1_send_btn">Send</button>
2272
- <a href="<?php echo site_url('/');?>" class='button' target="_blank" title="new tab/window"
2273
- id="theme_1_site_preview_btn" name="theme_1_site_preview_btn">View Site</a>
2274
 
2275
- <?php do_action('orbisius_child_theme_creator_editors_ext_actions', 'theme_1'); ?>
 
 
 
 
 
 
2276
 
2277
- <!--
2278
- <button type="button" class='button' id="theme_1_new_folder_btn" name="theme_1_new_folder_btn">New Folder</button>-->
2279
 
2280
- <a href='javascript:void(0)' class='app-button-right app-button-negative' id="theme_1_delete_file_btn" name="theme_1_delete_file_btn">Delete File</a>
 
2281
 
2282
- <div id='theme_1_new_file_container' class="theme_1_new_file_container app-hide">
2283
- <strong>New File</strong>
2284
- <input type="text" id="theme_1_new_file" name="theme_1_new_file" value="" />
2285
- <span>e.g. test.js, extra.css, headers/header-two.php etc</span>
2286
 
2287
- <!--<br/>
2288
- <label>
2289
- <input type="checkbox" name="theme_1_new_file_type" value="folder" />
2290
- Create a folder Instead
2291
- </label>-->
2292
 
2293
- <span class="status"></span>
 
 
 
 
2294
 
2295
- <br/>
2296
- <button type='button' class='button button-primary' id="theme_1_new_file_btn_ok" name="theme_1_new_file_btn_ok">Save</button>
2297
- <a href='javascript:void(0)' class='app-button-negative00 button delete' id="theme_1_new_file_btn_cancel" name="theme_1_new_file_btn_cancel">Cancel</a>
2298
- </div>
2299
 
2300
- <!-- send -->
2301
- <div id='theme_1_send_container' class="theme_1_send_container app-hide">
2302
- <p>
2303
- Email selected theme and parent theme (if any) to yourself or a colleague.
2304
- Separate multiple emails with commas.<br/>
2305
- <strong>To:</strong>
2306
- <input type="text" id="theme_1_send_to" name="email" value="" placeholder="Enter email" />
2307
 
2308
- <button type='button' class='button button-primary' id="theme_1_send_btn_ok" name="theme_1_send_btn_ok">Send</button>
2309
- <a href='javascript:void(0)' class='app-button-negative00 button delete'
2310
- id="theme_1_send_btn_cancel" name="theme_1_send_btn_cancel">Cancel</a>
2311
- </p>
2312
- </div>
2313
- <!-- /send -->
 
 
 
 
 
 
 
 
2314
 
2315
- <?php do_action('orbisius_child_theme_creator_editors_ext_action_left_start', array( 'place' => 'left' ) ); ?>
2316
- <?php do_action('orbisius_child_theme_creator_editors_ext_action_left_end', array( 'place' => 'left' ) ); ?>
2317
-
2318
- <div style="border:1px solid #ccc;margin:10px 0;padding:3px 5px;">
2319
- <h3>Pro Addon
2320
- <?php if ( ! orbisius_child_theme_creator_is_pro_installed() ) : ?>
2321
- <ul>
2322
- <li>Syntax Highlighting</li>
2323
- <li>Better dropdown for selecting themes and files</li>
2324
- <li>Soon: snippet library stored in the cloud</li>
2325
- <li></li>
2326
- </ul>
2327
- <?php endif; ?>
2328
- </h3>
2329
-
2330
- <?php if ( orbisius_child_theme_creator_is_pro_installed() ) : ?>
2331
- <div class="app-alert-success">
2332
- The <a href="//orbisius.com/products/wordpress-plugins/orbisius-child-theme-creator-pro/?utm_source=orbisius-child-theme-editor&utm_medium=footer&utm_campaign=product"
2333
- target="_blank" title="[new window]" style="font-weight: bolder;text-decoration: underline;">Pro Addon</a>
2334
- is up and running. Thanks for supporting our <a
2335
- href="//orbisius.com/products/wordpress-plugins/?utm_source=orbisius-child-theme-editor&utm_medium=footer&utm_campaign=product" target="_blank">work</a>!
2336
- </div>
2337
- <?php else : ?>
2338
- <span>Get more cool features by purchasing the </span>
2339
- <a href="//orbisius.com/products/wordpress-plugins/orbisius-child-theme-creator-pro/?utm_source=orbisius-child-theme-editor&utm_medium=footer&utm_campaign=product"
2340
- target="_blank" title="[new window]" style="font-weight: bolder;color:red;text-decoration: underline;">Pro Addon</a>
2341
- <?php endif; ?>
2342
 
2343
- <!--<ul>
2344
- <li><a href="//orbisius.com/products/wordpress-plugins/orbisius-theme-switcher/?utm_source=orbisius-child-theme-creator&utm_medium=editors&utm_campaign=product"
2345
- target="_blank" title="Opens in a new tab/window">Orbisius Theme Switcher</a> - Allows you to preview any of the installed themes on your site.</li>
2346
- </ul>-->
2347
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2348
 
2349
- <!-- new folder -->
2350
- <!--
2351
- <div id='theme_1_new_folder_container' class="theme_1_new_folder_container app-hide">
2352
- <strong>New Folder</strong>
2353
- <input type="text" id="theme_1_new_folder" name="theme_1_new_folder" value="" />
2354
- <span>e.g. includes, data</span>
2355
- <span class="status"></span>
2356
 
2357
- <br/>
2358
- <button type='button' class='button button-primary' id="theme_1_new_folder_btn_ok" name="theme_1_new_folder_btn_ok">Save</button>
2359
- <a href='javascript:void(0)' class='app-button-negative00 button delete' id="theme_1_new_folder_btn_cancel" name="theme_1_new_folder_btn_cancel">Cancel</a>
2360
- </div>-->
2361
- <!-- /new folder -->
2362
- </div> <!-- /secondary_buttons -->
2363
- </form>
2364
  </td>
2365
  <td width="50%">
2366
  <form id="orbisius_ctc_theme_editor_theme_2_form" class="orbisius_ctc_theme_editor_theme_2_form">
@@ -2379,7 +2444,7 @@ function orbisius_ctc_theme_editor() {
2379
  </span>
2380
 
2381
  <div id="theme_2_file_contents_container">
2382
- <textarea id="theme_2_file_contents" name="theme_2_file_contents" rows="22" class="widefat"></textarea>
2383
  </div>
2384
 
2385
  <div class="orbisius_ctc_theme_editor_theme_2_primary_buttons primary_buttons">
@@ -2449,7 +2514,7 @@ function orbisius_ctc_theme_editor_no_auth_ajax() {
2449
  function orbisius_ctc_theme_editor_ajax() {
2450
  $buff = 'INVALID AJAX SUB_CMD';
2451
 
2452
- $req = orbisius_ctc_theme_editor_get_request();
2453
  $sub_cmd = empty($req['sub_cmd']) ? '' : $req['sub_cmd'];
2454
 
2455
  switch ($sub_cmd) {
@@ -2645,19 +2710,6 @@ function orbisius_ctc_theme_editor_check_syntax($theme_file_contents) {
2645
  return $status_rec;
2646
  }
2647
 
2648
- /**
2649
- * It seems WP intentionally adds slashes for consistency with php.
2650
- * Please note: WordPress Core and most plugins will still be expecting slashes, and the above code will confuse and break them.
2651
- * If you must unslash, consider only doing it to your own data which isn't used by others:
2652
- * @see http://codex.wordpress.org/Function_Reference/stripslashes_deep
2653
- */
2654
- function orbisius_ctc_theme_editor_get_request() {
2655
- $req = $_REQUEST;
2656
- $req = stripslashes_deep( $req );
2657
-
2658
- return $req;
2659
- }
2660
-
2661
  /**
2662
  * This returns an HTML select with the selected theme's files.
2663
  * the name/id of that select must be either theme_1_file or theme_2_file
@@ -2665,7 +2717,7 @@ function orbisius_ctc_theme_editor_get_request() {
2665
  */
2666
  function orbisius_ctc_theme_editor_generate_dropdown() {
2667
  $theme_base_dir = $theme_1_file = '';
2668
- $req = orbisius_ctc_theme_editor_get_request();
2669
 
2670
  $select_name = 'theme_1_file';
2671
 
@@ -2715,7 +2767,7 @@ function orbisius_ctc_theme_editor_manage_file( $cmd_id = 1 ) {
2715
 
2716
  $buff = $theme_base_dir = $theme_dir = $theme_file = '';
2717
 
2718
- $req = orbisius_ctc_theme_editor_get_request();
2719
 
2720
  $theme_root = trailingslashit( get_theme_root() );
2721
 
3
  Plugin Name: Orbisius Child Theme Creator
4
  Plugin URI: http://orbisius.com/products/wordpress-plugins/orbisius-child-theme-creator/
5
  Description: This plugin allows you to quickly create child themes from any theme that you have currently installed on your site/blog.
6
+ Version: 1.4.1
7
  Author: Svetoslav Marinov (Slavi)
8
  Author URI: http://orbisius.com
9
  */
25
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26
  */
27
 
28
+ define( 'ORBISIUS_CHILD_THEME_CREATOR_BASE_DIR', __DIR__ );
29
  define( 'ORBISIUS_CHILD_THEME_CREATOR_MAIN_PLUGIN_FILE', __FILE__ );
30
 
31
  // Set up plugin
46
 
47
  register_activation_hook( __FILE__, 'orbisius_child_theme_creator_on_activate' );
48
 
49
+ require_once( ORBISIUS_CHILD_THEME_CREATOR_BASE_DIR . '/lib/000_singleton.php' );
50
+ require_once( ORBISIUS_CHILD_THEME_CREATOR_BASE_DIR . '/lib/result.php' );
51
+ require_once( ORBISIUS_CHILD_THEME_CREATOR_BASE_DIR . '/lib/user.php' );
52
+
53
+ if (file_exists( ORBISIUS_CHILD_THEME_CREATOR_BASE_DIR . '/addons/init.php' ) ) {
54
+ require_once( ORBISIUS_CHILD_THEME_CREATOR_BASE_DIR . '/addons/init.php' );
55
+ }
56
 
57
  /**
58
  * Adds admin bar items for easy access to the theme creator and editor
266
  return $opts;
267
  }
268
 
269
+ function orbisius_child_theme_creator_is_live_env() {
270
+ return empty($_SERVER['DEV_ENV']);
271
+ }
272
+
273
+ add_filter('orbisius_child_theme_creator_filter_asset_src', 'orbisius_child_theme_creator_fix_asset_src', 10, 2);
274
+ function orbisius_child_theme_creator_fix_asset_src($src, $ctx = []) {
275
+ if (!preg_match('#^(?:https?:)?//#si', $src)) // not full urls.
276
+ {
277
+ $new_src = $src;
278
+
279
+ // We might need to get last_mod for min files too.
280
+ if (orbisius_child_theme_creator_is_live_env() && (stripos($src, '.min.') === false)) {
281
+ $new_src = str_replace('.css', '.min.css', $new_src);
282
+ $new_src = str_replace('.js', '.min.js', $new_src);
283
+ }
284
+
285
+ $local_file = plugin_dir_path( ORBISIUS_CHILD_THEME_CREATOR_MAIN_PLUGIN_FILE ) . $new_src;
286
+
287
+ // We check if .min file exists and if so use it.
288
+ if (file_exists($local_file)) {
289
+ if (!empty($ctx['last_mod'])) {
290
+ $src = filemtime($local_file);
291
+ } else {
292
+ $full_new_src = plugins_url($new_src, ORBISIUS_CHILD_THEME_CREATOR_MAIN_PLUGIN_FILE);
293
+ $src = $full_new_src;
294
+ }
295
+ }
296
+ }
297
+
298
+ return $src;
299
+ }
300
+
301
  /**
302
  * @package Orbisius Child Theme Creator
303
  * @since 1.0
310
  return ;
311
  }
312
 
313
+ $suffix = orbisius_child_theme_creator_is_live_env() ? '.min' : '';
314
 
315
  wp_register_style('orbisius_child_theme_creator', plugins_url("/assets/main{$suffix}.css", __FILE__), false,
316
  filemtime( plugin_dir_path( __FILE__ ) . "/assets/main{$suffix}.css" ) );
321
  filemtime( plugin_dir_path( __FILE__ ) . "/assets/main{$suffix}.js" ), true);
322
  wp_enqueue_script( 'orbisius_child_theme_creator' );
323
 
324
+ do_action( 'orbisius_child_theme_creator_admin_enqueue_scripts', [ 'suffix' => $suffix, ] );
325
  }
326
 
327
  /**
1391
  * If you must unslash, consider only doing it to your own data which isn't used by others:
1392
  * @see http://codex.wordpress.org/Function_Reference/stripslashes_deep
1393
  */
1394
+ function orbisius_child_theme_creator_get_request($key = null, $default = '') {
1395
  $req = $_REQUEST;
1396
  $req = stripslashes_deep($req);
1397
 
1398
+ if (!empty($key)) {
1399
+ $val = isset($req[$key]) ? $req[$key] : $default;
1400
+ return $val;
1401
+ }
1402
+
1403
  return $req;
1404
  }
1405
 
1406
+ /**
1407
+ * orbisius_child_theme_creator_get();
1408
+ * @param str $key
1409
+ * @param str $default
1410
+ * @return mixed
1411
+ */
1412
+ function orbisius_child_theme_creator_get($key = null, $default = '') {
1413
+ $val = orbisius_child_theme_creator_get_request($key, $default);
1414
+
1415
+ if (is_scalar($val)) {
1416
+ $val = wp_kses($val, []);
1417
+ $val = trim($val);
1418
+ } elseif (is_array($key)) {
1419
+ $val = array_map('orbisius_child_theme_creator_get', $key);
1420
+ }
1421
+
1422
+ return $val;
1423
+ }
1424
+
1425
+
1426
  /**
1427
  * adds some HTML comments in the page so people would know that this plugin powers their site.
1428
  */
2262
 
2263
  <?php
2264
  $buff = $theme_1_file = $theme_2_file = '';
2265
+ $req = orbisius_child_theme_creator_get_request();
2266
 
2267
  $current_theme = wp_get_theme();
2268
 
2320
  </span>
2321
 
2322
  <div id="theme_1_file_contents_container">
2323
+ <textarea id="theme_1_file_contents" name="theme_1_file_contents" rows="16" class="widefat"></textarea>
2324
  </div>
2325
 
2326
  <div class="orbisius_ctc_theme_editor_theme_1_primary_buttons primary_buttons">
2327
  <button type='submit' class='button button-primary' id="theme_1_submit" name="theme_1_submit">Save Changes</button>
2328
  <span class="status"></span>
2329
  </div>
2330
+ </form>
2331
 
 
 
 
 
 
 
 
2332
 
2333
+ <hr />
2334
+ <div class="orbisius_ctc_theme_editor_theme_1_secondary_buttons secondary_buttons">
2335
+ <button type="button" class='button' id="theme_1_new_file_btn" name="theme_1_new_file_btn">New File</button>
2336
+ <button type="button" class='button' id="theme_1_syntax_chk_btn" name="theme_1_syntax_chk_btn">PHP Syntax Check</button>
2337
+ <button type="button" class='button' id="theme_1_send_btn" name="theme_1_send_btn">Send</button>
2338
+ <a href="<?php echo site_url('/');?>" class='button' target="_blank" title="new tab/window"
2339
+ id="theme_1_site_preview_btn" name="theme_1_site_preview_btn">View Site</a>
2340
 
2341
+ <?php do_action('orbisius_child_theme_creator_editors_ext_actions', 'theme_1'); ?>
 
2342
 
2343
+ <!--
2344
+ <button type="button" class='button' id="theme_1_new_folder_btn" name="theme_1_new_folder_btn">New Folder</button>-->
2345
 
2346
+ <a href='javascript:void(0)' class='app-button-right app-button-negative' id="theme_1_delete_file_btn" name="theme_1_delete_file_btn">Delete File</a>
 
 
 
2347
 
2348
+ <div id='theme_1_new_file_container' class="theme_1_new_file_container app-hide">
2349
+ <strong>New File</strong>
2350
+ <input type="text" id="theme_1_new_file" name="theme_1_new_file" value="" />
2351
+ <span>e.g. test.js, extra.css, headers/header-two.php etc</span>
 
2352
 
2353
+ <!--<br/>
2354
+ <label>
2355
+ <input type="checkbox" name="theme_1_new_file_type" value="folder" />
2356
+ Create a folder Instead
2357
+ </label>-->
2358
 
2359
+ <span class="status"></span>
 
 
 
2360
 
2361
+ <br/>
2362
+ <button type='button' class='button button-primary' id="theme_1_new_file_btn_ok" name="theme_1_new_file_btn_ok">Save</button>
2363
+ <a href='javascript:void(0)' class='app-button-negative00 button delete' id="theme_1_new_file_btn_cancel" name="theme_1_new_file_btn_cancel">Cancel</a>
2364
+ </div>
 
 
 
2365
 
2366
+ <!-- send -->
2367
+ <div id='theme_1_send_container' class="theme_1_send_container app-hide">
2368
+ <p>
2369
+ Email selected theme and parent theme (if any) to yourself or a colleague.
2370
+ Separate multiple emails with commas.<br/>
2371
+ <strong>To:</strong>
2372
+ <input type="text" id="theme_1_send_to" name="email" value="" placeholder="Enter email" />
2373
+
2374
+ <button type='button' class='button button-primary' id="theme_1_send_btn_ok" name="theme_1_send_btn_ok">Send</button>
2375
+ <a href='javascript:void(0)' class='app-button-negative00 button delete'
2376
+ id="theme_1_send_btn_cancel" name="theme_1_send_btn_cancel">Cancel</a>
2377
+ </p>
2378
+ </div>
2379
+ <!-- /send -->
2380
 
2381
+ <?php do_action('orbisius_child_theme_creator_editors_ext_action_left_start', array( 'place' => 'left' ) ); ?>
2382
+ <?php do_action('orbisius_child_theme_creator_editors_ext_action_left_end', array( 'place' => 'left' ) ); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2383
 
2384
+ <div style="border:1px solid #ccc;margin:10px 0;padding:3px 5px;">
2385
+ <h3>Pro Addon
2386
+ <?php if ( ! orbisius_child_theme_creator_is_pro_installed() ) : ?>
2387
+ <ul>
2388
+ <li>Syntax Highlighting</li>
2389
+ <li>Better dropdown for selecting themes and files</li>
2390
+ <li>Soon: snippet library stored in the cloud</li>
2391
+ <li></li>
2392
+ </ul>
2393
+ <?php endif; ?>
2394
+ </h3>
2395
+
2396
+ <?php if ( orbisius_child_theme_creator_is_pro_installed() ) : ?>
2397
+ <div class="app-alert-success">
2398
+ The <a href="//orbisius.com/products/wordpress-plugins/orbisius-child-theme-creator-pro/?utm_source=orbisius-child-theme-editor&utm_medium=footer&utm_campaign=product"
2399
+ target="_blank" title="[new window]" style="font-weight: bolder;text-decoration: underline;">Pro Addon</a>
2400
+ is up and running. Thanks for supporting our <a
2401
+ href="//orbisius.com/products/wordpress-plugins/?utm_source=orbisius-child-theme-editor&utm_medium=footer&utm_campaign=product" target="_blank">work</a>!
2402
+ </div>
2403
+ <?php else : ?>
2404
+ <span>Get more cool features by purchasing the </span>
2405
+ <a href="//orbisius.com/products/wordpress-plugins/orbisius-child-theme-creator-pro/?utm_source=orbisius-child-theme-editor&utm_medium=footer&utm_campaign=product"
2406
+ target="_blank" title="[new window]" style="font-weight: bolder;color:red;text-decoration: underline;">Pro Addon</a>
2407
+ <?php endif; ?>
2408
+
2409
+ <!--<ul>
2410
+ <li><a href="//orbisius.com/products/wordpress-plugins/orbisius-theme-switcher/?utm_source=orbisius-child-theme-creator&utm_medium=editors&utm_campaign=product"
2411
+ target="_blank" title="Opens in a new tab/window">Orbisius Theme Switcher</a> - Allows you to preview any of the installed themes on your site.</li>
2412
+ </ul>-->
2413
+ </div>
2414
 
2415
+ <!-- new folder -->
2416
+ <!--
2417
+ <div id='theme_1_new_folder_container' class="theme_1_new_folder_container app-hide">
2418
+ <strong>New Folder</strong>
2419
+ <input type="text" id="theme_1_new_folder" name="theme_1_new_folder" value="" />
2420
+ <span>e.g. includes, data</span>
2421
+ <span class="status"></span>
2422
 
2423
+ <br/>
2424
+ <button type='button' class='button button-primary' id="theme_1_new_folder_btn_ok" name="theme_1_new_folder_btn_ok">Save</button>
2425
+ <a href='javascript:void(0)' class='app-button-negative00 button delete' id="theme_1_new_folder_btn_cancel" name="theme_1_new_folder_btn_cancel">Cancel</a>
2426
+ </div>-->
2427
+ <!-- /new folder -->
2428
+ </div> <!-- /secondary_buttons -->
 
2429
  </td>
2430
  <td width="50%">
2431
  <form id="orbisius_ctc_theme_editor_theme_2_form" class="orbisius_ctc_theme_editor_theme_2_form">
2444
  </span>
2445
 
2446
  <div id="theme_2_file_contents_container">
2447
+ <textarea id="theme_2_file_contents" name="theme_2_file_contents" rows="16" class="widefat"></textarea>
2448
  </div>
2449
 
2450
  <div class="orbisius_ctc_theme_editor_theme_2_primary_buttons primary_buttons">
2514
  function orbisius_ctc_theme_editor_ajax() {
2515
  $buff = 'INVALID AJAX SUB_CMD';
2516
 
2517
+ $req = orbisius_child_theme_creator_get_request();
2518
  $sub_cmd = empty($req['sub_cmd']) ? '' : $req['sub_cmd'];
2519
 
2520
  switch ($sub_cmd) {
2710
  return $status_rec;
2711
  }
2712
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2713
  /**
2714
  * This returns an HTML select with the selected theme's files.
2715
  * the name/id of that select must be either theme_1_file or theme_2_file
2717
  */
2718
  function orbisius_ctc_theme_editor_generate_dropdown() {
2719
  $theme_base_dir = $theme_1_file = '';
2720
+ $req = orbisius_child_theme_creator_get_request();
2721
 
2722
  $select_name = 'theme_1_file';
2723
 
2767
 
2768
  $buff = $theme_base_dir = $theme_dir = $theme_file = '';
2769
 
2770
+ $req = orbisius_child_theme_creator_get_request();
2771
 
2772
  $theme_root = trailingslashit( get_theme_root() );
2773
 
readme.txt CHANGED
@@ -1,378 +1,387 @@
1
- === Child Theme Creator by Orbisius ===
2
- Contributors: lordspace,orbisius
3
- Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=7APYDVPBCSY9A
4
- Tags: theme,child theme,childtheme,childthemes,parent theme,child themes,CSS,styling,resposive design,design,custom themeing, shared hosting,theme editor theme,themes,wp,wordpress,orbisius,theme creator,custom theme,theme generator,css,css editor
5
- Requires at least: 3.4
6
- Tested up to: 4.7
7
- Stable tag: 1.3.9
8
- License: GPLv2 or later
9
-
10
- Create Child Themes quickly and easily from any theme that you have currently installed on your site/blog.
11
-
12
- == Description ==
13
-
14
- This plugin allows you to quickly create child themes from any theme that you have currently installed on your site/blog.
15
- It also creates rtl.css if exists in the parent theme.
16
-
17
- **Did you find this plugin helpful? Please consider [writing a review](https://wordpress.org/support/view/plugin-reviews/orbisius-child-theme-creator).**
18
-
19
- = Child Theme Creator Features =
20
- * Create a theme with a click of a button
21
- * Uses the recommended approach for loading css (since v.1.3.4)
22
- * Never forget what files to copy and what to skip when creating child themes.
23
- * Copies parent theme's options (since v.1.3)
24
- * Easy to use interface
25
- * When moving through the themes the currently looked one will have a nice background & border
26
- * Create *unlimited* child themes from a parent theme. The plugin will add Child 01, Child 02 etc.
27
- * Edit theme files with our two theme editors.
28
- * Automatically creates rtl.css if it exists in the parent theme
29
- * The plugin uses minified css/js to make sure it loads quicker.
30
-
31
- This plugin allows you to quickly edit theme files from Appearance &gt; Orbisius Theme Editor (entry added by the same plugin)
32
- It features two editors and you can pick snippets from one theme and paste into another.
33
-
34
- = Theme Editor Features =
35
-
36
- * Edit two theme files at the same time
37
- * Ajax -> No page refresh
38
- * Easy to use interface
39
- * Supports WordPress Multisite
40
- * Create a New File (+ checks if the file exists)
41
- * Delete file
42
- * Respects the DISALLOW_FILE_EDIT constant, which if set to true will disable the Theme editor
43
- * Since (v1.1.3) PHP syntax check
44
- * Since (v1.1.3) Send selected theme and parent theme (if any) to yourself or a colleague.
45
- * Since (v1.1.3) Implemented theme files to be listed recursively (i.e. all files from the selected theme)
46
- * Since (v1.1.9) Both editors have the same buttons (in older versions only the left editor had all of the buttons).
47
- * Since (v1.2.2) Can create a blank functions.php file (Thanks Tobias Kaupat for the suggestion)
48
- * Since (v1.3.5)* Users can create new files in non-existing folders e.g. headers/header-two.php
49
-
50
- = Important Reasons to Create Child Themes =
51
- * Keep your changes when the parent theme is updated.
52
- * Reduce duplicated code i.e. you need to copy and customize only the files that need to be customized
53
- * Child Themes are often very small in size and can easily be shared and used for another project.
54
- * Lots of cool and professional people do it
55
- * ... and a lot more
56
-
57
- = Pro Addon is Now Available =
58
- We've just released the
59
- <a href="http://club.orbisius.com/products/wordpress-plugins/orbisius-child-theme-creator-pro/?utm_source=orbisius-child-theme-creator&utm_medium=readme&utm_campaign=product"
60
- target="_blank" title="[new window]" style="font-weight: bolder;color:red;">Pro Addon</a> which improves on the current functionality.
61
-
62
- = Important =
63
- > We have noticed that some child themes created by this plugin do not work as expected.
64
- > This is not a bug in this plugin but could be caused by theme authors using custom theme frameworks and/or do not using WordPress' recommended functions for themes that support child themes.
65
- > Please check with the created of the theme first to see if their theme supports child themes.
66
-
67
- We have launched a **FREE** service that allows you to setup a test/sandbox WordPress site in seconds. No technical knowledge is required.
68
- Join today and test themes and plugins before you actually put them on your live site. For more info go to:
69
- <a href="http://qsandbox.com/?utm_source=orbisius-child-theme-creator&utm_medium=readme&utm_campaign=product" target="_blank" title="Free Test/Sandbox WordPress Site">http://qsandbox.com</a>
70
-
71
- = Usage : To create a child theme go to =
72
- Go to Admin > Appearance > Orbisius Child Theme Creator then click on the theme you like and the child theme will be created for you.
73
-
74
- = Usage : To edit themes files go to =
75
- Go to Admin > Appearance > Orbisius Theme Editor then click on the theme you like and the child theme will be created for you.
76
-
77
- = Demo =
78
- http://www.youtube.com/watch?v=BZUVq6ZTv-o
79
-
80
- = Premium =
81
- Do you want to be able to preview themes from within the 2 editors?
82
- Get this <a href="http://club.orbisius.com/products/wordpress-plugins/orbisius-theme-switcher/?utm_source=orbisius-child-theme-creator&utm_medium=readme_description&utm_campaign=product" target="_blank" title="[new window]">Orbisius Theme Switcher</a> plugin
83
-
84
- = Support =
85
- > Support is handled on our site: <a href="http://club.orbisius.com/" target="_blank" title="[new window]">http://club.orbisius.com/</a>
86
- > Please do NOT use the WordPress forums or other places to seek support.
87
-
88
- = Author =
89
-
90
- Do you need an amazing plugin created especially for your needs? Contact me.
91
- Svetoslav Marinov (Slavi) | <a href="http://orbisius.com" title="Custom Web Programming, Web Design, e-commerce, e-store, Wordpress Plugin Development, Facebook and Mobile App Development in Niagara Falls, St. Catharines, Ontario, Canada" target="_blank">Custom Web and Mobile Programming by Orbisius.com</a>
92
-
93
- = Hire Us =
94
- Do you need any WordPress work done? e.g. WordPress tweaks, new plugin development or existing plugin improvements.
95
-
96
- Do you need a trusted <a href="http://orbisius.com/page/free-quote/?utm_source=child-theme-creator&utm_medium=plugin-linksutm_campaign=plugin-update"
97
- title="If you want a custom web/mobile app or a plugin developed contact us. This opens in a new window/tab">WordPress Developer</a> to hire?
98
-
99
- == Upgrade Notice ==
100
- n/a
101
-
102
- == Screenshots ==
103
- 1. Plugin page after installation
104
- 2. Orbisius Child Theme Creator in Appearance > Orbisius Child Theme Creator - before creating a child theme
105
- 3. Orbisius Child Theme Creator in Appearance > Orbisius Child Theme Creator - after creating a child theme
106
- 4. Orbisius Theme Editor in Action from Admin > Appearance > Orbisius Theme Editor
107
-
108
- == Installation ==
109
-
110
- 1. Unzip the package, and upload `orbisius-child-theme-creator` to the `/wp-content/plugins/` directory
111
- 2. Activate the plugin through the 'Plugins' menu in WordPress
112
-
113
- == Frequently Asked Questions ==
114
-
115
- = How to change Child thme screenshot? =
116
- currently, only via ftp.
117
-
118
- = How to use this plugin? =
119
- Just install the plugin and activate it. Then go to Admin > Appearance > Orbisius Child Theme Creator.
120
- Then click on a theme and the plugin will create a child theme for you.
121
-
122
- = After my child theme is created can I remove the plugin safely? =
123
- Yes, you can, however, the plugin comes with a double editor which is pretty awesome.
124
- It allows you to copy and paste from one theme to another without changing screens.
125
-
126
- = How to disable Orbisius Theme Editor Plugin? =
127
- Just put this line right after the first <?php tag in the wp-config.php. This will also remove the WordPress' Theme/Plugin editors as well.
128
-
129
- define('DISALLOW_FILE_EDIT', true);
130
-
131
- = How to edit a logo or colours? =
132
- The theme should have an option to do that.
133
- Please, check the customizer or within the admin area for a menu that matches the theme's name.
134
- Our plugin doesn't know how each theme works so it's better to direct those kind of questions to the theme designer.
135
-
136
- = The child theme is created but doesn't have some styles or doesn't show the admin panel of the parent theme =
137
- OK. Please contact the theme author if his/her theme is child theme friendly.
138
- Also which files does the theme need in order to work well.
139
-
140
- = My Site is Broken =
141
- !@$@!$. Ok. Calm down. When you created the theme did you click on copy functions.php from advanced options?
142
- Ok. You'll need to use FTP client and go to in the wordpress folder and then wp-content/themes/AAAAA-child-01/ and delete functions.php
143
- AAAAA is of course the directory of your parent theme.
144
-
145
- = I want to be able to copy functions.php =
146
- Please use Orbisius Theme Editor (part of this plugin)
147
-
148
- = Troubleshooting =
149
- If your site becomes broken due to a child theme (mis)configuration. Please check another plugin of ours:
150
- <a href="http://club.orbisius.com/products/wordpress-plugins/orbisius-theme-fixer/?utm_source=orbisius-child-theme-creator&utm_medium=readme_troubleshooting&utm_campaign=product" target="_blank" title="[new window]">Orbisius Theme Fixer</a>
151
-
152
- = What to do next? =
153
- Go to http://club.orbisius.com and post suggestions in our forum for new features that you'd like to see in this plugin or its extensions.
154
-
155
- = Need a custom plugin? =
156
- Let's talk.
157
- <a href="http://orbisius.com/page/free-quote/?utm_source=orbisius-child-theme-creator&utm_medium=plugin-readme-faq&utm_campaign=product"
158
- title="If you want a custom web/mobile app/plugin developed contact us. This opens in a new window/tab"
159
- class="button-primary" target="_blank">Get a Free Quote</a>
160
-
161
- Todo
162
- - Add buttons in the WP's Theme listing page near Customize
163
- - Orbisius Create
164
- - Orbisius Edit
165
-
166
- == Changelog ==
167
-
168
- = 1.4.0 =
169
- * Tested with WP 4.7.5
170
-
171
- = 1.3.9 =
172
- * Minor fixes and improvements to the UI
173
- * Tested with WP 4.7.4
174
-
175
- = 1.3.8 =
176
- * Now it's easier to switch to a child theme ... there's an Activate button under each child theme.
177
- * Reduced the default option (= SELECT THEME =) in the dropdown so it doesn't push the buttons down on smaller displays.
178
- * Removed some top links in the creator
179
- * Improved how messages are shown using WP classes and not custom ones.
180
- * Removed some centering in css
181
- * Tested with WP 4.7.3
182
-
183
- = 1.3.7 =
184
- * Tested with WP 4.7.2
185
- * Corrected some links within the plugin. They were pointing to a wrong site because of an additiona .com to the domain name.
186
- * Fixes
187
-
188
- = 1.3.6 =
189
- * Corrected some links from club.orbisius.com -> orbisius.com
190
-
191
- = 1.3.5 =
192
- * Changed twitter non-ssl links to protocol relative URLs.
193
- * Added LOCK_SH for the file read operation
194
- * Added a flag to tell if the content editors are 'dirty' i.e. their content was modified.
195
- * Added a border to the content box if modified.
196
- * Warn the user if there's unsaved content in either of the editors. The browser won't display the actual message I've provided which is stupid.
197
- * TODO: check php syntax before saving for php files - remove button to check syntax?
198
- * Users now can create new files in non-existing folders e.g. headers/header-two.php
199
- * When the admin creates a new file we'll scroll to the element so he/she can start typing
200
- * Tested with WP 4.7
201
-
202
- = 1.3.4 =
203
- * Uses the recommended approach for loading css (since v.1.3.4)
204
- * Fixes, updated FAQ
205
- * Removed a notice about depricated function: https://wordpress.org/support/topic/depricated-functions-3/
206
- * Removed some snippets that contained some 3rd party tracking info e.g. twitter's via or some user id to the addthis widget.
207
-
208
- = 1.3.3 =
209
- * Tested with WP 4.6
210
- * TODO: when saving return JSON and show an error on invalid syntax.
211
-
212
- = 1.3.2 =
213
- * Added locking when saving files.
214
- * Syntax check is performed only for php files. Saving other files should be quicker now.
215
- * Perform a syntax check before saving to avoid crashing good people's WordPress. Changes are saved in a file with the same name but there's suffix added to it _error_
216
- * Listing _error_ files as well as sass, scss (if any)
217
- * Tested with WP 4.5
218
-
219
- = 1.3.1 =
220
- * For some reason WordPress.org didn't register the 1.3.0 release or the stable tag didn't get set to 1.3.0 on time.
221
-
222
- = 1.3.0 =
223
- * Happy new year!
224
- * Copying parent theme's options (if any).
225
- * Tested with WP 4.4.
226
-
227
- = 1.2.9 =
228
- * Added a link in the plugin's settings page to point to Appearance → Orbisius Child Theme Creator ( to save 1-2 seconds to the user :) )
229
- * Removed the Free test from qSandbox as there is no longer a free plan.
230
- * Tested with WP 4.3.1
231
-
232
- = 1.2.8 =
233
- * Improved security even more. Thanks Mika!
234
-
235
- = 1.2.7 =
236
- * Improved security.
237
-
238
- = 1.2.6 =
239
- * Fixed a wrong check for the Pro version.
240
- * Tested with latest WP
241
- * Added a call to action to ask users for write a review.
242
-
243
- = 1.2.5 =
244
- * Fixes
245
- * Improvements
246
- * Made some fixes so the Pro addon shines even more.
247
-
248
- = 1.2.4 =
249
- * Made the plugin more extendable (js).
250
- * Added another Save button near the theme and file dropdowns (for lazy people).
251
- * Added links to the Pro addon.
252
- * Added a nice global wait for all ajax calls.
253
- * Added an error message to be displayed when we're doing ajax and the user is not authenticated.
254
-
255
- = 1.2.3 =
256
- * Tested with WP 4.1
257
-
258
- = 1.2.2 =
259
- * Added: Create a blank functions.php file option (Thanks Tobias Kaupat for the suggestion).
260
- * Added a link to edit theme after the child theme is created.
261
- * Changed the UI. Parent and Child Themes are nicely separated.
262
- * Added a sidebar in the screen where child themes are created
263
- * Fixed some wrong call to action (left from another plugin).
264
-
265
- = 1.2.1 =
266
- * Fixed: A notice in the settings
267
- * Fixed a typo
268
- * Tested with WP 4.0.1
269
-
270
- = 1.2.0 =
271
- * Fixed: BUG - Deleting a file from Theme 1 deletes files from Theme 2. Ref: http://club.orbisius.com/forums/topic/bug-deleting-a-file-from-theme-1-deletes-files-from-theme-2/
272
- * Fixes: CSS so the themes are showing up as 3 per row like they used to be.
273
- * Added a link to a larger version of the theme's screenshot.
274
- * Tested with WP 4
275
-
276
- = 1.1.9 =
277
- * Added the buttons under the 2nd editor
278
- * Hid the plugin from the Tools menu
279
- * Integrated with <a href="http://club.orbisius.com/products/wordpress-plugins/orbisius-theme-switcher/?utm_source=orbisius-child-theme-creator&utm_medium=readme_changelog&utm_campaign=product" target="_blank" title="[new window]">Orbisius Theme Switcher</a>
280
-
281
-
282
- = 1.1.8 =
283
- * Tested with WP 3.8.1
284
-
285
- = 1.1.7 =
286
- * Added Plugin's links to the admin nav bar.
287
- * Added site preview button in the theme editor
288
-
289
- = 1.1.6 =
290
- * Added settings link in the Plugin listing.
291
-
292
- = 1.1.5 =
293
- * Added an option if the email couldn't be sent to offer the download links.
294
- * Unsuccessful zip creation was showing as Sent.
295
-
296
- = 1.1.4 =
297
- * Minor tweaks after v1.1.3
298
-
299
- = 1.1.3 =
300
- * Updated CSS to add some top-margin above the update/save changed buttons
301
- * Added php syntax check
302
- * Added Send button so you can email the selected theme and parent theme (if any) to yourself or a colleague.
303
- * Implemented theme files to be listed recursively (i.e. all files from the selected theme)
304
- * Fixed JS error on Settings page.
305
- * Added uninstall.php file to clean after itself
306
- * Added a check and the notice that shows up on the plugins page won't show up after 24h
307
- * Added Edit Themes link to the Plugin's -> Action links
308
- * Improved and better organized the plugin's settings page
309
-
310
- = 1.1.2 =
311
- * Reduced the height of the editors (to 22 rows) so the save/delete buttons are visible
312
- * Restricted the width of the dropdowns in the theme editor so they don't push the editor and the buttons down.
313
- * Tweaked the position of the New File button and the new form that appears.
314
- * Tested with WP 3.8
315
-
316
- = 1.1.1 =
317
- * Fix: The version 1.1.0 wasn't released properly.
318
-
319
- = 1.1.0 =
320
- * Added a new feature to Customize title, description etc of the new child theme
321
-
322
- = 1.0.9 =
323
- * Fixed: JS errors are cause errors with other plugins
324
- * Loads plugin's JS/CSS files only on child theme creator pages (admin area)
325
-
326
- = 1.0.8 =
327
- * Tested with WP 3.7.1
328
- * Added New File and Delete operations for Theme Editor #1 (left)
329
- * Respects the DISALLOW_FILE_EDIT constant, which if set to true will disable the Theme editor
330
- * Added a quick fix to use file modification time for the css and js assets.
331
-
332
- = 1.0.7 =
333
- * Added: Theme Editor
334
- * - New File, checks for existing file are made on typing.
335
- * - Delete File
336
-
337
- = 1.0.6 =
338
- * Tested with WP 3.7
339
- * Loading current theme in the left editor if there is no theme selected yet.
340
- * Reduced the font size of the links in the top right corner of Child Theme Creator and Theme Editor
341
- * Separated Parent themes from Child ones
342
- * Hid the advanced section. Was confusing and scaring people. If you really want to copy functions pass &orb_show_copy_functions parameter to the Child Plugin page.
343
-
344
- = 1.0.5 =
345
- * Tested under WordPress Multisite environment
346
- * Added menus in WordPress Multisite environment
347
- * Added an option for network wide theme activation (which is mutually exclusive with make theme active).
348
- * Added double editor for easy theme editing.
349
- * Added Orbisius: Edit to the theme list
350
- * Show a notice in the plugins area to let the user know how to work with the plugin. On multisite the message is shown only on the network site.
351
- * Aded minimized versions for main css and js
352
-
353
- = 1.0.4 =
354
- * Tested with wp 3.6.1
355
- * Added a link in the Appearance
356
- * Added header.php to the copied file list
357
- * Added a checkbox in case the user wants to switch to the newly created theme
358
- * Added a checkbox in case the user wants to copy the functions.php from the parent theme
359
- * Removed parent theme's license from the copied list
360
- * Removed the Create Child Theme From themes that are child themes already
361
- * Skipping hidden files (files starting with a dot)
362
- * Copying admin/ from the parent theme if it exists
363
- * Added some security checks if the user actually has permission to install themes
364
- * Fixed some notices
365
-
366
- = 1.0.3 =
367
- * Tested with wp 3.6
368
- * Added settings page in case users want to check it.
369
- * Added a few notices about <a href="http://qsandbox.com/?utm_source=orbisius-child-theme-creator&utm_medium=readme_changelog&utm_campaign=product" target="_blank" title="Free Test/Sandbox WordPress Site">http://qsandbox.com</a>
370
-
371
- = 1.0.2 =
372
- * Tested with wp 3.5.2
373
-
374
- = 1.0.1 =
375
- * Added links to video demo
376
-
377
- = 1.0.0 =
 
 
 
 
 
 
 
 
 
378
  * Initial release
1
+ === Child Theme Creator by Orbisius ===
2
+ Contributors: lordspace,orbisius
3
+ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=7APYDVPBCSY9A
4
+ Tags: theme,child theme,childtheme,childthemes,parent theme,child themes,CSS,styling,resposive design,design,custom themeing, shared hosting,theme editor theme,themes,wp,wordpress,orbisius,theme creator,custom theme,theme generator,css,css editor
5
+ Requires at least: 3.4
6
+ Tested up to: 4.8
7
+ Stable tag: 1.4.1
8
+ License: GPLv2 or later
9
+
10
+ Create Child Themes quickly and easily from any theme that you have currently installed on your site/blog.
11
+
12
+ == Description ==
13
+
14
+ This plugin allows you to quickly create child themes from any theme that you have currently installed on your site/blog.
15
+ It also creates rtl.css if exists in the parent theme.
16
+
17
+ **Did you find this plugin helpful? Please consider [writing a review](https://wordpress.org/support/view/plugin-reviews/orbisius-child-theme-creator).**
18
+
19
+ = Child Theme Creator Features =
20
+ * Since v1.4 store your snippets, license keys in Orbisius cloud library. Access them with a click of a button.
21
+ * Create a theme with a click of a button
22
+ * Uses the recommended approach for loading css (since v.1.3.4)
23
+ * Never forget what files to copy and what to skip when creating child themes.
24
+ * Copies parent theme's options (since v.1.3)
25
+ * Easy to use interface
26
+ * When moving through the themes the currently looked one will have a nice background & border
27
+ * Create *unlimited* child themes from a parent theme. The plugin will add Child 01, Child 02 etc.
28
+ * Edit theme files with our two theme editors.
29
+ * Automatically creates rtl.css if it exists in the parent theme
30
+ * The plugin uses minified css/js to make sure it loads quicker.
31
+
32
+ This plugin allows you to quickly edit theme files from Appearance &gt; Orbisius Theme Editor (entry added by the same plugin)
33
+ It features two editors and you can pick snippets from one theme and paste into another.
34
+
35
+ = Theme Editor Features =
36
+
37
+ * Edit two theme files at the same time
38
+ * Ajax -> No page refresh
39
+ * Easy to use interface
40
+ * Supports WordPress Multisite
41
+ * Create a New File (+ checks if the file exists)
42
+ * Delete file
43
+ * Respects the DISALLOW_FILE_EDIT constant, which if set to true will disable the Theme editor
44
+ * Since (v1.1.3) PHP syntax check
45
+ * Since (v1.1.3) Send selected theme and parent theme (if any) to yourself or a colleague.
46
+ * Since (v1.1.3) Implemented theme files to be listed recursively (i.e. all files from the selected theme)
47
+ * Since (v1.1.9) Both editors have the same buttons (in older versions only the left editor had all of the buttons).
48
+ * Since (v1.2.2) Can create a blank functions.php file (Thanks Tobias Kaupat for the suggestion)
49
+ * Since (v1.3.5)* Users can create new files in non-existing folders e.g. headers/header-two.php
50
+
51
+ = Important Reasons to Create Child Themes =
52
+ * Keep your changes when the parent theme is updated.
53
+ * Reduce duplicated code i.e. you need to copy and customize only the files that need to be customized
54
+ * Child Themes are often very small in size and can easily be shared and used for another project.
55
+ * Lots of cool and professional people do it
56
+ * ... and a lot more
57
+
58
+ = Pro Addon is Now Available =
59
+ We've just released the
60
+ <a href="http://club.orbisius.com/products/wordpress-plugins/orbisius-child-theme-creator-pro/?utm_source=orbisius-child-theme-creator&utm_medium=readme&utm_campaign=product"
61
+ target="_blank" title="[new window]" style="font-weight: bolder;color:red;">Pro Addon</a> which improves on the current functionality.
62
+
63
+ = Important =
64
+ > We have noticed that some child themes created by this plugin do not work as expected.
65
+ > This is not a bug in this plugin but could be caused by theme authors using custom theme frameworks and/or do not using WordPress' recommended functions for themes that support child themes.
66
+ > Please check with the created of the theme first to see if their theme supports child themes.
67
+
68
+ We have launched a **FREE** service that allows you to setup a test/sandbox WordPress site in seconds. No technical knowledge is required.
69
+ Join today and test themes and plugins before you actually put them on your live site. For more info go to:
70
+ <a href="http://qsandbox.com/?utm_source=orbisius-child-theme-creator&utm_medium=readme&utm_campaign=product" target="_blank" title="Free Test/Sandbox WordPress Site">http://qsandbox.com</a>
71
+
72
+ = Usage : To create a child theme go to =
73
+ Go to Admin > Appearance > Orbisius Child Theme Creator then click on the theme you like and the child theme will be created for you.
74
+
75
+ = Usage : To edit themes files go to =
76
+ Go to Admin > Appearance > Orbisius Theme Editor then click on the theme you like and the child theme will be created for you.
77
+
78
+ = Demo =
79
+ http://www.youtube.com/watch?v=BZUVq6ZTv-o
80
+
81
+ = Premium =
82
+ Do you want to be able to preview themes from within the 2 editors?
83
+ Get this <a href="http://club.orbisius.com/products/wordpress-plugins/orbisius-theme-switcher/?utm_source=orbisius-child-theme-creator&utm_medium=readme_description&utm_campaign=product" target="_blank" title="[new window]">Orbisius Theme Switcher</a> plugin
84
+
85
+ = Support =
86
+ > Support is handled on our site: <a href="http://club.orbisius.com/" target="_blank" title="[new window]">http://club.orbisius.com/</a>
87
+ > Please do NOT use the WordPress forums or other places to seek support.
88
+
89
+ = Author =
90
+
91
+ Do you need an amazing plugin created especially for your needs? Contact me.
92
+ Svetoslav Marinov (Slavi) | <a href="http://orbisius.com" title="Custom Web Programming, Web Design, e-commerce, e-store, Wordpress Plugin Development, Facebook and Mobile App Development in Niagara Falls, St. Catharines, Ontario, Canada" target="_blank">Custom Web and Mobile Programming by Orbisius.com</a>
93
+
94
+ = Hire Us =
95
+ Do you need any WordPress work done? e.g. WordPress tweaks, new plugin development or existing plugin improvements.
96
+
97
+ Do you need a trusted <a href="http://orbisius.com/page/free-quote/?utm_source=child-theme-creator&utm_medium=plugin-linksutm_campaign=plugin-update"
98
+ title="If you want a custom web/mobile app or a plugin developed contact us. This opens in a new window/tab">WordPress Developer</a> to hire?
99
+
100
+ == Upgrade Notice ==
101
+ n/a
102
+
103
+ == Screenshots ==
104
+ 1. Plugin page after installation
105
+ 2. Orbisius Child Theme Creator in Appearance > Orbisius Child Theme Creator - before creating a child theme
106
+ 3. Orbisius Child Theme Creator in Appearance > Orbisius Child Theme Creator - after creating a child theme
107
+ 4. Orbisius Theme Editor in Action from Admin > Appearance > Orbisius Theme Editor
108
+
109
+ == Installation ==
110
+
111
+ 1. Unzip the package, and upload `orbisius-child-theme-creator` to the `/wp-content/plugins/` directory
112
+ 2. Activate the plugin through the 'Plugins' menu in WordPress
113
+
114
+ == Frequently Asked Questions ==
115
+
116
+ = How to change Child thme screenshot? =
117
+ currently, only via ftp.
118
+
119
+ = How to use this plugin? =
120
+ Just install the plugin and activate it. Then go to Admin > Appearance > Orbisius Child Theme Creator.
121
+ Then click on a theme and the plugin will create a child theme for you.
122
+
123
+ = After my child theme is created can I remove the plugin safely? =
124
+ Yes, you can, however, the plugin comes with a double editor which is pretty awesome.
125
+ It allows you to copy and paste from one theme to another without changing screens.
126
+
127
+ = How to disable Orbisius Theme Editor Plugin? =
128
+ Just put this line right after the first <?php tag in the wp-config.php. This will also remove the WordPress' Theme/Plugin editors as well.
129
+
130
+ define('DISALLOW_FILE_EDIT', true);
131
+
132
+ = How to edit a logo or colours? =
133
+ The theme should have an option to do that.
134
+ Please, check the customizer or within the admin area for a menu that matches the theme's name.
135
+ Our plugin doesn't know how each theme works so it's better to direct those kind of questions to the theme designer.
136
+
137
+ = The child theme is created but doesn't have some styles or doesn't show the admin panel of the parent theme =
138
+ OK. Please contact the theme author if his/her theme is child theme friendly.
139
+ Also which files does the theme need in order to work well.
140
+
141
+ = My Site is Broken =
142
+ !@$@!$. Ok. Calm down. When you created the theme did you click on copy functions.php from advanced options?
143
+ Ok. You'll need to use FTP client and go to in the wordpress folder and then wp-content/themes/AAAAA-child-01/ and delete functions.php
144
+ AAAAA is of course the directory of your parent theme.
145
+
146
+ = I want to be able to copy functions.php =
147
+ Please use Orbisius Theme Editor (part of this plugin)
148
+
149
+ = Troubleshooting =
150
+ If your site becomes broken due to a child theme (mis)configuration. Please check another plugin of ours:
151
+ <a href="http://club.orbisius.com/products/wordpress-plugins/orbisius-theme-fixer/?utm_source=orbisius-child-theme-creator&utm_medium=readme_troubleshooting&utm_campaign=product" target="_blank" title="[new window]">Orbisius Theme Fixer</a>
152
+
153
+ = What to do next? =
154
+ Go to http://club.orbisius.com and post suggestions in our forum for new features that you'd like to see in this plugin or its extensions.
155
+
156
+ = Need a custom plugin? =
157
+ Let's talk.
158
+ <a href="http://orbisius.com/page/free-quote/?utm_source=orbisius-child-theme-creator&utm_medium=plugin-readme-faq&utm_campaign=product"
159
+ title="If you want a custom web/mobile app/plugin developed contact us. This opens in a new window/tab"
160
+ class="button-primary" target="_blank">Get a Free Quote</a>
161
+
162
+ Todo
163
+ - Add buttons in the WP's Theme listing page near Customize
164
+ - Orbisius Create
165
+ - Orbisius Edit
166
+
167
+ == Changelog ==
168
+
169
+ = 1.4.1 =
170
+ * The previous version got released prematurely. So sorry!
171
+
172
+ = 1.4.0 =
173
+ * Added Orbisius cloud library where people can store snippets, license keys etc.
174
+ * Tested with WP 4.8
175
+ * Got rid of some duplicated functions.
176
+ * Reduced the height of the 2x editors (from 22 rows to 16)
177
+ * Tests, improvements and lots of cool stuff.
178
+ * Drank lots of coffee, danced bachata, kizomba & salsa ;)
179
+
180
+ = 1.3.9 =
181
+ * Minor fixes and improvements to the UI
182
+ * Tested with WP 4.7.4
183
+
184
+ = 1.3.8 =
185
+ * Now it's easier to switch to a child theme ... there's an Activate button under each child theme.
186
+ * Reduced the default option (= SELECT THEME =) in the dropdown so it doesn't push the buttons down on smaller displays.
187
+ * Removed some top links in the creator
188
+ * Improved how messages are shown using WP classes and not custom ones.
189
+ * Removed some centering in css
190
+ * Tested with WP 4.7.3
191
+
192
+ = 1.3.7 =
193
+ * Tested with WP 4.7.2
194
+ * Corrected some links within the plugin. They were pointing to a wrong site because of an additiona .com to the domain name.
195
+ * Fixes
196
+
197
+ = 1.3.6 =
198
+ * Corrected some links from club.orbisius.com -> orbisius.com
199
+
200
+ = 1.3.5 =
201
+ * Changed twitter non-ssl links to protocol relative URLs.
202
+ * Added LOCK_SH for the file read operation
203
+ * Added a flag to tell if the content editors are 'dirty' i.e. their content was modified.
204
+ * Added a border to the content box if modified.
205
+ * Warn the user if there's unsaved content in either of the editors. The browser won't display the actual message I've provided which is stupid.
206
+ * TODO: check php syntax before saving for php files - remove button to check syntax?
207
+ * Users now can create new files in non-existing folders e.g. headers/header-two.php
208
+ * When the admin creates a new file we'll scroll to the element so he/she can start typing
209
+ * Tested with WP 4.7
210
+
211
+ = 1.3.4 =
212
+ * Uses the recommended approach for loading css (since v.1.3.4)
213
+ * Fixes, updated FAQ
214
+ * Removed a notice about depricated function: https://wordpress.org/support/topic/depricated-functions-3/
215
+ * Removed some snippets that contained some 3rd party tracking info e.g. twitter's via or some user id to the addthis widget.
216
+
217
+ = 1.3.3 =
218
+ * Tested with WP 4.6
219
+ * TODO: when saving return JSON and show an error on invalid syntax.
220
+
221
+ = 1.3.2 =
222
+ * Added locking when saving files.
223
+ * Syntax check is performed only for php files. Saving other files should be quicker now.
224
+ * Perform a syntax check before saving to avoid crashing good people's WordPress. Changes are saved in a file with the same name but there's suffix added to it _error_
225
+ * Listing _error_ files as well as sass, scss (if any)
226
+ * Tested with WP 4.5
227
+
228
+ = 1.3.1 =
229
+ * For some reason WordPress.org didn't register the 1.3.0 release or the stable tag didn't get set to 1.3.0 on time.
230
+
231
+ = 1.3.0 =
232
+ * Happy new year!
233
+ * Copying parent theme's options (if any).
234
+ * Tested with WP 4.4.
235
+
236
+ = 1.2.9 =
237
+ * Added a link in the plugin's settings page to point to Appearance → Orbisius Child Theme Creator ( to save 1-2 seconds to the user :) )
238
+ * Removed the Free test from qSandbox as there is no longer a free plan.
239
+ * Tested with WP 4.3.1
240
+
241
+ = 1.2.8 =
242
+ * Improved security even more. Thanks Mika!
243
+
244
+ = 1.2.7 =
245
+ * Improved security.
246
+
247
+ = 1.2.6 =
248
+ * Fixed a wrong check for the Pro version.
249
+ * Tested with latest WP
250
+ * Added a call to action to ask users for write a review.
251
+
252
+ = 1.2.5 =
253
+ * Fixes
254
+ * Improvements
255
+ * Made some fixes so the Pro addon shines even more.
256
+
257
+ = 1.2.4 =
258
+ * Made the plugin more extendable (js).
259
+ * Added another Save button near the theme and file dropdowns (for lazy people).
260
+ * Added links to the Pro addon.
261
+ * Added a nice global wait for all ajax calls.
262
+ * Added an error message to be displayed when we're doing ajax and the user is not authenticated.
263
+
264
+ = 1.2.3 =
265
+ * Tested with WP 4.1
266
+
267
+ = 1.2.2 =
268
+ * Added: Create a blank functions.php file option (Thanks Tobias Kaupat for the suggestion).
269
+ * Added a link to edit theme after the child theme is created.
270
+ * Changed the UI. Parent and Child Themes are nicely separated.
271
+ * Added a sidebar in the screen where child themes are created
272
+ * Fixed some wrong call to action (left from another plugin).
273
+
274
+ = 1.2.1 =
275
+ * Fixed: A notice in the settings
276
+ * Fixed a typo
277
+ * Tested with WP 4.0.1
278
+
279
+ = 1.2.0 =
280
+ * Fixed: BUG - Deleting a file from Theme 1 deletes files from Theme 2. Ref: http://club.orbisius.com/forums/topic/bug-deleting-a-file-from-theme-1-deletes-files-from-theme-2/
281
+ * Fixes: CSS so the themes are showing up as 3 per row like they used to be.
282
+ * Added a link to a larger version of the theme's screenshot.
283
+ * Tested with WP 4
284
+
285
+ = 1.1.9 =
286
+ * Added the buttons under the 2nd editor
287
+ * Hid the plugin from the Tools menu
288
+ * Integrated with <a href="http://club.orbisius.com/products/wordpress-plugins/orbisius-theme-switcher/?utm_source=orbisius-child-theme-creator&utm_medium=readme_changelog&utm_campaign=product" target="_blank" title="[new window]">Orbisius Theme Switcher</a>
289
+
290
+
291
+ = 1.1.8 =
292
+ * Tested with WP 3.8.1
293
+
294
+ = 1.1.7 =
295
+ * Added Plugin's links to the admin nav bar.
296
+ * Added site preview button in the theme editor
297
+
298
+ = 1.1.6 =
299
+ * Added settings link in the Plugin listing.
300
+
301
+ = 1.1.5 =
302
+ * Added an option if the email couldn't be sent to offer the download links.
303
+ * Unsuccessful zip creation was showing as Sent.
304
+
305
+ = 1.1.4 =
306
+ * Minor tweaks after v1.1.3
307
+
308
+ = 1.1.3 =
309
+ * Updated CSS to add some top-margin above the update/save changed buttons
310
+ * Added php syntax check
311
+ * Added Send button so you can email the selected theme and parent theme (if any) to yourself or a colleague.
312
+ * Implemented theme files to be listed recursively (i.e. all files from the selected theme)
313
+ * Fixed JS error on Settings page.
314
+ * Added uninstall.php file to clean after itself
315
+ * Added a check and the notice that shows up on the plugins page won't show up after 24h
316
+ * Added Edit Themes link to the Plugin's -> Action links
317
+ * Improved and better organized the plugin's settings page
318
+
319
+ = 1.1.2 =
320
+ * Reduced the height of the editors (to 22 rows) so the save/delete buttons are visible
321
+ * Restricted the width of the dropdowns in the theme editor so they don't push the editor and the buttons down.
322
+ * Tweaked the position of the New File button and the new form that appears.
323
+ * Tested with WP 3.8
324
+
325
+ = 1.1.1 =
326
+ * Fix: The version 1.1.0 wasn't released properly.
327
+
328
+ = 1.1.0 =
329
+ * Added a new feature to Customize title, description etc of the new child theme
330
+
331
+ = 1.0.9 =
332
+ * Fixed: JS errors are cause errors with other plugins
333
+ * Loads plugin's JS/CSS files only on child theme creator pages (admin area)
334
+
335
+ = 1.0.8 =
336
+ * Tested with WP 3.7.1
337
+ * Added New File and Delete operations for Theme Editor #1 (left)
338
+ * Respects the DISALLOW_FILE_EDIT constant, which if set to true will disable the Theme editor
339
+ * Added a quick fix to use file modification time for the css and js assets.
340
+
341
+ = 1.0.7 =
342
+ * Added: Theme Editor
343
+ * - New File, checks for existing file are made on typing.
344
+ * - Delete File
345
+
346
+ = 1.0.6 =
347
+ * Tested with WP 3.7
348
+ * Loading current theme in the left editor if there is no theme selected yet.
349
+ * Reduced the font size of the links in the top right corner of Child Theme Creator and Theme Editor
350
+ * Separated Parent themes from Child ones
351
+ * Hid the advanced section. Was confusing and scaring people. If you really want to copy functions pass &orb_show_copy_functions parameter to the Child Plugin page.
352
+
353
+ = 1.0.5 =
354
+ * Tested under WordPress Multisite environment
355
+ * Added menus in WordPress Multisite environment
356
+ * Added an option for network wide theme activation (which is mutually exclusive with make theme active).
357
+ * Added double editor for easy theme editing.
358
+ * Added Orbisius: Edit to the theme list
359
+ * Show a notice in the plugins area to let the user know how to work with the plugin. On multisite the message is shown only on the network site.
360
+ * Aded minimized versions for main css and js
361
+
362
+ = 1.0.4 =
363
+ * Tested with wp 3.6.1
364
+ * Added a link in the Appearance
365
+ * Added header.php to the copied file list
366
+ * Added a checkbox in case the user wants to switch to the newly created theme
367
+ * Added a checkbox in case the user wants to copy the functions.php from the parent theme
368
+ * Removed parent theme's license from the copied list
369
+ * Removed the Create Child Theme From themes that are child themes already
370
+ * Skipping hidden files (files starting with a dot)
371
+ * Copying admin/ from the parent theme if it exists
372
+ * Added some security checks if the user actually has permission to install themes
373
+ * Fixed some notices
374
+
375
+ = 1.0.3 =
376
+ * Tested with wp 3.6
377
+ * Added settings page in case users want to check it.
378
+ * Added a few notices about <a href="http://qsandbox.com/?utm_source=orbisius-child-theme-creator&utm_medium=readme_changelog&utm_campaign=product" target="_blank" title="Free Test/Sandbox WordPress Site">http://qsandbox.com</a>
379
+
380
+ = 1.0.2 =
381
+ * Tested with wp 3.5.2
382
+
383
+ = 1.0.1 =
384
+ * Added links to video demo
385
+
386
+ = 1.0.0 =
387
  * Initial release