/**
  * Build the option pages
  *
  * Utilizes BWP Option Page Builder (@see BWP_OPTION_PAGE)
  */
 public function build_option_pages()
 {
     if (!current_user_can(BWP_MINIFY_CAPABILITY)) {
         wp_die(__('You do not have sufficient permissions to access this page.'));
     }
     $page = $_GET['page'];
     $active_page = '';
     $original_options = $this->options;
     $bwp_option_page = new BWP_OPTION_PAGE($page, $this->site_options);
     // Get option from the database, general options are used for both
     // 'General Options' page and 'Manage enqueued' page
     if (BWP_MINIFY_OPTION_GENERAL == $page || BWP_MINIFY_MANAGE == $page) {
         $active_page = BWP_MINIFY_OPTION_GENERAL;
         $options = $bwp_option_page->get_db_options($active_page, $bwp_option_page->get_options(array('input_minurl', 'input_minpath', 'input_cache_dir', 'input_doc_root', 'input_maxfiles', 'input_maxage', 'input_custom_buster', 'enable_min_js', 'enable_min_css', 'enable_external_origin', 'enable_bloginfo', 'enable_css_bubble', 'enable_cache_file_lock', 'enable_debug', 'select_buster_type', 'select_time_type', 'input_ignore', 'input_header', 'input_direct', 'input_footer', 'input_oblivion', 'input_style_ignore', 'input_style_direct', 'input_style_oblivion'), $this->options));
     } else {
         $active_page = BWP_MINIFY_OPTION_ADVANCED;
         $options = $bwp_option_page->get_db_options($active_page, $bwp_option_page->get_options(array('enable_fly_min', 'input_fly_minpath', 'input_nginx_config_file', 'enable_cdn', 'input_cdn_host', 'input_cdn_host_js', 'input_cdn_host_css', 'select_cdn_ssl_type'), $this->options));
     }
     if (!empty($page)) {
         if ($page == BWP_MINIFY_OPTION_GENERAL) {
             $bwp_option_page->set_current_tab(1);
             // add two buttons to save and flush cache or to flush cache
             // right now we only support flushing by super admin, to be
             // improved in 1.3.x
             if (!self::is_normal_admin()) {
                 add_filter('bwp_option_submit_button', array($this, 'add_flush_cache_buttons'));
             }
             $form = array('items' => array('heading', 'checkbox', 'checkbox', 'checkbox', 'checkbox', 'input', 'input', 'select', 'heading', 'input', 'input', 'input', 'checkbox', 'checkbox', 'checkbox'), 'item_labels' => array(__('Plugin Functionality', $this->domain), __('Minify JS files automatically?', $this->domain), __('Minify CSS files automatically?', $this->domain), __('Minify <code>bloginfo()</code> stylesheets?', $this->domain), __('Leave external files at their original positions?', $this->domain), __('URL path to Minify library (relative to domain root)', $this->domain), __('One minify string will contain', $this->domain), __('For cache buster, use', $this->domain), __('Minify Library Settings', $this->domain), __('WordPress document root', $this->domain), __('Cache directory', $this->domain), __('Cache age', $this->domain), __('Enable bubble CSS import?', $this->domain), __('Enable cache file locking?', $this->domain), __('Enable debugging?', $this->domain)), 'item_names' => array('h1', 'cb1', 'cb3', 'cb2', 'ext_origin', 'input_minpath', 'input_maxfiles', 'select_buster_type', 'h2', 'input_doc_root', 'input_cache_dir', 'input_maxage', 'cb4', 'cb5', 'cb6'), 'heading' => array('h1' => '', 'h2' => '<a name="minify.config.php"></a>' . sprintf(__('<em>These options will let you control how the actual ' . '<a href="%s" target="_blank">Minify</a> library works.</em>', $this->domain), 'https://code.google.com/p/minify/')), 'select' => array('select_time_type' => array(__('second(s)', $this->domain) => 1, __('minute(s)', $this->domain) => 60, __('hour(s)', $this->domain) => 3600, __('day(s)', $this->domain) => 86400), 'select_buster_type' => array(__('No cache buster', $this->domain) => 'none', __('Cache folder&#8217;s last modified time', $this->domain) => 'mtime', __('Your WordPress&#8217;s current version', $this->domain) => 'wpver', __('Your theme&#8217;s current version', $this->domain) => 'tver', __('A custom number', $this->domain) => 'custom')), 'checkbox' => array('cb1' => array(__('you can still use <code>bwp_minify()</code> helper function if you disable this.', $this->domain) => 'enable_min_js'), 'cb3' => array(__('you can still use <code>bwp_minify()</code> helper function if you disable this.', $this->domain) => 'enable_min_css'), 'cb2' => array(__('enable this for themes that use <code>bloginfo()</code> to print the main stylesheet (i.e. <code>style.css</code>). If you want to minify <code>style.css</code> with the rest of your css files, you must enqueue it.', $this->domain) => 'enable_bloginfo'), 'ext_origin' => array(__('enable this to improve compatibility with plugins/themes that print external JS/CSS files directly, for e.g. <code>Simple Google Maps Short Code</code> plugin or <code>Avada</code> theme.', $this->domain) => 'enable_external_origin'), 'cb4' => array(sprintf(__('move all <code>@import</code> rules in CSS files to the top. More info <a href="%s" target="_blank">here</a>.', $this->domain), $this->get_url('min_css_bubble')) => 'enable_css_bubble'), 'cb5' => array(__('disable this if filesystem is NFS.', $this->domain) => 'enable_cache_file_lock'), 'cb6' => array(sprintf(__('only enable this when minification does not work as expected. More info <a href="%s" target="_blank">here</a>.', $this->domain), $this->get_url('min_debug')) => 'enable_debug')), 'input' => array('input_minpath' => array('size' => 55, 'label' => '<br />' . sprintf(__('Leave empty to use default value, which is <code>%s</code>.<br />' . 'Please read <a href="%s#advanced_customization" target="_blank">here</a> ' . 'to know how to properly modify this.', $this->domain), $this->get_default_min_path(), $this->plugin_url)), 'input_doc_root' => array('size' => 55, 'label' => '<br />' . $this->_get_input_doc_root_label()), 'input_cache_dir' => array('size' => 55, 'label' => '<br />' . sprintf(__('Expect a full path to a publicly accessible directory ' . '(i.e. can be served under your document root). <br />' . 'Leave empty to use default value, which is <code>%s</code>.<br />' . 'Cache directory must be writable ' . '(i.e. CHMOD to 755 or 777). ' . 'More details can be found ' . '<a href="%s#minify_cache_directory" target="_blank">here</a>. ', $this->domain), $this->get_default_cache_dir(), $this->plugin_url)), 'input_maxfiles' => array('size' => 3, 'label' => __('file(s) at most.', $this->domain)), 'input_maxage' => array('size' => 5, 'label' => __('&mdash;', $this->domain)), 'input_custom_buster' => array('pre' => '<em>&rarr; /min/?f=file.js&#038;ver=</em> ', 'size' => 12, 'label' => '.', 'disabled' => ' disabled="disabled"')), 'textarea' => array('input_symlinks' => array('cols' => 90, 'rows' => 5)), 'container' => array('select_buster_type' => '<em><strong>' . __('Note', $this->domain) . ':</strong> ' . __('Whenever a new cache buster is used, ' . 'you are telling browsers to refresh cached JS and CSS files. ' . 'This is particularly useful when source files have been changed, ' . 'use this feature wisely.', $this->domain) . '</em>'), 'inline_fields' => array('input_maxage' => array('select_time_type' => 'select'), 'select_buster_type' => array('input_custom_buster' => 'input')), 'role' => array('input_minpath' => 'superadmin', 'h2' => 'superadmin', 'input_doc_root' => 'superadmin', 'input_cache_dir' => 'superadmin', 'input_maxage' => 'superadmin', 'select_time_type' => 'superadmin', 'cb4' => 'superadmin', 'cb5' => 'superadmin', 'cb6' => 'superadmin'));
             // Get a subset of the option array for this form
             $form_options = array('input_minurl', 'input_minpath', 'input_cache_dir', 'input_doc_root', 'input_maxfiles', 'input_maxage', 'input_custom_buster', 'enable_min_js', 'enable_min_css', 'enable_external_origin', 'enable_bloginfo', 'enable_css_bubble', 'enable_cache_file_lock', 'enable_debug', 'select_buster_type', 'select_time_type');
             // Flush the cache
             if ((isset($_POST['flush_cache']) || isset($_POST['save_flush'])) && !self::is_normal_admin()) {
                 check_admin_referer($page);
                 $deleted = $this->_flush_cache();
                 if (0 < $deleted) {
                     $this->add_notice('<strong>' . __('Notice', $this->domain) . ':</strong> ' . sprintf(__("<strong>%d</strong> cached files " . "have been deleted successfully!", $this->domain), $deleted));
                 } else {
                     $this->add_notice('<strong>' . __('Notice', $this->domain) . ':</strong> ' . __("Could not delete any cached files. " . "Please manually flush the cache directory.", $this->domain));
                 }
                 // this should also clear all saved Minify groups
                 $this->detector->clear_logs('group');
             }
         } else {
             if ($page == BWP_MINIFY_OPTION_ADVANCED) {
                 $bwp_option_page->set_current_tab(2);
                 $form = array('items' => array('heading', 'checkbox', 'input', 'input', 'heading', 'checkbox', 'select', 'input', 'input', 'input', 'textarea'), 'item_labels' => array(__('Friendly Minify Urls', $this->domain), __('Enable friendly Minify urls', $this->domain), sprintf(__('Friendly Minify url path (relative to ' . 'your Site/Network Address). More info <a href="%s#friendly_minify_urls" ' . 'target="_blank">here</a>.', $this->domain), $this->plugin_url), __('Path to Nginx config file', $this->domain), __('Content Delivery Network (CDN)', $this->domain), __('Enable CDN support', $this->domain), __('SSL support for CDN', $this->domain), __('CDN hostname (primary)', $this->domain), __('CDN hostname for JS files', $this->domain), __('CDN hostname for CSS files', $this->domain), __('Additional HTTP headers used with CDN', $this->domain)), 'item_names' => array('h1', 'cb1', 'input_fly_minpath', 'input_nginx_config_file', 'h2', 'cb2', 'select_cdn_ssl_type', 'input_cdn_host', 'input_cdn_host_js', 'input_cdn_host_css'), 'heading' => array('h1' => '<em>' . sprintf(__('Turn long and ugly Minify urls with ' . 'query variables (such as <code>%s</code>), ' . 'into more friendly ones (e.g. <code>%s</code>). ' . '', $this->domain), trailingslashit($this->min_url) . '?f=path/to/script1.js,path/to/script2.js', home_url('path/to/cache/somestring.js')) . '</em>', 'h2' => '<em>' . sprintf(__('Serve minified contents ' . 'using a <a href="%s" target="_blank">CDN</a> to improve performance.', $this->domain), $this->get_url('wikipedia_cdn')) . '</em>'), 'select' => array('select_fly_serve_method' => array(__('WordPress', $this->domain) => 'wp', __('Server rewrite rules', $this->domain) => 'server'), 'select_cdn_ssl_type' => array(__('Do not use SSL for CDN', $this->domain) => 'off', __('Use SSL when suitable', $this->domain) => 'on', __('Use protocol-relative URL', $this->domain) => 'less')), 'checkbox' => array('cb1' => array(__('for CDN support it is highly recommended that you enable this feature.', $this->domain) => 'enable_fly_min'), 'cb2' => array(__('please make sure that your CDN is property setup before enabling this feature.', $this->domain) => 'enable_cdn')), 'input' => array('input_fly_minpath' => array('size' => 55, 'label' => $this->_get_input_fly_min_path_label()), 'input_nginx_config_file' => array('size' => 55, 'label' => '<br />' . sprintf(__('Expect a full path to your Nginx ' . 'configuration file (e.g. <code>%s</code>). ' . 'If none specified or the config file ' . 'is not writable, you will have to manually update it. ' . 'Alternatively, if you have a config file ' . 'at <code>%s</code>, which is used by W3 Total Cache ' . 'plugin, you can leave this field blank and ' . 'BWP Minify will use that config file.', $this->domain), '/path/to/nginx.conf', $this->get_doc_root('nginx.conf'))), 'input_cdn_host' => array('size' => 40, 'label' => '<br />' . sprintf(__('Use either hostnames provided by your ' . 'CDN or custom ones. Please do NOT include ' . 'the scheme (i.e. <code>http://</code> or <code>https://</code>). ' . 'Good examples are: <code>%s</code>, <code>%s</code>, etc.', $this->domain), 'yourzone.yourcdn.com', 'cdn.yourdomain.com')), 'input_cdn_host_js' => array('size' => 40, 'label' => '&nbsp; ' . __('used when not empty.', $this->domain)), 'input_cdn_host_css' => array('size' => 40, 'label' => '&nbsp; ' . __('used when not empty.', $this->domain))), 'textarea' => array('input_cdn_headers' => array('')), 'container' => array('cb2' => '<p style="margin-left:220px;"><em>' . __('If you\'re looking for a CDN, I highly recommend ' . '<strong>MaxCDN</strong>. They provide the most reliable CDN service ' . 'for WordPress sites. Support is exceptional and ' . 'you got a 30-day Money Back Guarantee, too.', $this->domain) . '</em><br />' . '<a href="#" target="_blank" class="button-secondary" style="margin-top:10px;" ' . 'onclick="this.href=\'' . $this->get_url('aff_maxcdn') . '\';">' . __('Create a MaxCDN account today and save 25%</a>', $this->domain) . '</p>'), 'post' => array(), 'role' => array('input_fly_minpath' => 'superadmin'));
                 $form_options = array();
             } else {
                 if ($page == BWP_MINIFY_MANAGE) {
                     $bwp_option_page->set_current_tab(3);
                     remove_action('bwp_option_action_before_form', array($this, 'show_donation'), 12);
                     // add a secondary button to clear enqueued file lists (both)
                     add_filter('bwp_option_submit_button', array($this, 'add_clear_enqueue_button'));
                     if (isset($_POST['clear_enqueue'])) {
                         check_admin_referer($page);
                         $this->detector->clear_logs('enqueue');
                         $this->add_notice(__('Enqueued file lists have been cleared successfully. ' . 'Try refreshing this page to see updated file lists.', $this->domain));
                     }
                     $form = array('items' => array('heading', 'heading'), 'item_labels' => array(__('Manage enqueued JS files', $this->domain), __('Manage enqueued CSS files', $this->domain)), 'item_names' => array('h1', 'h2'), 'heading' => array('h1' => '<em>' . sprintf(__('Below you can find a list of enqueued JS files ' . 'detected by this plugin. Press <strong>select</strong> and ' . 'then choose to perform an appropriate action on selected JS file. ' . 'You can also directly type in one script handle (<strong>NOT ' . 'filename/script src</strong>) per line in the input field if ' . 'you want. More info <a href="%s#manage_enqueued_files" target="_blank">here</a>.', $this->domain), $this->plugin_url) . '</em>', 'h2' => '<em>' . sprintf(__('Below you can find a list of enqueued CSS files ' . 'detected by this plugin. Press <strong>select</strong> and ' . 'then choose to perform an appropriate action on selected CSS file. ' . 'You can also directly type in one style handle (<strong>NOT ' . 'filename/style src</strong>) per line in the input field if ' . 'you want. More info <a href="%s#manage_enqueued_files" target="_blank">here</a>.', $this->domain), $this->plugin_url) . '</em>'), 'container' => array('h1' => $this->_show_enqueued_scripts(), 'h2' => $this->_show_enqueued_styles()));
                     // Get a subset of the option array for this form
                     $form_options = array('input_ignore', 'input_header', 'input_direct', 'input_footer', 'input_oblivion', 'input_style_ignore', 'input_style_direct', 'input_style_oblivion');
                 }
             }
         }
     }
     $option_formats = array('input_maxfiles' => 'int', 'input_maxage' => 'int', 'select_time_type' => 'int');
     $option_super_admin = $this->site_options;
     // Get option from user input
     if ((isset($_POST['submit_' . $bwp_option_page->get_form_name()]) || isset($_POST['save_flush']) && $page == BWP_MINIFY_OPTION_GENERAL && !self::is_normal_admin()) && isset($options) && is_array($options)) {
         // basic security check
         check_admin_referer($page);
         foreach ($options as $key => &$option) {
             if (0 < sizeof($form_options) && !in_array($key, $form_options) || self::is_normal_admin() && in_array($key, $option_super_admin)) {
                 // field not found in options assigned to current form
                 // OR not a super admin, and this is a super-admin only setting
                 continue;
             } else {
                 if (isset($_POST[$key])) {
                     // make sure inputs are in expected format
                     $bwp_option_page->format_field($key, $option_formats);
                     $option = trim(stripslashes($_POST[$key]));
                 }
                 if (!isset($_POST[$key]) && !isset($form['input'][$key]['disabled'])) {
                     // checkbox, exclude disabled input
                     $option = '';
                 } else {
                     if (isset($option_formats[$key]) && 'int' == $option_formats[$key] && ('' === $_POST[$key] || 0 > $_POST[$key])) {
                         // expect integer but received empty string or negative integer
                         $option = $this->options_default[$key];
                     }
                 }
             }
         }
         // update per-blog options
         update_option($active_page, $options);
         // if current user is super admin, allow him to update site-only
         // options - this is WPMS compatible
         if (!self::is_normal_admin()) {
             update_site_option($active_page, $options);
         }
         // refresh the options property to include updated options
         $this->options = array_merge($this->options, $options);
         // success messages when settings are saved
         if ($page == BWP_MINIFY_MANAGE) {
             $this->detector->auto_detect();
             $this->add_notice(__('All positions have been saved. ' . 'Try refreshing this page for updated file lists.', $this->domain));
         } else {
             $this->add_notice(__('All options have been saved.', $this->domain));
         }
         // take care of some custom POST actions when form is submitted,
         // when multisite is active, only do this when the user is a superadmin
         if ($page == BWP_MINIFY_OPTION_GENERAL) {
             // other actions for the general option page
             if ($original_options['enable_min_js'] != $this->options['enable_min_js'] || $original_options['enable_min_css'] != $this->options['enable_min_css']) {
                 // @since 1.3.2 changed plugin functionality, clear the log
                 $this->detector->clear_logs();
             }
             if (!self::is_normal_admin()) {
                 // try to save the Minify config file
                 $result = $this->create_minify_config_file();
                 if (true === $result) {
                     // config file was successfully written
                     $this->add_notice(sprintf(__('Minify config file <code>%s</code> ' . 'has been updated successfully.', $this->domain), $this->min_dir . 'config.php'));
                 } else {
                     if ('config' === $result) {
                         // config file is missing
                         $this->add_error('<strong style="color:red">' . __('Error') . ':</strong> ' . sprintf(__('Minify config file <code>config.php</code> could not be found. ' . 'The auto-detected directory to look for the config file is <code>%s</code>. ' . 'Please manually check if that directory actually exists ' . 'and contains the config file.', $this->domain), $this->get_doc_root($this->get_min_path())));
                     } else {
                         if ('put' === $result) {
                             // the write process failed for some reasons
                             $this->add_error(sprintf('<strong style="color:red">' . __('Error') . ':</strong> ' . __('There was an error writing to Minify config file <code>%s</code>. ' . 'Please try again.', $this->domain), $this->min_dir . 'config.php'));
                         } else {
                             // config file is not writable, show the auto-generated
                             // contents to admin for manual update
                             $this->add_notice(sprintf('<strong>' . __('Notice', $this->domain) . ':</strong> ' . __('Minify config file <code>%s</code> ' . 'is not writable. See ' . '<a href="#minify.config.php">below</a> ' . 'for details.', $this->domain), $this->min_dir . 'config.php'));
                             $form['container']['h2'] = $this->_show_generated_config($result);
                         }
                     }
                 }
             }
         } else {
             if ($page == BWP_MINIFY_OPTION_ADVANCED) {
                 // friendly minify url is turned on, add rewrite rules to
                 // server directory config file (e.g. `.htaccess`). This should
                 // not require WordPress's pretty permalink to be turned on
                 if ('yes' != $original_options['enable_fly_min'] && 'yes' == $this->options['enable_fly_min']) {
                     $this->_toggle_rewrite_rules($options, $form);
                 } else {
                     if ('yes' == $original_options['enable_fly_min'] && 'yes' != $this->options['enable_fly_min']) {
                         // remove the rules and flush cache if this setting is
                         // turned off, ingore all error messages for now
                         $this->_remove_rewrite_rules();
                         $this->_flush_cache();
                     }
                 }
             }
         }
     }
     if ($page == BWP_MINIFY_OPTION_GENERAL) {
         // take care of non-POST actions when we're on General Options page
         // re-generate the buster string preview whenever buster type change
         $options['input_custom_buster'] = $this->get_buster($options['select_buster_type']);
         if ('custom' == $options['select_buster_type']) {
             unset($form['input']['input_custom_buster']['disabled']);
         }
         // warns admin that the cache directory does not exist or is not writable
         if (!self::is_normal_admin()) {
             $cache_dir = $this->get_cache_dir();
             if (!file_exists($cache_dir)) {
                 $this->add_notice('<strong>' . __('Warning') . ':</strong> ' . sprintf(__("Cache directory <code>%s</code> does not exist " . "and can not be created automatically. " . "Please manually create the cache folder " . "and make sure that it is writable " . "for Minify to perform more efficiently.", $this->domain), $cache_dir));
             } else {
                 if (!is_writable($cache_dir)) {
                     $this->add_notice('<strong>' . __('Warning') . ':</strong> ' . sprintf(__("Cache directory <code>%s</code> is not writable. " . "Please try CHMOD your cache directory to 755. " . "If you still see this warning, try CHMOD to 777.", $this->domain), $cache_dir));
                 }
             }
         }
     } else {
         if ($page == BWP_MINIFY_OPTION_ADVANCED) {
             // Also remove nginx config path if not on nginx server
             if (!self::is_nginx() || self::is_normal_admin()) {
                 $bwp_option_page->kill_html_fields($form, array('input_nginx_config_file'));
             }
             // Append rewrite rules to the form when fly min is enabled, only
             // for superadmin
             if ($this->options['enable_fly_min'] == 'yes' && !self::is_normal_admin()) {
                 $this->_append_fly_rewrite_rules_to_form($form);
             }
         }
     }
     /* // check for rewrite rules if needed, suppress error */
     /* if ('yes' == $this->options['enable_fly_min']) */
     /* 	$this->_add_rewrite_rules(); */
     // Assign the form and option array
     $bwp_option_page->init($form, $options, $this->form_tabs);
     // Build the option page
     echo $bwp_option_page->generate_html_form();
 }