├── LICENSE.md ├── README.md ├── _screenshots ├── screenshot-1.png └── screenshot-2.png ├── plugin-example.php ├── sunrise.css ├── sunrise.js └── sunrise.php /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Vladimir Anokhin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Sunrise for WordPress 2 | --------------------- 3 | 4 | ### New Maintainer 5 | 6 | As of March 1, 2015, [Tyler Longren](https://longrendev.io/) has taken over maintenance of this plugin. If you have any feature requests or know of something broken, please [create an issue](https://github.com/gndev/sunrise/issues). I am **especially interested in removing any deprecated WordPress functions** and replacing them with their proper alternatives. 7 | 8 | #### Options Pages Framework for WordPress Plugins and Themes 9 | 10 | Sunrise is an open-source and OOP-based plugin framework. It can help you to make unlimited number of fast and powerful options pages with native look in your WordPress plugins or themes. It was designed to speed up plugin deployment and development, together with sufficient 11 | functionality. 12 | 13 | ##### Quick start 14 | 15 | Open file _plugin-example.php_ and modify the code as you want. Detailed documentation will be added in closest future. Use native WordPress functions to get and update created options - get_option( $id ), update_option( $id, 'new value' ) 16 | 17 | ##### Useful links 18 | 19 | * [Documentation](https://gndev.info/kb/) - read the code for more info 20 | * [My Twitter](http://twitter.com/gndevinfo) and [homepage](http://anovladimir.me/) 21 | * [Page at wordpress.org](http://wordpress.org/plugins/sunrise/) 22 | 23 | #### Screenshots 24 | 25 | *Regular fields* 26 | ![Regular fields](/_screenshots/screenshot-1.png?raw=true) 27 | 28 | *Extra fields* 29 | ![Extra fields](/_screenshots/screenshot-2.png?raw=true) 30 | -------------------------------------------------------------------------------- /_screenshots/screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanokhin/sunrise/e4f3cf86fa829cfdfe3beb315864f145d5512b48/_screenshots/screenshot-1.png -------------------------------------------------------------------------------- /_screenshots/screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanokhin/sunrise/e4f3cf86fa829cfdfe3beb315864f145d5512b48/_screenshots/screenshot-2.png -------------------------------------------------------------------------------- /plugin-example.php: -------------------------------------------------------------------------------- 1 | __FILE__, 28 | // Plugin slug (should be equal to plugin directory name) 29 | 'slug' => 'plugin-example', 30 | // Plugin prefix 31 | 'prefix' => 'plugin_example_', 32 | // Plugin textdomain 33 | 'textdomain' => 'plugin-example', 34 | // Custom CSS assets folder 35 | 'css' => '', 36 | // Custom JS assets folder 37 | 'js' => '', 38 | ) ); 39 | 40 | // Prepare array with options 41 | $options = array( 42 | 43 | // Open tab: Regular fields 44 | array( 45 | 'type' => 'opentab', 46 | 'name' => __( 'Regular fields', 'plugin-example' ), 47 | ), 48 | 49 | // Text field 50 | array( 51 | 'id' => 'text_field_id', 52 | 'type' => 'text', 53 | 'default' => 'Default value', 54 | 'name' => __( 'Text field', 'plugin-example' ), 55 | 'desc' => __( 'Text field description', 'plugin-example' ), 56 | ), 57 | 58 | // Textarea 59 | array( 60 | 'id' => 'textarea_id', 61 | 'type' => 'textarea', 62 | 'default' => 'Default value', 63 | 'rows' => 10, 64 | 'name' => __( 'Textarea', 'plugin-example' ), 65 | 'desc' => __( 'Textarea description', 'plugin-example' ), 66 | ), 67 | 68 | // Checkbox 69 | array( 70 | 'id' => 'checkbox_id', 71 | 'type' => 'checkbox', 72 | 'default' => 'on', 73 | 'name' => __( 'Checkbox', 'plugin-example' ), 74 | 'desc' => __( 'Checkbox description', 'plugin-example' ), 75 | 'label' => __( 'Enabled', 'plugin-example' ), 76 | ), 77 | 78 | // Select (dropdown list) 79 | array( 80 | 'id' => 'select_id', 81 | 'type' => 'select', 82 | 'default' => 'option-1', 83 | 'name' => __( 'Select', 'plugin-example' ), 84 | 'desc' => __( 'Select description', 'plugin-example' ), 85 | 'options' => array( 86 | array( 87 | 'value' => 'option-1', 88 | 'label' => __( 'Option 1', 'plugin-example' ), 89 | ), 90 | array( 91 | 'value' => 'option-2', 92 | 'label' => __( 'Option 2', 'plugin-example' ), 93 | ), 94 | array( 95 | 'value' => 'option-3', 96 | 'label' => __( 'Option 3', 'plugin-example' ), 97 | ), 98 | ), 99 | ), 100 | 101 | // Multi-select (dropdown list with multiple choices) 102 | array( 103 | 'id' => 'multi_select_id', 104 | 'type' => 'select', 105 | 'default' => array( 'option-1', 'option-2' ), 106 | 'name' => __( 'Multi-select', 'plugin-example' ), 107 | 'desc' => __( 'Multi-select description', 'plugin-example' ), 108 | 'options' => array( 109 | array( 110 | 'value' => 'option-1', 111 | 'label' => __( 'Option 1', 'plugin-example' ), 112 | ), 113 | array( 114 | 'value' => 'option-2', 115 | 'label' => __( 'Option 2', 'plugin-example' ), 116 | ), 117 | array( 118 | 'value' => 'option-3', 119 | 'label' => __( 'Option 3', 'plugin-example' ), 120 | ) 121 | ), 122 | 'multiple' => true, 123 | 'size' => 4, 124 | ), 125 | 126 | // Radio buttons 127 | array( 128 | 'id' => 'radio_id', 129 | 'type' => 'radio', 130 | 'default' => 'option-1', 131 | 'name' => __( 'Radio', 'plugin-example' ), 132 | 'desc' => __( 'Radio description', 'plugin-example' ), 133 | 'options' => array( 134 | array( 135 | 'value' => 'option-1', 136 | 'label' => __( 'Option 1', 'plugin-example' ), 137 | ), 138 | array( 139 | 'value' => 'option-2', 140 | 'label' => __( 'Option 2', 'plugin-example' ), 141 | ), 142 | array( 143 | 'value' => 'option-3', 144 | 'label' => __( 'Option 3', 'plugin-example' ), 145 | ) 146 | ) 147 | ), 148 | 149 | // Number picker 150 | array( 151 | 'id' => 'number_field_id', 152 | 'type' => 'number', 153 | 'default' => 10, 154 | 'name' => __( 'Number', 'plugin-example' ), 155 | 'desc' => __( 'Number field description', 'plugin-example' ), 156 | 'min' => 0, 157 | 'max' => 20, 158 | 'step' => 1, 159 | ), 160 | 161 | // Close tab: Regular fields 162 | array( 163 | 'type' => 'closetab', 164 | ), 165 | 166 | // Open tab: Extra fields 167 | array( 168 | 'type' => 'opentab', 169 | 'name' => __( 'Extra fields', 'plugin-example' ), 170 | ), 171 | 172 | // Media (text field with Media library button) 173 | array( 174 | 'id' => 'media_field_id', 175 | 'type' => 'media', 176 | 'default' => '', 177 | 'name' => __( 'Media', 'plugin-example' ), 178 | 'desc' => __( 'Media field description', 'plugin-example' ), 179 | ), 180 | 181 | // Color picker 182 | array( 183 | 'id' => 'color_field_id', 184 | 'type' => 'color', 185 | 'default' => '#0099ff', 186 | 'name' => __( 'Color', 'plugin-example' ), 187 | 'desc' => __( 'Color field description', 'plugin-example' ), 188 | ), 189 | 190 | // Size picker 191 | array( 192 | 'id' => 'size_field_id', 193 | 'type' => 'size', 194 | 'default' => array( 0 => '20', 1 => 'px' ), 195 | 'name' => __( 'Size', 'plugin-example' ), 196 | 'desc' => __( 'Size field description', 'plugin-example' ), 197 | 'units' => array( 'px', 'em', '%' ), 198 | 'min' => 0, 199 | 'max' => 200, 200 | 'step' => 10, 201 | ), 202 | 203 | // Checkbox group 204 | array( 205 | 'id' => 'checkbox_group_id', 206 | 'type' => 'checkbox_group', 207 | 'default' => array( 208 | 'checkbox-1' => 'on', 209 | 'checkbox-2' => 'on', 210 | ), 211 | 'name' => __( 'Checkbox group', 'plugin-example' ), 212 | 'desc' => __( 'Checkbox group description', 'plugin-example' ), 213 | 'options' => array( 214 | array( 215 | 'id' => 'checkbox-1', 216 | 'label' => __( 'Checkbox 1', 'plugin-example' ), 217 | ), 218 | array( 219 | 'id' => 'checkbox-2', 220 | 'label' => __( 'Checkbox 2', 'plugin-example' ), 221 | ), 222 | array( 223 | 'id' => 'checkbox-3', 224 | 'label' => __( 'Checkbox 3', 'plugin-example' ), 225 | ) 226 | ), 227 | 'multiple' => true, 228 | 'size' => 4, 229 | ), 230 | 231 | // Custom HTML content 232 | array( 233 | 'type' => 'html', 234 | 'content' => '

HTML field type

Paragraph tag

', 235 | ), 236 | 237 | // Custom title 238 | array( 239 | 'type' => 'title', 240 | 'name' => __( 'Title field', 'plugin-example' ), 241 | ), 242 | 243 | // Image radio 244 | array( 245 | 'id' => 'image_radio_id', 246 | 'type' => 'image_radio', 247 | 'default' => 'option-1', 248 | 'name' => __( 'Image radio', 'plugin-example' ), 249 | 'desc' => __( 'Image radio description', 'plugin-example' ), 250 | 'options' => array( 251 | array( 252 | 'value' => 'option-1', 253 | 'label' => __( 'Option 1', 'plugin-example' ), 254 | 'image' => 'http://lorempixel.com/120/90/food/1/', 255 | ), 256 | array( 257 | 'value' => 'option-2', 258 | 'label' => __( 'Option 2', 'plugin-example' ), 259 | 'image' => 'http://lorempixel.com/120/90/food/2/', 260 | ), 261 | array( 262 | 'value' => 'option-3', 263 | 'label' => __( 'Option 3', 'plugin-example' ), 264 | 'image' => 'http://lorempixel.com/120/90/food/3/', 265 | ), 266 | ), 267 | ), 268 | 269 | // Close tab: Extra fields 270 | array( 271 | 'type' => 'closetab', 272 | ) 273 | ); 274 | 275 | // Add top-level menu (like Dashboard -> Comments) 276 | $admin->add_menu( array( 277 | // Settings page 278 | 'page_title' => __( 'Example Plugin Settings', 'plugin-example' ), 279 | // Menu title, will be shown in left dashboard menu 280 | 'menu_title' => __( 'Example Plugin', 'plugin-example' ), 281 | // Minimal user capability to access this page 282 | 'capability' => 'manage_options', 283 | // Unique page slug 284 | 'slug' => 'plugin-example-settings', 285 | // Add here your custom icon url, or use [dashicons](https://developer.wordpress.org/resource/dashicons/) 286 | // 'icon_url' => admin_url( 'images/wp-logo.png' ), 287 | 'icon_url' => 'dashicons-wordpress', 288 | // Menu position from 80 to <infinity>, you can use decimals 289 | 'position' => '91.1', 290 | // Array with options available on this page 291 | 'options' => $options, 292 | ) ); 293 | 294 | // Add sub-menu (like Dashboard -> Settings -> Permalinks) 295 | $admin->add_submenu( array( 296 | // Settings page <title> 297 | 'page_title' => __( 'Example Plugin Settings', 'plugin-example' ), 298 | // Menu title, will be shown in left dashboard menu 299 | 'menu_title' => __( 'Page 2', 'plugin-example' ), 300 | // Unique page slug, you can use here the slug of parent page, which you've already created 301 | 'slug' => 'plugin-example-settings-2', 302 | // Slug of the parent page (see above) 303 | 'parent_slug' => 'plugin-example-settings', 304 | // Array with options available on this page 305 | 'options' => $options, 306 | ) ); 307 | 308 | // Add another sub-menu (like Dashboard -> Settings -> Permalinks) 309 | $admin->add_submenu( array( 310 | // Settings page <title> 311 | 'page_title' => __( 'Example Plugin Settings', 'plugin-example' ), 312 | // Menu title, will be shown in left dashboard menu 313 | 'menu_title' => __( 'Page 3', 'plugin-example' ), 314 | // Unique page slug, you can use here the slug of parent page, which you've already created 315 | 'slug' => 'plugin-example-settings-3', 316 | // Slug of the parent page (see above) 317 | 'parent_slug' => 'plugin-example-settings', 318 | // Array with options available on this page 319 | 'options' => $options, 320 | ) ); 321 | } 322 | 323 | // Hook to plugins_loaded 324 | add_action( 'plugins_loaded', 'plugin_example_init' ); 325 | -------------------------------------------------------------------------------- /sunrise.css: -------------------------------------------------------------------------------- 1 | /*********************************** 2 | Common styles 3 | ***********************************/ 4 | 5 | .sunrise-onehalf { 6 | width: 46%; 7 | margin: 0 4% 1em 0; 8 | float: left; 9 | } 10 | .sunrise-onethird { 11 | width: 31%; 12 | margin: 0 2% 1em 0; 13 | float: left; 14 | } 15 | .sunrise-clear { 16 | display: block; 17 | height: 0; 18 | clear: both; 19 | overflow: hidden; 20 | } 21 | .sunrise-hidden { display: none; } 22 | 23 | 24 | /*********************************** 25 | Nav tabs 26 | ***********************************/ 27 | 28 | #sunrise-tabs { } 29 | #sunrise-tabs span { cursor: pointer; } 30 | #sunrise-tabs .nav-tab-active, 31 | #sunrise-tabs span:hover { color: #464646; } 32 | #sunrise-tabs .nav-tab-active { cursor: default; } 33 | h3.sunrise-no-js-tab { 34 | margin: 1em 0; 35 | padding: 1em; 36 | border-top: 2px solid #ccc; 37 | border-bottom: 2px solid #ccc; 38 | background: #f2f2f2; 39 | color: #555; 40 | } 41 | 42 | 43 | /*********************************** 44 | Panes 45 | ***********************************/ 46 | 47 | .sunrise-pane { 48 | margin: 2em 0; 49 | } 50 | .sunrise-pane .widefat { 51 | max-width: 600px; 52 | } 53 | .js .sunrise-pane { 54 | display: none; 55 | border: none; 56 | } 57 | 58 | 59 | /*********************************** 60 | Notices 61 | ***********************************/ 62 | 63 | #sunrise-settings div.sunrise-notice { margin: 1.5em 0; } 64 | 65 | 66 | /*********************************** 67 | Inline menus 68 | ***********************************/ 69 | 70 | .sunrise-inline-menu { 71 | margin: 1.5em 0; 72 | line-height: 1.5em; 73 | } 74 | .sunrise-inline-menu a { 75 | display: inline-block; 76 | padding: 0 0.7em; 77 | border-right: 1px dotted #ccc; 78 | text-decoration: none; 79 | line-height: 1.5em; 80 | } 81 | .sunrise-inline-menu a:hover { 82 | text-decoration: underline; 83 | } 84 | .sunrise-inline-menu a:first-child { 85 | padding-left: 0; 86 | } 87 | .sunrise-inline-menu a:last-child { 88 | display: inline-block; 89 | padding-right: 0; 90 | border-right: none; 91 | } 92 | 93 | 94 | /*********************************** 95 | Common fields 96 | ***********************************/ 97 | 98 | #sunrise-settings .form-table td, 99 | #sunrise-settings .form-table th { padding-bottom: 20px; } 100 | 101 | #sunrise-settings .description { 102 | display: block; 103 | margin-top: 5px; 104 | } 105 | 106 | #sunrise-settings textarea { min-width: 200px; } 107 | 108 | .sunrise-checkbox-group label { 109 | display: inline-block; 110 | margin: 0 0 5px 0; 111 | } 112 | .sunrise-title-field { 113 | margin: 0 0 0.5em; 114 | padding: 0 0 0.5em; 115 | border-bottom: 1px solid #ddd; 116 | color: #999; 117 | font-weight: bold; 118 | font-size: 17px; 119 | } 120 | 121 | 122 | /*********************************** 123 | Color picker 124 | ***********************************/ 125 | 126 | .sunrise-color-picker { position: relative; } 127 | .sunrise-color-picker-wheel { 128 | position: absolute; 129 | top: 100%; 130 | left: 0; 131 | z-index: 9999; 132 | display: none; 133 | border: 1px solid #aaa; 134 | -webkit-border-radius: 50%; 135 | -moz-border-radius: 50%; 136 | border-radius: 50%; 137 | background: #fff; 138 | -webkit-box-shadow: 0 2px 5px #ccc; 139 | -moz-box-shadow: 0 2px 5px #ccc; 140 | box-shadow: 0 2px 5px #ccc; 141 | } 142 | .sunrise-color-picker .button img { 143 | margin: -3px 4px 0 -4px; 144 | vertical-align: middle; 145 | } 146 | 147 | 148 | /*********************************** 149 | Media manager 150 | ***********************************/ 151 | 152 | .sunrise-media { } 153 | .sunrise-media .button img { 154 | margin: -3px 4px 0 -4px; 155 | vertical-align: middle; 156 | } 157 | 158 | 159 | /*********************************** 160 | Image radio 161 | ***********************************/ 162 | 163 | .sunrise-image-radio { } 164 | .sunrise-image-radio a { 165 | position: relative; 166 | display: inline-block; 167 | margin: 0 10px 10px 0; 168 | padding: 4px; 169 | background: #f0f0f0; 170 | text-decoration: none; 171 | -webkit-border-radius: 3px; 172 | -moz-border-radius: 3px; 173 | border-radius: 3px; 174 | outline: none; 175 | } 176 | .sunrise-image-radio a:hover { 177 | background: #eee; 178 | } 179 | .sunrise-image-radio a.sunrise-image-radio-selected { 180 | background: #2685AF; 181 | } 182 | .sunrise-image-radio img { 183 | max-width: 400px; 184 | margin: 0; 185 | padding: 0; 186 | border: 1px solid #fff; 187 | display: block; 188 | } 189 | .sunrise-image-radio a.sunrise-image-radio-selected img { 190 | opacity: 0.85; 191 | filter: alpha(opacity=85); 192 | } 193 | 194 | 195 | /*********************************** 196 | Actions bar 197 | ***********************************/ 198 | 199 | .sunrise-actions-bar { 200 | margin-top: 20px; 201 | padding: 10px; 202 | border-top: 1px solid #eee; 203 | -webkit-border-bottom-right-radius: 5px; 204 | -moz-border-radius-bottomright: 5px; 205 | border-bottom-right-radius: 5px; 206 | -webkit-border-bottom-left-radius: 5px; 207 | -moz-border-radius-bottomleft: 5px; 208 | border-bottom-left-radius: 5px; 209 | background: #f5f5f5; 210 | } 211 | .sunrise-spin, 212 | .sunrise-success-tip { 213 | display: none; 214 | margin-left: 10px; 215 | } 216 | .sunrise-success-tip { color: #0b0; } 217 | .sunrise-spin img, 218 | .sunrise-success-tip img { margin: 0 5px -3px 0; } -------------------------------------------------------------------------------- /sunrise.js: -------------------------------------------------------------------------------- 1 | // Wait DOM 2 | jQuery(document).ready(function ($) { 3 | 4 | 5 | // ########## Tabs ########## 6 | 7 | // Nav tab click 8 | $('#sunrise-tabs span').click(function (event) { 9 | // Hide tips 10 | $('.sunrise-spin, .sunrise-success-tip').hide(); 11 | // Remove active class from all tabs 12 | $('#sunrise-tabs span').removeClass('nav-tab-active'); 13 | // Hide all panes 14 | $('.sunrise-pane').hide(); 15 | // Add active class to current tab 16 | $(this).addClass('nav-tab-active'); 17 | // Show current pane 18 | $('.sunrise-pane:eq(' + $(this).index() + ')').fadeIn(300); 19 | // Save tab to cookies 20 | createCookie(pagenow + '_last_tab', $(this).index(), 365); 21 | }); 22 | 23 | // Auto-open tab by link with hash 24 | if (strpos(document.location.hash, '#tab-') !== false) $('#sunrise-tabs span:eq(' + document.location.hash.replace('#tab-', '') + ')').trigger('click'); 25 | // Auto-open tab by cookies 26 | else if (readCookie(pagenow + '_last_tab') != null) $('#sunrise-tabs span:eq(' + readCookie(pagenow + '_last_tab') + ')').trigger('click'); 27 | // Open first tab by default 28 | else $('#sunrise-tabs span:eq(0)').trigger('click'); 29 | 30 | 31 | // ########## Ajaxed form ########## 32 | 33 | $('#sunrise-form').ajaxForm({ 34 | beforeSubmit: function() { 35 | $('.sunrise-success-tip').hide(); 36 | $('.sunrise-spin').fadeIn(200); 37 | $('.sunrise-submit').attr('disabled', true); 38 | $('.sunrise-notice').fadeOut(400); 39 | }, 40 | success: function() { 41 | $('.sunrise-spin').hide(); 42 | $('.sunrise-success-tip').show(); 43 | setTimeout(function() { 44 | $('.sunrise-success-tip').fadeOut(200); 45 | }, 2000); 46 | $('.sunrise-submit').attr('disabled', false); 47 | } 48 | }); 49 | 50 | 51 | // ########## Reset settings confirmation ########## 52 | 53 | $('.sunrise-reset').click(function () { 54 | if (!confirm($(this).attr('title'))) return false; 55 | else return true; 56 | }); 57 | 58 | // ########## Color picker ########## 59 | 60 | $('.sunrise-color-picker').each(function (i) { 61 | $(this).find('.sunrise-color-picker-wheel').filter(':first').farbtastic('.sunrise-color-picker-value:eq(' + 62 | i + ')'); 63 | $(this).find('.sunrise-color-picker-value').focus(function () { 64 | $('.sunrise-color-picker-wheel:eq(' + i + ')').show(); 65 | }); 66 | $(this).find('.sunrise-color-picker-value').blur(function () { 67 | $('.sunrise-color-picker-wheel:eq(' + i + ')').hide(); 68 | }); 69 | $(this).find('.sunrise-color-picker-button').click(function (e) { 70 | $('.sunrise-color-picker-value:eq(' + i + ')').focus(); 71 | e.preventDefault(); 72 | }); 73 | }); 74 | 75 | // ########## Media manager ########## 76 | 77 | $('.sunrise-media-button').each(function () { 78 | var $button = $(this), 79 | $val = $(this).parents('.sunrise-media').find('input:text'), 80 | file; 81 | $button.on('click', function (e) { 82 | e.preventDefault(); 83 | // If the frame already exists, reopen it 84 | if (typeof (file) !== 'undefined') file.close(); 85 | // Create WP media frame. 86 | file = wp.media.frames.customHeader = wp.media({ 87 | // Title of media manager frame 88 | title: sunrise.media_title, 89 | button: { 90 | //Button text 91 | text: sunrise.media_insert 92 | }, 93 | // Do not allow multiple files, if you want multiple, set true 94 | multiple: false 95 | }); 96 | //callback for selected image 97 | file.on('select', function () { 98 | var attachment = file.state().get('selection').first().toJSON(); 99 | $val.val(attachment.url).trigger('change'); 100 | }); 101 | // Open modal 102 | file.open(); 103 | }); 104 | }); 105 | 106 | // ########## Image radio ########## 107 | 108 | $('.sunrise-image-radio').each(function () { 109 | var $this = $(this), 110 | $options = $this.find('a'), 111 | $value = $this.find('input'); 112 | // Image click 113 | $options.on('click', function (e) { 114 | // Remove selected class from all options 115 | $options.removeClass('sunrise-image-radio-selected'); 116 | // Add selected class to the current option 117 | $(this).addClass('sunrise-image-radio-selected'); 118 | // Set new value 119 | $value.val($(this).data('value')); 120 | e.preventDefault(); 121 | }); 122 | // Activate selected image 123 | $options.filter('[data-value="' + $value.val() + '"]').addClass('sunrise-image-radio-selected'); 124 | }); 125 | 126 | // ########## Cookie utilities ########## 127 | 128 | function createCookie(name, value, days) { 129 | if (days) { 130 | var date = new Date(); 131 | date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); 132 | var expires = "; expires=" + date.toGMTString() 133 | } else var expires = ""; 134 | document.cookie = name + "=" + value + expires + "; path=/" 135 | } 136 | 137 | function readCookie(name) { 138 | var nameEQ = name + "="; 139 | var ca = document.cookie.split(';'); 140 | for (var i = 0; i < ca.length; i++) { 141 | var c = ca[i]; 142 | while (c.charAt(0) == ' ') c = c.substring(1, c.length); 143 | if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length) 144 | } 145 | return null 146 | } 147 | 148 | // ########## Strpos tool ########## 149 | 150 | function strpos(haystack, needle, offset) { 151 | var i = haystack.indexOf(needle, offset); 152 | return i >= 0 ? i : false; 153 | } 154 | 155 | }); -------------------------------------------------------------------------------- /sunrise.php: -------------------------------------------------------------------------------- 1 | <?php 2 | if ( !class_exists( 'Sunrise7' ) ) { 3 | 4 | /** 5 | * Sunrise 6 | * 7 | * @author Vladimir Anokhin <http://gndev.info/> 8 | * @license MIT 9 | */ 10 | class Sunrise7 { 11 | 12 | /** @var array Class config */ 13 | var $config = array(); 14 | 15 | /** 16 | * Constructor 17 | * 18 | * @param array Class settings 19 | */ 20 | function __construct( $args = array() ) { 21 | // Parse config 22 | $args = wp_parse_args( $args, array( 23 | 'file' => '', 24 | 'slug' => '', 25 | 'prefix' => '', 26 | 'textdomain' => '', 27 | 'url' => '', 28 | 'version' => '7', 29 | 'options' => array(), 30 | 'menus' => array(), 31 | 'pages' => array(), 32 | 'slugs' => array(), 33 | 'css' => 'assets/css', 34 | 'js' => 'assets/js', 35 | 'views_class' => 'Sunrise7_Views' 36 | ) ); 37 | // Check required settings 38 | if ( !$args['file'] ) wp_die( 'Sunrise: please specify plugin __FILE__' ); 39 | if ( !$args['slug'] ) $args['slug'] = sanitize_key( plugin_basename( basename( $args['file'] , '.php' ) ) ); 40 | if ( !$args['prefix'] ) $args['prefix'] = 'sunrise_' . sanitize_key( $args['slug'] ) . '_'; 41 | if ( !$args['textdomain'] ) $args['textdomain'] = sanitize_key( $args['slug'] ); 42 | // Setup config 43 | $this->config = $args; 44 | // Register hooks 45 | add_action( 'admin_menu', array( &$this, 'register' ) ); 46 | add_action( 'admin_init', array( &$this, 'assets' ), 10 ); 47 | add_action( 'admin_init', array( &$this, 'enqueue' ), 20 ); 48 | add_action( 'admin_init', array( &$this, 'defaults' ) ); 49 | add_action( 'admin_init', array( &$this, 'submit' ) ); 50 | } 51 | 52 | /** 53 | * Helper to get config 54 | * 55 | * @param mixed $option Option ID 56 | * @return mixed Option value 57 | */ 58 | public function config( $option = false ) { 59 | if ( $option ) $data = ( isset( $this->config[$option] ) ) ? $this->config[$option] : false; 60 | else $data = $this->config; 61 | return $data; 62 | } 63 | 64 | /** 65 | * Register options pages 66 | */ 67 | public function register() { 68 | if ( isset( $this->config['menus'] ) && count( $this->config['menus'] ) ) 69 | foreach ( $this->config['menus'] as $menu ) { 70 | add_menu_page( $menu['page_title'], $menu['menu_title'], $menu['capability'], $menu['slug'], array( &$this, 'render' ), $menu['icon_url'], $menu['position'] ); 71 | } 72 | if ( isset( $this->config['pages'] ) && count( $this->config['pages'] ) ) 73 | foreach ( $this->config['pages'] as $page ) { 74 | add_submenu_page( $page['parent_slug'], $page['page_title'], $page['menu_title'], $page['capability'], $page['slug'], array( &$this, 'render' ) ); 75 | } 76 | } 77 | 78 | /** 79 | * Add top-level menu 80 | * 81 | * @param array $args Page config and options 82 | */ 83 | public function add_menu( $args ) { 84 | // Prepare default config 85 | $args = wp_parse_args( $args, array( 86 | 'page_title' => __( 'Plugin Settings', $this->config['textdomain'] ), 87 | 'menu_title' => __( 'Plugin Settings', $this->config['textdomain'] ), 88 | 'capability' => 'manage_options', 89 | 'slug' => $this->config['slug'], 90 | 'icon_url' => '', 91 | 'position' => '81.' . rand( 0, 99 ), 92 | 'url' => '', 93 | 'options' => array() 94 | ) ); 95 | // Define page url 96 | if ( !$args['url'] ) $args['url'] = admin_url( 'admin.php?page=' . $args['slug'] ); 97 | // Save url to global config 98 | if ( !$this->config['url'] ) $this->config['url'] = $args['url']; 99 | // Save options to global config 100 | if ( is_array( $args['options'] ) && count( $args['options'] ) ) foreach ( $args['options'] as $option ) { 101 | $this->config['options'][] = $option; 102 | } 103 | // Save menu slug to the global config 104 | $this->config['slugs'][] = $args['slug']; 105 | // Add page to global config 106 | $this->config['menus'][$args['slug']] = $args; 107 | } 108 | 109 | /** 110 | * Add sub-menu 111 | * 112 | * @param array $args Page config and options 113 | */ 114 | public function add_submenu( $args ) { 115 | // Prepare default config 116 | $args = wp_parse_args( $args, array( 117 | 'parent_slug' => 'options-general.php', 118 | 'page_title' => __( 'Plugin Settings', $this->config['textdomain'] ), 119 | 'menu_title' => __( 'Plugin Settings', $this->config['textdomain'] ), 120 | 'capability' => 'manage_options', 121 | 'slug' => $this->config['slug'], 122 | 'url' => '', 123 | 'options' => array() 124 | ) ); 125 | // Define page url 126 | if ( !$args['url'] ) { 127 | if ( strpos( $args['parent_slug'], '.php' ) !== false && strpos( $args['parent_slug'], '?' ) !== false ) $args['url'] = admin_url( $args['parent_slug'] . '&page=' . $args['slug'] ); 128 | elseif ( strpos( $args['parent_slug'], '.php' ) !== false ) $args['url'] = admin_url( $args['parent_slug'] . '?page=' . $args['slug'] ); 129 | else $args['url'] = ( isset( $this->config['menus'][$args['parent_slug']] ) ) ? admin_url( 'admin.php?page=' . $args['slug'] ) : ''; 130 | } 131 | // Save url to global config 132 | if ( !$this->config['url'] ) $this->config['url'] = $args['url']; 133 | // Save options to global config 134 | if ( is_array( $args['options'] ) && count( $args['options'] ) && !in_array( $args['slug'], array_keys( (array) $this->config['menus'] ) ) ) foreach ( $args['options'] as $option ) { 135 | $this->config['options'][] = $option; 136 | } 137 | // Save page slug to the global config 138 | $this->config['slugs'][] = $args['slug']; 139 | // Add page to global config 140 | $this->config['pages'][$args['slug']] = $args; 141 | } 142 | 143 | /** 144 | * Display options page 145 | */ 146 | public function render() { 147 | // Prepare page options 148 | $options = $this->get_page_options(); 149 | // Get current page slug 150 | $page = sanitize_key( $_GET['page'] ); 151 | // Hook before page output 152 | do_action( 'sunrise/page/before' ); 153 | do_action( 'sunrise/page/' . $page . '/before' ); 154 | echo '<div id="sunrise-settings" class="wrap">'; 155 | echo call_user_func( array( $this->config['views_class'], 'options_page_tabs' ), $options, $this->config ); 156 | echo call_user_func( array( $this->config['views_class'], 'options_page_notices' ), $options, $this->config ); 157 | echo '<form action="" method="post" id="sunrise-form">'; 158 | echo call_user_func( array( $this->config['views_class'], 'options_page_panes' ), $options, $this->config ); 159 | echo '<input type="hidden" name="sunrise_action" value="save" />'; 160 | echo '<input type="hidden" name="sunrise_nonce" value="' . wp_create_nonce( 'sunrise' ) . '" />'; 161 | do_action( 'sunrise/page/form' ); 162 | echo '</form></div>'; 163 | // Hook after page output 164 | do_action( 'sunrise/page/after' ); 165 | do_action( 'sunrise/page/' . $page . '/after' ); 166 | } 167 | 168 | /** 169 | * Register class assets 170 | */ 171 | public function assets() { 172 | // Register styles 173 | wp_register_style( 'sunrise-' . $this->config['version'], plugins_url( $this->config['css'], $this->config['file'] ) . '/sunrise.css', false, $this->config['version'], 'all' ); 174 | // Register scripts 175 | wp_register_script( 'sunrise-' . $this->config['version'], plugins_url( $this->config['js'], $this->config['file'] ) . '/sunrise.js', array( 'jquery', 'jquery-form' ), $this->config['version'], true ); 176 | // Add some l10n to JS 177 | wp_localize_script( 'sunrise-' . $this->config['version'], 'sunrise', array( 178 | 'media_title' => __( 'Choose file', $this->config['textdomain'] ), 179 | 'media_insert' => __( 'Use selected file', $this->config['textdomain'] ) 180 | ) ); 181 | // Hook to add/remove custom files 182 | do_action( 'sunrise/assets/register' ); 183 | } 184 | 185 | /** 186 | * Enqueue class assets 187 | */ 188 | public function enqueue() { 189 | // Check there is an options page 190 | if ( !$this->is_sunrise() ) return; 191 | // Enqueue styles 192 | foreach ( array( 'farbtastic', 'sunrise-' . $this->config['version'] ) as $style ) wp_enqueue_style( $style ); 193 | // Enqueue scripts 194 | foreach ( array( 'jquery', 'jquery-form', 'farbtastic', 'sunrise-' . $this->config['version'] ) as $script ) wp_enqueue_script( $script ); 195 | // Hook to add/remove files 196 | do_action( 'sunrise/assets/enqueue' ); 197 | } 198 | 199 | /** 200 | * Hook to insert default settings 201 | */ 202 | public function defaults() { 203 | // Check defaults isn't set 204 | if ( get_option( 'sunrise_defaults_' . $this->config['slug'] ) ) return; 205 | // Check config options 206 | if ( isset( $this->config['options'] ) && is_array( $this->config['options'] ) ) { 207 | // Insert default options 208 | foreach ( $this->config['options'] as $option ) { 209 | // Option id and option defaut value is present 210 | if ( isset( $option['id'] ) && isset( $option['default'] ) ) update_option( $this->config['prefix'] . $option['id'], $option['default'] ); 211 | // Default value isn't set bacause there is an multiple options array 212 | elseif ( isset( $option['id'] ) && isset( $option['options'] ) && is_array( $option['options'] ) ) { 213 | $options = array(); 214 | foreach ( $option['options'] as $item ) { 215 | if ( isset( $item['id'] ) && isset( $item['default'] ) ) $options[$item['id']] = $item['default']; 216 | } 217 | update_option( $this->config['prefix'] . $option['id'], $options ); 218 | } 219 | } 220 | // Defaults is set 221 | update_option( 'sunrise_defaults_' . $this->config['slug'], true ); 222 | } 223 | } 224 | 225 | /** 226 | * Hook to process submitted data 227 | */ 228 | public function submit() { 229 | // Check request 230 | if ( empty( $_REQUEST['sunrise_action'] ) || empty( $_REQUEST['page'] ) ) return; 231 | // Check nonce 232 | if ( empty( $_REQUEST['sunrise_nonce'] ) || !wp_verify_nonce( $_REQUEST['sunrise_nonce'], 'sunrise' ) ) return; 233 | // Check page 234 | if ( !$this->is_sunrise() ) return; 235 | // Prepare page slug 236 | $page = sanitize_key( $_GET['page'] ); 237 | // Submit hooks 238 | do_action( 'sunrise/submit', $this ); 239 | do_action( 'sunrise/submit/' . $page, $this ); 240 | // Parse incoming data 241 | $action = sanitize_key( $_REQUEST['sunrise_action'] ); 242 | $request = ( isset( $_REQUEST['sunrise'] ) ) ? (array) $_REQUEST['sunrise'] : array(); 243 | // Run actions 244 | // Save options 245 | if ( $action === 'save' ) { 246 | // Loop through current page options 247 | foreach ( (array) $this->get_page_options() as $option ) { 248 | // Option must have an ID 249 | if ( !isset( $option['id'] ) ) continue; 250 | // Prepare value 251 | $val = ( isset( $request[$option['id']] ) ) ? $request[$option['id']] : ''; 252 | // Save options value 253 | update_option( $this->config['prefix'] . $option['id'], $val ); 254 | } 255 | // Save hooks 256 | do_action( 'sunrise/save', $this ); 257 | do_action( 'sunrise/save/' . $page, $this ); 258 | // Set message 259 | $message = 1; 260 | } 261 | // Reset options 262 | elseif ( $action === 'reset' ) { 263 | // Loop through current page options 264 | foreach ( (array) $this->get_page_options() as $option ) { 265 | // Option must have an ID 266 | if ( !isset( $option['id'] ) ) continue; 267 | // Reset option with multiple values 268 | if ( !isset( $option['default'] ) && isset( $option['options'] ) ) { 269 | // Prepare variable for default value 270 | $option['default'] = array(); 271 | // Loop through multiple values 272 | foreach ( (array) $option['options'] as $item ) { 273 | if ( isset( $item['id'] ) && isset( $item['default'] ) ) $option['default'][$item['id']] = $item['default']; 274 | } 275 | } 276 | // Save option value 277 | if ( isset( $option['default'] ) ) update_option( $this->config['prefix'] . $option['id'], $option['default'] ); 278 | } 279 | // Reset hooks 280 | do_action( 'sunrise/reset', $this ); 281 | do_action( 'sunrise/reset/' . $page, $this ); 282 | // Set message 283 | $message = 2; 284 | } 285 | // Other actions 286 | else { 287 | // Set message var to "Something went wrong..." 288 | $message = 3; 289 | } 290 | // Go to page with specified message 291 | wp_redirect( $this->get_page_url() . '&message=' . $message ); 292 | exit; 293 | } 294 | 295 | /** 296 | * Get current page data 297 | */ 298 | public function get_page() { 299 | $slug = sanitize_key( $_REQUEST['page'] ); 300 | // This page is added to the top-level menus 301 | if ( in_array( $slug, array_keys( (array) $this->config['menus'] ) ) ) return $this->config['menus'][$slug]; 302 | // This page is added to the sub-menus 303 | else if ( in_array( $slug, array_keys( (array) $this->config['pages'] ) ) ) return $this->config['pages'][$slug]; 304 | // Return an empty array by default 305 | return array(); 306 | } 307 | 308 | /** 309 | * Get current page options 310 | */ 311 | public function get_page_options() { 312 | // Get current page data 313 | $page = $this->get_page(); 314 | // Prepare array for options 315 | $options = array(); 316 | // This page have some options 317 | if ( isset( $page['options'] ) && is_array( $page['options'] ) ) 318 | // Loop through page options 319 | foreach ( $page['options'] as $option ) { 320 | // Add option to resulting array 321 | $options[] = $option; 322 | } 323 | // Return options 324 | return $options; 325 | } 326 | 327 | /** 328 | * Get current page URL 329 | * 330 | * @param mixed $slug Page slug (optional). This parameter can be automatically retrieved from $_GET['page'] 331 | * @return string Page URL 332 | */ 333 | public function get_page_url( $slug = false ) { 334 | // Get slug from $_GET['page'] 335 | if ( !$slug && isset( $_REQUEST['page'] ) ) $slug = sanitize_key( $_REQUEST['page'] ); 336 | // Serach for URL in registered top-level menus 337 | if ( isset( $this->config['menus'][$slug] ) && isset( $this->config['menus'][$slug]['url'] ) ) return $this->config['menus'][$slug]['url']; 338 | // Serach for URL in registered sub-menus 339 | elseif ( isset( $this->config['pages'][$slug] ) && isset( $this->config['pages'][$slug]['url'] ) ) return $this->config['pages'][$slug]['url']; 340 | // Return empty string if URL doesn't found 341 | return ''; 342 | } 343 | 344 | /** 345 | * Conditional check for Sunrise options page 346 | * 347 | * @return boolean true/false - there is an page created by Sunrise 348 | */ 349 | public function is_sunrise() { 350 | return isset( $_GET['page'] ) && in_array( $_GET['page'], $this->config['slugs'] ); 351 | } 352 | 353 | } 354 | } 355 | 356 | if ( !class_exists( 'Sunrise7_Views' ) ) { 357 | 358 | /** 359 | * Sunrise Views 360 | * 361 | * no comments, just some markup 362 | */ 363 | class Sunrise7_Views { 364 | 365 | function __construct() {} 366 | 367 | public static function notice( $msg = '', $class = '' ) { 368 | return '<div class="sunrise-notice ' . $class . '"><p>' . $msg . '</p></div>'; 369 | } 370 | 371 | public static function type_opentab( $field, $config ) { 372 | return '<div class="sunrise-pane"><h3 class="hide-if-js sunrise-no-js-tab">' . $field['name'] . '</h3><table class="form-table">'; 373 | } 374 | 375 | public static function type_closetab( $field, $config ) { 376 | $field = wp_parse_args( $field, array( 'actions' => true ) ); 377 | $return = array(); 378 | $return[] = '</table>'; 379 | if ( $field['actions'] ) $return[] = '<div class="sunrise-actions-bar"><input type="submit" value="' . __( 'Save changes', $config['textdomain'] ) . '" class="sunrise-submit button-primary" /><span class="sunrise-spin"><img src="' . admin_url( 'images/wpspin_light.gif' ) . '" alt="" /> ' . __( 'Saving', $config['textdomain'] ) . '…</span><span class="sunrise-success-tip"><img src="' . admin_url( 'images/yes.png' ) . '" alt="" /> ' . __( 'Saved', $config['textdomain'] ) . '</span><a href="' . $_SERVER["REQUEST_URI"] . '&sunrise_action=reset&sunrise_nonce=' . wp_create_nonce( 'sunrise' ) . '" class="sunrise-reset button alignright" title="' . esc_attr( __( 'This action will delete all your settings. Are you sure? This action cannot be undone!', $config['textdomain'] ) ) . '">' . __( 'Restore default settings', $config['textdomain'] ) . '</a></div>'; 380 | $return[] = '</div>'; 381 | return implode( '', $return ); 382 | } 383 | 384 | public static function type_text( $field, $config ) { 385 | $field = wp_parse_args( $field, array( 386 | 'name' => __( 'Text field', $config['textdomain'] ), 387 | 'id' => '', 388 | 'desc' => '' 389 | ) ); 390 | return '<tr><th scope="row"><label for="sunrise-field-' . $field['id'] . '">' . $field['name'] . '</label></th><td><input type="text" value="' . get_option( $config['prefix'] . $field['id'] ) . '" name="sunrise[' . $field['id'] . ']" id="sunrise-field-' . $field['id'] . '" class="widefat" /><p class="description">' . $field['desc'] . '</p></td></tr>'; 391 | } 392 | 393 | public static function type_textarea( $field, $config ) { 394 | $field = wp_parse_args( $field, array( 395 | 'name' => __( 'Textarea field', $config['textdomain'] ), 396 | 'id' => '', 397 | 'desc' => '', 398 | 'rows' => 10 399 | ) ); 400 | return '<tr><th scope="row"><label for="sunrise-field-' . $field['id'] . '">' . $field['name'] . '</label></th><td><textarea name="sunrise[' . $field['id'] . ']" id="sunrise-field-' . $field['id'] . '" class="regular-text widefat" rows="' . $field['rows'] . '">' . esc_textarea( stripslashes( get_option( $config['prefix'] . $field['id'] ) ) ) . '</textarea><p class="description">' . $field['desc'] . '</p></td></tr>'; 401 | } 402 | 403 | public static function type_checkbox( $field, $config ) { 404 | $field = wp_parse_args( $field, array( 405 | 'name' => __( 'Checkbox', $config['textdomain'] ), 406 | 'id' => '', 407 | 'desc' => '', 408 | 'label' => __( 'Label', $config['textdomain'] ) 409 | ) ); 410 | $checked = ( get_option( $config['prefix'] . $field['id'] ) === 'on' ) ? ' checked="checked"' : ''; 411 | return '<tr><th scope="row"><label for="sunrise-field-' . $field['id'] . '">' . $field['name'] . '</label></th><td><label><input type="checkbox" name="sunrise[' . $field['id'] . ']" id="sunrise-field-' . $field['id'] . '"' . $checked . ' />  ' . $field['label'] . '</label><span class="description">' . $field['desc'] . '</span></td></tr>'; 412 | } 413 | 414 | public static function type_select( $field, $config ) { 415 | $field = wp_parse_args( $field, array( 416 | 'name' => __( 'Select', $config['textdomain'] ), 417 | 'id' => '', 418 | 'desc' => '', 419 | 'options' => array(), 420 | 'multiple' => false, 421 | 'size' => 1 422 | ) ); 423 | $options = array(); 424 | $value = get_option( $config['prefix'] . $field['id'] ); 425 | if ( !$value ) $value = array(); 426 | if ( !is_array( $value ) ) $value = array( $value ); 427 | $name = ( $field['multiple'] ) ? 'sunrise[' . $field['id'] . '][]' : 'sunrise[' . $field['id'] . ']'; 428 | $field['multiple'] = ( $field['multiple'] ) ? ' multiple="multiple"' : ''; 429 | $field['size'] = ( $field['size'] > 1 ) ? ' size="' . $field['size'] . '"' : ''; 430 | foreach ( $field['options'] as $option ) { 431 | $selected = ( in_array( $option['value'], $value ) ) ? ' selected="selected"' : ''; 432 | $options[] = '<option value="' . $option['value'] . '"' . $selected . '>' . $option['label'] . '</option>'; 433 | } 434 | return '<tr><th scope="row"><label for="sunrise-field-' . $field['id'] . '">' . $field['name'] . '</label></th><td><select name="' . $name . '" class="widefat" id="sunrise-field-' . $field['id'] . '"' . $field['size'] . $field['multiple'] . '>' . implode( '', $options ) . '</select><span class="description">' . $field['desc'] . '</span></td></tr>'; 435 | } 436 | 437 | public static function type_radio( $field, $config ) { 438 | $field = wp_parse_args( $field, array( 439 | 'name' => __( 'Checkbox group', $config['textdomain'] ), 440 | 'options' => array(), 441 | 'id' => '', 442 | 'desc' => '' 443 | ) ); 444 | $group = array(); 445 | $value = get_option( $config['prefix'] . $field['id'] ); 446 | if ( is_array( $field['options'] ) ) foreach ( $field['options'] as $single ) { 447 | $checked = ( $single['value'] === $value ) ? ' checked="checked"' : ''; 448 | $group[] = '<label for="sunrise-field-' . $field['id'] . '-' . $single['value'] . '"><input type="radio" name="sunrise[' . $field['id'] . ']" id="sunrise-field-' . $field['id'] . '-' . $single['value'] . '" value="' . $single['value'] . '"' . $checked . ' />  ' . $single['label'] . '</label><br/>'; 449 | } 450 | return '<tr><th scope="row">' . $field['name'] . '</th><td>' . implode( '', $group ) . '<span class="description">' . $field['desc'] . '</span></td></tr>'; 451 | } 452 | 453 | public static function type_number( $field, $config ) { 454 | $field = wp_parse_args( $field, array( 455 | 'name' => __( 'Text field', $config['textdomain'] ), 456 | 'id' => '', 457 | 'desc' => '', 458 | 'min' => 0, 459 | 'max' => 100, 460 | 'step' => 1 461 | ) ); 462 | return '<tr><th scope="row"><label for="sunrise-field-' . $field['id'] . '">' . $field['name'] . '</label></th><td><input type="number" value="' . get_option( $config['prefix'] . $field['id'] ) . '" name="sunrise[' . $field['id'] . ']" id="sunrise-field-' . $field['id'] . '" class="widefat" min="' . (string) $field['min'] . '" max="' . (string) $field['max'] . '" step="' . (string) $field['step'] . '" /><p class="description">' . $field['desc'] . '</p></td></tr>'; 463 | } 464 | 465 | public static function type_media( $field, $config ) { 466 | $field = wp_parse_args( $field, array( 467 | 'name' => __( 'Media', $config['textdomain'] ), 468 | 'id' => '', 469 | 'desc' => '' 470 | ) ); 471 | if ( function_exists( 'wp_enqueue_media' ) ) wp_enqueue_media(); 472 | return '<tr class="sunrise-media"><th scope="row"><label for="sunrise-field-' . $field['id'] . '">' . $field['name'] . '</label></th><td><input type="text" value="' . get_option( $config['prefix'] . $field['id'] ) . '" name="sunrise[' . $field['id'] . ']" id="sunrise-field-' . $field['id'] . '" class="regular-text sunrise-media-value" /> <a href="javascript:;" class="button sunrise-media-button hide-if-no-js"><img src="' . admin_url( 'images/media-button.png' ) . '" alt="" /> ' . __( 'Open media library', $config['textdomain'] ) . '</a><p class="description">' . $field['desc'] . '</p></td></tr>'; 473 | } 474 | 475 | public static function type_color( $field, $config ) { 476 | $field = wp_parse_args( $field, array( 477 | 'name' => __( 'Color picker', $config['textdomain'] ), 478 | 'id' => '', 479 | 'desc' => '' 480 | ) ); 481 | ///////////////////////////////////////////////////////////////////////////////// 482 | // DON'T PANIC - IT's NOT A MALWARE 483 | // this is base64-encoded image for color picker =) 484 | ///////////////////////////////////////////////////////////////////////////////// 485 | return '<tr><th scope="row"><label for="sunrise-field-' . $field['id'] . '">' . $field['name'] . '</label></th><td><div class="sunrise-color-picker"><input type="text" value="' . get_option( $config['prefix'] . $field['id'] ) . '" name="sunrise[' . $field['id'] . ']" id="sunrise-field-' . $field['id'] . '" class="regular-text sunrise-color-picker-value" /><span class="sunrise-color-picker-wheel"></span> <a href="javascript:;" class="button sunrise-color-picker-button hide-if-no-js"><img alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAArFJREFUeNqkU01PE1EUPUOn004/hpmmhH6AFA2KRojxIzFoooK4calLXbhyTeLeEFe69Qe4wJiwcKMLo8Yag9EEIgsS0VpKsdOZ0hbaaUtp6cx0vAOkgbjkJefNnXn3nHvefW8Yy7JwlMHa06uXDM566SUB1JbQwxcx7tpwjEJ1hKDRQju6bhg9SzrCcRfOFE2cxib8uGZN7gkckLshnQw8kG7eGREGJ45x7pCARhdaSr1ajacz5TfKbbPEvqDMz4cc7EeTbKz/Uezcs8tcwxSwvAwk54GyDy7vUKDnysVA9/mrx9ee/uw1FYfN+2jTuuzJ4hFmwsLUwPiTMY7PCdheBPyUE40AkSjg6gb+6OCqfmHg4fUxyxeaaoELdxy0grjLhm+NsJLuAyeTIq15g4DbDwgCUO8FPCKwLoH1+3zsBXOk9CV7l6jPdx0U3ZhgpUvBdSYFzSfCDBO5j6rHBggxctGHdjCCmiggX6aenJCCWWCi42BVx3DT7XcVoUCABNHhhSiK8HgiYLwBNBke2hag8UClDTQ5t2sV+nBHIGXAqaKKEizQblHZR4BzwcHzKDFExh7s79skloLh7AhQf9I/6iv9Tr/HWUCTPOyg104Es9vlMqGwA5QaQLUFqGrdSEBPd05BLiL+Vllo5Cj+CwN50lXhoBhYo+qqA8hTKZnsJ6l6PKU0MqjHOw6sFGYWpV/3gpFRPiREnQyRm1TdQ7BHkx4VEimS6VS9qifVtNLG5kzHAW1ebmmt6U9zHworWs3IkW6GyGu2A0KGkKXMlS3NWJifKxh6fZrOVj58E03MNjIb+Fp4/Th8ajvaN+TlRSnKQjdQKZaN7PdkQ32XUIy8TmRx9v+rbA/dnDWWc9/kxPv7spQdp0swiFrAtpHG7604sq0ZtGPyQQpz1N/5nwADAEUXDAYgnuAXAAAAAElFTkSuQmCC" /> ' . __( 'Pick a color', $config['textdomain'] ) . '</a></div><span class="description">' . $field['desc'] . '</span></td></tr>'; 486 | } 487 | 488 | public static function type_checkbox_group( $field, $config ) { 489 | $field = wp_parse_args( $field, array( 490 | 'name' => __( 'Checkbox group', $config['textdomain'] ), 491 | 'options' => array(), 492 | 'id' => '', 493 | 'desc' => '' 494 | ) ); 495 | $group = array(); 496 | $value = (array) get_option( $config['prefix'] . $field['id'] ); 497 | if ( is_array( $field['options'] ) ) foreach ( $field['options'] as $single ) { 498 | $checked = ( isset( $value[$single['id']] ) && $value[$single['id']] === 'on' ) ? ' checked="checked"' : ''; 499 | $group[] = '<label for="sunrise-field-' . $field['id'] . '-' . $single['id'] . '"><input type="checkbox" name="sunrise[' . $field['id'] . '][' . $single['id'] . ']" id="sunrise-field-' . $field['id'] . '-' . $single['id'] . '"' . $checked . ' />  ' . $single['label'] . '</label><br/>'; 500 | } 501 | return '<tr><th scope="row">' . $field['name'] . '</th><td class="sunrise-checkbox-group">' . implode( '', $group ) . '<span class="description">' . $field['desc'] . '</span></td></tr>'; 502 | } 503 | 504 | public static function type_html( $field, $config ) { 505 | $field = wp_parse_args( $field, array( 506 | 'content' => __( 'HTML field', $config['textdomain'] ) 507 | ) ); 508 | return '<tr><td colspan="2">' . $field['content'] . '</td></tr>'; 509 | } 510 | 511 | public static function type_title( $field, $config ) { 512 | $field = wp_parse_args( $field, array( 513 | 'name' => __( 'Title field', $config['textdomain'] ) 514 | ) ); 515 | return '<tr><td colspan="2"><h3 class="sunrise-title-field">' . $field['name'] . '</h3></td></tr>'; 516 | } 517 | 518 | public static function type_image_radio( $field, $config ) { 519 | $field = wp_parse_args( $field, array( 520 | 'name' => __( 'Image radio', $config['textdomain'] ), 521 | 'id' => '', 522 | 'desc' => '', 523 | 'options' => array() 524 | ) ); 525 | $options = array(); 526 | foreach( $field['options'] as $option ) { 527 | $label = ( isset( $option['label'] ) ) ? $option['label'] : ''; 528 | $options[] = '<a href="javascript:;" data-value="' . $option['value'] . '" title="' . $label . '"><img src="' . $option['image'] . '" alt="" /></a>'; 529 | } 530 | return '<tr><th scope="row">' . $field['name'] . '</th><td><div class="sunrise-image-radio">' . implode( '', $options ) . '<input type="hidden" value="' . get_option( $config['prefix'] . $field['id'] ) . '" name="sunrise[' . $field['id'] . ']" id="sunrise-field-' . $field['id'] . '" /></div><p class="description">' . $field['desc'] . '</p></td></tr>'; 531 | } 532 | 533 | public static function type_size( $field, $config ) { 534 | $field = wp_parse_args( $field, array( 535 | 'name' => __( 'Size', $config['textdomain'] ), 536 | 'id' => '', 537 | 'desc' => '', 538 | 'units' => array( 'px', 'em', '%' ), 539 | 'min' => 0, 540 | 'max' => 200, 541 | 'step' => 10 542 | ) ); 543 | $value = get_option( $config['prefix'] . $field['id'] ); 544 | if ( !is_array( $value ) || count( $value ) !== 2 ) $value = array( 0 => '0', 1 => 'px' ); 545 | $units = array(); 546 | foreach( $field['units'] as $unit ) { 547 | $units[] = '<option value="' . $unit . '">' . $unit . '</option>'; 548 | } 549 | return '<tr><th scope="row"><label for="sunrise-field-' . $field['id'] . '-0">' . $field['name'] . '</label></th><td><input type="number" value="' . $value[0] . '" name="sunrise[' . $field['id'] . '][0]" id="sunrise-field-' . $field['id'] . '-0" class="regular-text" min="' . (string) $field['min'] . '" max="' . (string) $field['max'] . '" step="' . (string) $field['step'] . '" /> <select name="sunrise[' . $field['id'] . '][1]" id="sunrise-field-' . $field['id'] . '-1">' . str_replace( 'value="' . $value[1] . '"', 'value="' . $value[1] . '" selected="selected"', implode( '', $units ) ) . '</select><p class="description">' . $field['desc'] . '</p></td></tr>'; 550 | } 551 | 552 | /** 553 | * Display options page tabs 554 | */ 555 | public static function options_page_tabs( $options, $config ) { 556 | // Declare tabs array 557 | $tabs = array(); 558 | // Loop through options 559 | foreach ( (array) $options as $option ) { 560 | // Current option is opentab 561 | if ( isset( $option['type'] ) && isset( $option['name'] ) && $option['type'] === 'opentab' ) $tabs[] = '<span class="nav-tab">' . $option['name'] . '</span>'; 562 | } 563 | // Return resulting markup 564 | return ( count( $tabs ) ) ? '<div id="icon-options-general" class="icon32 hide-if-no-js"><br /></div><h2 id="sunrise-tabs" class="nav-tab-wrapper hide-if-no-js">' . implode( '', $tabs ) . '</h2>' : ''; 565 | } 566 | 567 | /** 568 | * Display options page notices 569 | */ 570 | public static function options_page_notices( $options, $config ) { 571 | // Setup messsages 572 | $msgs = apply_filters( 'sunrise/page/notices', array( 573 | __( 'For full functionality of this page it is reccomended to enable javascript.', $config['textdomain'] ), 574 | __( 'Settings saved successfully', $config['textdomain'] ), 575 | __( 'Settings reseted successfully', $config['textdomain'] ), 576 | __( 'Something went wrong. Please try again later', $config['textdomain'] ), 577 | ) ); 578 | // Prepare output variable 579 | $output = array(); 580 | // Get current message 581 | $message = ( isset( $_GET['message'] ) && is_numeric( $_GET['message'] ) ) ? intval( sanitize_key( $_GET['message'] ) ) : 0; 582 | // Add no-js notice (will be hidden for js-enabled browsers) 583 | $output[] = self::notice( '<a href="http://enable-javascript.com/" target="_blank">' . $msgs[0] . '</a>.', 'error hide-if-js' ); 584 | // Show notice 585 | if ( $message !== 0 ) $output[] = self::notice( $msgs[$message], 'updated' ); 586 | // Return resulting markup 587 | return implode( '', $output ); 588 | } 589 | 590 | /** 591 | * Display options panes 592 | */ 593 | public static function options_page_panes( $options, $config ) { 594 | // Declare panes array 595 | $panes = array(); 596 | // Loop through options 597 | foreach ( $options as $option ) { 598 | // Check option type definition 599 | if ( !isset( $option['type'] ) ) continue; 600 | // Try to call option from external source 601 | elseif ( isset( $option['callback'] ) && is_callable( $option['callback'] ) ) $panes[] = call_user_func( $option['callback'], $option, $config ); 602 | // Try to call option from built-in class SunriseX_Views 603 | elseif ( is_callable( array( $config['views_class'], 'type_' . $option['type'] ) ) ) $panes[] = call_user_func( array( $config['views_class'], 'type_' . $option['type'] ), $option, $config ); 604 | // Show error message 605 | else $panes[] = call_user_func( array( $config['views_class'], 'notice' ), 'Sunrise: ' . sprintf( __( 'option type %s is not callable', $config['textdomain'] ), '<b>' . $option['type'] . '</b>' ), 'error' ); 606 | } 607 | // Return resulting markup 608 | return implode( '', $panes ); 609 | } 610 | } 611 | } 612 | --------------------------------------------------------------------------------