function bunyad_shortcode_editor_plugin()
{
    global $tinymce_version;
    // check auth
    if (!is_user_logged_in() or !current_user_can('edit_posts')) {
        die('You do not have the right type of authorization. You must be logged in and be able to edit pages and posts.');
    }
    // javascript will be output
    header('Content-type: application/x-javascript');
    /*
     * Create shortcode generator menu javascript calls
     */
    $shortcodes = Bunyad_ShortCodes::getInstance()->get_all();
    $shortcode_menu = '';
    foreach ($shortcodes as $key => $value) {
        $output = '';
        $data = array();
        foreach ($value as $id => $shortcode) {
            // defaults
            $shortcode = array_merge(array('label' => null, 'dialog' => false, 'code' => null), $shortcode);
            if (!$shortcode['label']) {
                continue;
            }
            $dialog = $shortcode['dialog'] ? true : false;
            $options = array('title' => $shortcode['label'], 'id' => $id, 'dialog' => $dialog);
            // no dialog? has a predefined code to insert by default?
            if (!$dialog && $shortcode['code']) {
                $options['insert_code'] = $shortcode['code'];
            }
            // add top-level to output; collect sub-menu items
            if ($key == 'default') {
                $output .= "add_dialog(list, " . json_encode($options) . ");\n";
            } else {
                $data[] = $options;
            }
        }
        // top-level
        if ($key == 'default') {
            $shortcode_menu .= $output;
        } else {
            // sub-menu
            $shortcode_menu .= 'add_dialog(list, {title: "' . esc_attr($key) . '"}, ' . json_encode($data) . ");\n";
        }
    }
    ?>

(function() {
	//******* Load plugin specific language pack
	//tinymce.PluginManager.requireLangPack('example')
	
	<?php 
    if ($tinymce_version[0] >= 4) {
        /*
         * Used for WordPress 3.9 and TinyMCE >= 4
         */
        ?>

		tinymce.PluginManager.add('bunyad_shortcodes', function(editor, url) {
	
				var list = [];
				
				var add_dialog = function(list, item, sub) {
				
					if (sub && sub.length > 0) {
											
						var sub_list = [];
						
						for (i in sub) {
							add_dialog(sub_list, sub[i]);
						}
						
						list[list.length] = {text: item.title, menu: sub_list};
						
						return;
					}
					
					list[list.length] = {text: item.title, onclick: function() { // onclick
						
						// TODO: add cache
						if (item.dialog === true) {
							//tb_show('<?php 
        _e('Shortcode: ', 'bunyad-shortcodes');
        ?>
' + item.title, '<?php 
        echo plugin_dir_url(__FILE__) . 'shortcode-popup.php?shortcode=';
        ?>
' + item.id);
							tb_show('<?php 
        _e('Shortcode: ', 'bunyad-shortcodes');
        ?>
' + item.title, '<?php 
        echo admin_url('admin-ajax.php') . '?action=bunyad_shortcode_popup&shortcode=';
        ?>
' + item.id);
							
							jQuery('#TB_ajaxContent').css({width: 'auto', height: '90%'});
							
							var counter = 0,
								set_height = function() { 
							
								var height = jQuery('#TB_window').height();
								counter++;
								
								if (counter > 20) {
									return;
								}
								
								if (height < 100) {
									window.setTimeout(set_height, 500);
								}
								
								jQuery('#TB_ajaxContent').css('height', jQuery('#TB_window').height() - 45 + 'px');
							};
							
							set_height();
							
						}
						else { // just insert
						
							var shortcode, selected, 
								ed = tinyMCE.activeEditor;
							
							selected = ed.selection.getContent();
							
							if (!item.insert_code) {
								shortcode = '[' + item.id + ']%selected%[/' + item.id + ']'; 
							}
	
							if (jQuery.trim(selected) === '') {
								selected = '<?php 
        esc_attr_e('INSERT HERE', 'bunyad-shortcodes');
        ?>
'; 
							}
	
							shortcode = shortcode.replace('%selected%', selected);
							ed.execCommand('mceReplaceContent', false, shortcode);
						}						
					}};
				};
				
				<?php 
        echo $shortcode_menu;
        ?>
	
				editor.addButton('bunyad_shortcodes', {
					type: 'menubutton',
					text: '<?php 
        esc_attr_e('Shortcodes', 'bunyad-shortcodes');
        ?>
', 
					icon: false,
					menu: list
				});
		});
	
	<?php 
    } else {
        /*
         * Older than WordPress 3.8 Below - TinyMCE 3.x compat
         */
        ?>

	tinymce.create('tinymce.plugins.bunyad_shortcodes', {
		/**
		 * Initializes the plugin, this will be executed after the plugin has been created.
		 * This call is done before the editor instance has finished it's initialization so use the onInit event
		 * of the editor instance to intercept that event.
		 *
		 * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
		 * @param {string} url Absolute URL to where the plugin is located.
		 */
		init : function(ed, url) {
		
			// fix some styling issues and add correct wording
			ed.onPostRender.add(function(ed, cm) {
				var ele = jQuery('.mceAction .mce_bunyad_shortcodesList');
				ele.html('<?php 
        _e('Shortcodes', 'bunyad-shortcodes');
        ?>
');
				
				ele.removeClass('mceAction').css({width: 'auto'});
				ele.parent().css({width: 'auto', 'line-height': '1.7em', 'padding': '1px 5px'});
			});			
		},

		/**
		 * Creates control instances based in the incomming name. This method is normally not
		 * needed since the addButton method of the tinymce.Editor class is a more easy way of adding buttons
		 * but you sometimes need to create more complex controls like listboxes, split buttons etc then this
		 * method can be used to create those.
		 *
		 * @param {String} n Name of the control to create.
		 * @param {tinymce.ControlManager} cm Control manager to use inorder to create new control.
		 * @return {tinymce.ui.Control} New control instance or null if no control was created.
		 */
		createControl : function(n, cm) {
			
			var add_dialog = function(list, item, sub) {
			
				if (sub && sub.length > 0) {
					var sub_list = list.addMenu({title: item.title});
					
					for (i in sub) {
						add_dialog(sub_list, sub[i]);
					}
					
					return;
				}
				
				list.add({title: item.title, onclick: function() { // onclick
					
					// TODO: add cache
					if (item.dialog === true) {
						tb_show('<?php 
        _e('Shortcode: ', 'bunyad-shortcodes');
        ?>
' + item.title, '<?php 
        echo admin_url('admin-ajax.php') . '?action=bunyad_shortcode_popup&shortcode=';
        ?>
' + item.id);
						
						jQuery('#TB_ajaxContent').css({width: 'auto', height: '90%'});
						
						var counter = 0,
							set_height = function() { 
						
							var height = jQuery('#TB_window').height();
							counter++;
							
							if (counter > 20) {
								return;
							}
							
							if (height < 100) {
								window.setTimeout(set_height, 500);
							}
							
							jQuery('#TB_ajaxContent').css('height', jQuery('#TB_window').height() - 45 + 'px');
						};
						
						set_height();
						
						
					}
					else { // just insert
					
						var shortcode, selected, 
							ed = tinyMCE.activeEditor;
						
						selected = ed.selection.getContent();
						
						if (!item.insert_code) {
							shortcode = '[' + item.id + ']%selected%[/' + item.id + ']'; 
						}

						if (jQuery.trim(selected) === '') {
							selected = '<?php 
        _e('INSERT HERE', 'bunyad-shortcodes');
        ?>
'; 
						}

						shortcode = shortcode.replace('%selected%', selected);
						ed.execCommand('mceReplaceContent', false, shortcode);
					}
					
					// open window
					/*tinyMCE.activeEditor.windowManager.open({
						url: '<?php 
        echo plugin_dir_url(__FILE__) . 'shortcode-popup.php?shortcode=';
        ?>
' + item.id,
						inline: 1,
						width: 500,
						height: parseInt(jQuery(window).height()) * 0.8,
					});*/		
					
				}}); 
				
				return list;
			};
		
			if (n == 'bunyad_shortcodes') {
			
				var button = cm.createSplitButton('bunyad_shortcodesList', {
					title: '<?php 
        echo esc_attr__('Shortcodes', 'bunyad-shortcodes');
        ?>
',
					icons: false
				});
				
				button.onRenderMenu.add(function(c, list) {
				
				<?php 
        echo $shortcode_menu;
        ?>
					
				});
	
                // Return the new listbox instance
                return button;
             }
             
             return null;
		},

		/**
		 * Returns information about the plugin as a name/value array.
		 * The current keys are longname, author, authorurl, infourl and version.
		 *
		 * @return {Object} Name/value array containing information about the plugin.
		 */
		getInfo : function() {
			return {
				longname : 'Shortcode selector',
				author : 'asad',
				authorurl : 'http://twitter.com/asadkn',
				infourl : '',
				version : "1.0"
			};
		}
	});

	// Register plugin
	tinymce.PluginManager.add('bunyad_shortcodes', tinymce.plugins.bunyad_shortcodes);
	
	<?php 
    }
    // end version check
    ?>
	
})();

<?php 
    die;
    // end ajax request
}
<?php

/*
Plugin Name: Bunyad Shortcodes
Plugin URI: http://theme-sphere.com
Description: Bunyad Shortcodes adds multiple shortcode functionality for ThemeSphere themes. 
Version: 1.0.7
Author: ThemeSphere
Author URI: http://theme-sphere.com
License: GPL2
*/
$bunyad_sc = Bunyad_ShortCodes::getInstance();
add_action('after_setup_theme', array($bunyad_sc, 'setup'));
/**
 * Shortcode handlers
 */
class Bunyad_ShortCodes
{
    protected static $instance;
    protected $_conf = array();
    protected $_open = array();
    public $counter = 0;
    // number of shortcodes processed - not implemented
    public $temp = array();
    public $shortcodes = array();
    public $blocks = array();
    // shortcodes to be handled with a file
    public function setup()
    {
        // bunyad framework available? optional but good extras
        if (class_exists('Bunyad')) {
function bunyad_shortcode_popup()
{
    if (!is_user_logged_in() or !current_user_can('edit_pages') or !current_user_can('edit_posts')) {
        die('You do not have the right type of authorization. You must be logged in and be able to edit pages and posts.');
    }
    $shortcode = array_merge(array('label' => null, 'child' => null), Bunyad_ShortCodes::getInstance()->get_one($_GET['shortcode']));
    $dialog_file = dirname(__FILE__) . '/shortcode-dialogs/' . $shortcode['dialog'] . '.php';
    if ($shortcode['dialog'] && file_exists($dialog_file)) {
        $shortcode_file = $dialog_file;
    }
    ?>
<!DOCTYPE html>
<html>
<head>
	
</head>

<body>

<style type="text/css">

.bunyad-sc-visual { margin-top: 10px; }
.bunyad-sc-visual .element-control { 
	position: relative;
	margin-bottom: 5px;
}

.bunyad-sc-visual .element-control:after {
	content: " "; 
	display: block; 
	clear: both;
}

.bunyad-sc-visual label {
	width: 150px;
	float: left;
	display: block;
	font-weight: bold;
	padding-right: 10px;
	line-height: 2em;
}

.bunyad-sc-visual .element-control input {
	float: left;
	display: block;
	width: 100%;
	max-width: 200px;
}

.bunyad-sc-visual textarea { 
	width: 400px;
	height: 150px;
}

.bunyad-sc-visual .buttons {
	padding-top: 20px;
}

.bunyad-sc-visual .help {
	line-height: 2.5em;
	padding-left: 10px;
	color: gray;
	font-size: 80%;
}

.element-control .color-picker-element {
	left: 375px; 
	top: 0;
}

.divider-or {
	position: relative;
	width: 100%;
	text-align: center;
	margin: 10px 0;
}

.divider-or span {
	background: #fff;
	padding: 0 5px;
}

.divider-or:before {
	display: block;
	position: absolute;
	top: 50%;
	content: " ";
	border-top: 1px solid #ccc;
	width: 100%;
	z-index: -1;
}

</style>

<script type="text/javascript">

	function Bunyad_Shortcodes_Helper($) {

		var self = this;
		this.form;
		this.shortcode;
		this.child_shortcode;
		
		this.init = function() {

			this.form = $('form.bunyad-sc-visual');
			
			// register simple shortcode handler by default
			this.form.submit(this.simple_shortcodes);
			$('#add-more-groups').click(this.insert_group);
		};

		/*
		 * Handler for simple shortcodes. Generator form will just have key => field pairs to use 
		 * as attributes in the shortcode.
		 *
		 * Creates shortcodes of form: [shortcode field1="value1" field2="value2"]content[/shortcode]
		 */
		this.simple_shortcodes = function(e) 
		{
			if (e.isPropagationStopped()) {
				return;
			}

			var params  = self.form_to_attribs($(this)),
				attribs = params[0].join(' '),
				enclose = params[1];
		

			var shortcode   = "<?php 
    echo esc_attr($_GET['shortcode']);
    ?>
";
			var insert_code = '[' + shortcode + (attribs ? ' ' + attribs : '') + ']' + enclose + '[/' + shortcode + ']';

			self.insert_close(insert_code);
			
			return false;
		};

		this.form_to_attribs = function(form, enclose) 
		{
			var params = form.serializeArray();
			var attribs = [], enclose = '';
	
			$.each(params, function(k, v) {
	
				// ignore the hidden field and empty values
				if (v.name === 'shortcode' || v.name.indexOf('[') !== -1 || $.trim(v.value) === '') {
					return;
				}
									
				if (v.name === 'enclose') {
					enclose = v.value.replace(/\r?\n/gi, '<br />'); // possibly multi-line 
				}
				else {
					attribs.push(v.name + '="' + v.value + '"');
				}
			});

			return [attribs, enclose];
		};
		
		this.advanced_shortcodes = function(e) {

			if (e.isPropagationStopped()) {
				return;
			}
			
			var group = [], parent = self.shortcode, shortcode = self.child_shortcode || parent;
			$(this).find('[name^="content["], [name^="sc-group["]').each(function() {

				var group_id = ($(this).attr('name')).replace(/.*\[([0-9]+)\]/, '$1'),
					attribs  = [],
					the_content,
					found_content = false;
				
				$(this).parent().parent().find('[name$="[' + group_id + ']"]').each(function() {
				
					var name = ($(this).attr('name')).replace(/(.*)\[([0-9]+)\]/, '$1');

					if (name == 'content') {
						found_content = true; 
						the_content = $(this).val();
						return;
					}
					else if (name == 'sc-group') {
						return;
					}

					if ($(this).val()) {
						attribs.push(name + '="' + $(this).val() + '"');
					}
				});
				
				// have title and content?
				if (!found_content || the_content) {
					group.push({attribs: attribs.join(' '), content: the_content || ''});
				}
			});

			var insert_code = '';

			// create one shortcode for each group
			$.each(group, function(k, v) 
			{
				var content = v.content.replace(/\r?\n/gi, '<br />'); // multi-line 
				insert_code += '[' + shortcode + (v.attribs ? ' ' + v.attribs : '') + ']' + (content ? content + '[/' + shortcode + "]" : '') + '<br />';  
			});

			// add wrapping parent tag if both shortcode (child) and parent available
			if (self.child_shortcode && parent) {

				var attribs = self.form_to_attribs($(this));
				attribs = attribs[0].join(' ');
				
				
				insert_code = '[' + parent + (attribs ? ' ' + attribs : '') + "]<br />" + insert_code + '[/' + parent + ']';
			}

			self.insert_close(insert_code);

			e.stopPropagation();
			return false;
		};

		this.insert_close = function(code) {
			// insert shortcode and remove popup
			tinyMCE.activeEditor.execCommand("mceInsertContent", false, code);
			tb_remove();
		};

		this.set_handler = function(handler) 
		{
			
			if (handler == 'advanced') {
				this.form.unbind('submit').submit(this.advanced_shortcodes);
			}
			else if ($.isFunction(handler)) {
				this.form.unbind('submit').submit(handler);
			}
		};

		this.insert_group = function(e) {

			// current tabs count
			var tabs_count = $(this).parent().data('bunyad_tabs') || 0;
			if (tabs_count === 0) {
				tabs_count = $(this).parent().parent().find('.title').length;
			}

			if (tabs_count >= 6) { 
				alert('Woah, slow down. Do you really wish to be adding that many tabs?');
			}
			
			tabs_count++;

			// get our template and modify it
			var html = $(this).parent().parent().find('.template-group-options').html();

			html = $(html);
			html.find('span').each(function() {
				var span_html = $(this).html();
				$(this).html(span_html.replace('%number%', tabs_count));
			});

			html.find('[name*="[%number%]"]').each(function() {
				var attr = $(this).attr('name');
				$(this).attr('name', attr.replace('%number%', tabs_count));
			});
			
			$(this).parent().before(html);

			// update counter
			$(this).parent().data('bunyad_tabs', tabs_count);

			if (Bunyad_Options && $.farbtastic) {
				$('.colorpicker').wpColorPicker();
				Bunyad_Options.init_color_pickers();
			}

			return false;	
		};

		$(function() {
			self.init();
		});
	}

	var Bunyad_Shortcodes_Helper = new Bunyad_Shortcodes_Helper(jQuery);

	// set shortcodes
	Bunyad_Shortcodes_Helper.shortcode = '<?php 
    echo esc_attr(strip_tags($_GET['shortcode']));
    ?>
';
	Bunyad_Shortcodes_Helper.child_shortcode = '<?php 
    echo esc_attr($shortcode['child']);
    ?>
';

</script>

<form method="post" class="bunyad-sc-visual">
	<input type="hidden" name="shortcode" value="<?php 
    echo esc_attr($_GET['shortcode']);
    ?>
" />
	<?php 
    if ($shortcode_file) {
        include_once $shortcode_file;
    }
    ?>

	<div class="buttons">
		<input type="submit" value="<?php 
    _e('Insert ' . $shortcode['label'], 'bunyad-shortcodes');
    ?>
" class="button-primary" />
	</div>
	
</form>

<link rel="stylesheet" type="text/css" href="<?php 
    echo admin_url() . '/css/farbtastic.css';
    ?>
" />
<script src="<?php 
    echo admin_url() . '/js/farbtastic.js';
    ?>
"></script>
<script src="<?php 
    echo get_template_directory_uri() . '/admin/js/options.js';
    ?>
"></script>
</body>
</html><?php 
    die;
}
<?php

$render = Bunyad::factory('admin/option-renderer');
$button_colors = (array) Bunyad_ShortCodes::getInstance()->get_config('button_colors');
if (count($button_colors)) {
    $button_colors = array_combine($button_colors, array_map('ucfirst', $button_colors));
} else {
    $button_colors = array();
}
// all the attributes
$options = apply_filters('bunyad_shortcodes_button_options', array('link' => array('label' => __('Link To', 'bunyad-shortcodes'), 'type' => 'text', 'name' => 'link', 'html_post_output' => '<span class="help">' . __('Example: http://google.com.', 'bunyad-shortcodes') . '</span>'), 'text' => array('label' => __('Button Text', 'bunyad-shortcodes'), 'type' => 'text', 'name' => 'enclose'), 'size' => array('label' => __('Button Size', 'bunyad-shortcodes'), 'type' => 'select', 'name' => 'size', 'options' => array('' => __('Small', 'bunyad-shortcodes'), 'medium' => __('Medium', 'bunyad-shortcodes'), 'large' => __('Large', 'bunyad-shortcodes'))), 'preset' => array('label' => __('Preset Styles', 'bunyad-shortcodes'), 'type' => 'select', 'name' => 'preset', 'options' => $button_colors, 'html_post_output' => '<span class="help">' . __('Either choose a pre-defined style or customize below.', 'bunyad-shortcodes') . '</span>'), 'target' => array('label' => __('Open In', 'bunyad-shortcodes'), 'type' => 'select', 'name' => 'target', 'options' => array('' => __('Same Tab', 'bunyad-shortcodes'), 'new' => __('New Tab', 'bunyad-shortcodes'))), 'sep' => array('type' => 'html', 'html' => '<div class="divider-or"><span>' . __('Or Customize (Optional)', 'bunyad-shortcodes') . '</span></div>'), 'text_color' => array('label' => __('Text Color', 'bunyad-shortcodes'), 'type' => 'color', 'name' => 'text_color'), 'bg_color' => array('label' => __('Background Color', 'bunyad-shortcodes'), 'type' => 'color', 'name' => 'color', '')));
if (empty($button_colors)) {
    unset($options['preset']);
}
foreach ($options as $option) {
    echo $render->render($option);
}
?>

<script>
jQuery(function($) {

	// replace customized color - this will be hooked before main handler
	var button_handler = function() {

		var bg_color = $(this).find('input[name=color]'),
			preset = $(this).find('select[name=preset]');
		
		if (bg_color.val() == '') {
			bg_color.val(preset.val());
		}