/**
  * 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();
 }
 /**
  * Build the option pages
  *
  * Utilizes BWP Option Page Builder (@see BWP_OPTION_PAGE)
  */
 public function build_option_pages()
 {
     if (!current_user_can(BWP_CAPT_CAPABILITY)) {
         wp_die(__('You do not have sufficient permissions to access this page.'));
     }
     $page = $_GET['page'];
     $bwp_option_page = new BWP_OPTION_PAGE($page, $this->site_options, $this->domain);
     $options = array();
     if (!empty($page)) {
         if ($page == BWP_CAPT_OPTION_GENERAL) {
             $bwp_option_page->set_current_tab(1);
             // Option Structures - Form
             $form = array('items' => array('heading', 'checkbox', 'input', 'input', 'heading', 'section', 'section', 'heading', 'select', 'select', 'input', 'input', 'heading', 'checkbox', 'select', 'heading', 'select'), 'item_labels' => array(__('reCAPTCHA API Keys', $this->domain), __('Use main site\'s keys', $this->domain), __('Public Key', $this->domain), __('Private Key', $this->domain), __('Plugin Functionality', $this->domain), __('Enable this plugin for', $this->domain), __('Hide captcha for', $this->domain), __('reCAPTCHA for comment form', $this->domain), __('Captcha position', $this->domain), __('If invalid captcha response', $this->domain), __('Invalid captcha error message', $this->domain), __('Invalid captcha error message', $this->domain), __('Akismet Integration for comment form', $this->domain), __('Integrate with Akismet?', $this->domain), __('If correct captcha response', $this->domain), __('Contact Form 7 Integration', $this->domain), __('Captcha shortcode tag', $this->domain)), 'item_names' => array('h1', 'cb7', 'input_pubkey', 'input_prikey', 'heading_func', 'sec1', 'sec2', 'h2', 'select_position', 'select_response', 'input_error', 'input_back', 'h3', 'cb6', 'select_akismet_react', 'heading_cf7', 'select_cf7_tag'), 'heading' => array('h1' => '<em>' . sprintf(__('For this plugin to work, you will need ' . 'a pair of API keys (public and private), ' . 'which is available for free <a href="%s" target="_blank">here</a>. ' . 'Once you have created those two keys for this domain, ' . 'simply paste them below.</em>', $this->domain), 'https://www.google.com/recaptcha/admin/create'), 'heading_func' => '<em>' . __('Control how this plugin works.', $this->domain) . '</em>', 'h2' => '<em>' . __('Settings that are applied to ' . 'comment forms only.', $this->domain) . '</em>', 'h3' => '<em>' . __('Integrate with Akismet for better end-user experience.', $this->domain) . '</em>', 'heading_cf7' => '<em>' . __('Add reCAPTCHA to Contact Form 7. ' . 'This only works if you have Contact Form 7 activated.', $this->domain) . '</em>'), 'sec1' => array(array('checkbox', 'name' => 'cb1'), array('checkbox', 'name' => 'cb2'), array('checkbox', 'name' => 'cb8')), 'sec2' => array(array('checkbox', 'name' => 'cb3'), array('checkbox', 'name' => 'cb4'), array('checkbox', 'name' => 'cb5')), 'select' => array('select_lang' => $this->lang, 'select_cap' => $this->caps, 'select_position' => array(__('After comment field', $this->domain) => 'after_comment_field', __('After form fields (name, email, website)', $this->domain) => 'after_fields'), 'select_response' => array(__('Redirect commenter back to the comment form with error message', $this->domain) => 'redirect', __('Show an error page just like WordPress does', $this->domain) => 'back'), 'select_akismet_react' => array(__('Approve comment immediately', $this->domain) => '1', __('Hold comment in moderation queue', $this->domain) => 'hold'), 'select_cf7_tag' => array(__('Use "bwp-recaptcha" shortcode tag', $this->domain) => 'bwp-recaptcha', __('Use "recaptcha" shortcode tag', $this->domain) => 'recaptcha')), 'checkbox' => array('cb1' => array(__('Comment form.', $this->domain) => 'enable_comment'), 'cb2' => array(__('Registration form (user/site registration).', $this->domain) => 'enable_registration'), 'cb8' => array(__('Login form.', $this->domain) => 'enable_login'), 'cb3' => array(__('registered users <em>(even without any capabilities)</em>.', $this->domain) => 'hide_registered'), 'cb4' => array(__('users who can', $this->domain) => 'hide_cap'), 'cb5' => array(__('visitors who have at least', $this->domain) => 'hide_approved'), 'cb6' => array(__('A captcha is only shown when Akismet identifies a comment as spam. ' . 'Highly recommended if you do not want to ' . 'force your visitors to enter a captcha every time.', $this->domain) => 'enable_akismet'), 'cb7' => array(__('uncheck to use different key pairs for this site.', $this->domain) => 'use_global_keys')), 'input' => array('input_pubkey' => array('size' => 50, 'label' => '<br />' . __('A public key used to ' . 'request captchas from reCAPTCHA server.', $this->domain)), 'input_prikey' => array('size' => 50, 'label' => '<br />' . __('A private (secret) key used to ' . 'authenticate user\'s response.', $this->domain)), 'input_error' => array('size' => 90), 'input_back' => array('size' => 90), 'input_approved' => array('size' => 3, 'label' => __('approved comment(s).', $this->domain))), 'container' => array('cb8' => ''), 'post' => array('select_akismet_react' => '<br /><span style="display:inline-block;margin-top:5px;">' . __('It is best to put comments identified as spam in moderation queue ' . 'so you are able to review and instruct ' . 'Akismet to correctly handle similar comments in the future.</em>', $this->domain) . '</span>'), 'inline_fields' => array('cb4' => array('select_cap' => 'select'), 'cb5' => array('input_approved' => 'input')));
             // Get the default options
             $options = $bwp_option_page->get_options(array('use_global_keys', 'input_pubkey', 'input_prikey', 'input_error', 'input_approved', 'select_cap', 'hide_registered', 'hide_cap', 'hide_approved', 'enable_registration', 'enable_login', 'enable_comment', 'input_back', 'select_position', 'select_cf7_tag', 'select_response', 'enable_akismet', 'select_akismet_react'), $this->options);
             // Get option from the database
             $options = $bwp_option_page->get_db_options($page, $options);
             $option_formats = array('input_approved' => 'int', 'input_error' => 'html', 'input_back' => 'html');
             $option_super_admin = array();
             // show appropriate fields based on multi-site setting
             add_action('bwp_option_action_before_submit_button', array($this, 'modify_option_page'));
         } else {
             if ($page == BWP_CAPT_OPTION_THEME) {
                 $bwp_option_page->set_current_tab(2);
                 // Option Structures - Form
                 $form = array('items' => array('select', 'checkbox', 'select', 'input', 'heading'), 'item_labels' => array(__('reCAPTCHA theme', $this->domain), __('Use default CSS', $this->domain), __('Language for built-in themes', $this->domain), __('Tabindex for captcha input field', $this->domain), __('Preview your reCAPTCHA', $this->domain)), 'item_names' => array('select_theme', 'cb1', 'select_lang', 'input_tab', 'h1'), 'heading' => array('h1' => __('<em>Below you will see how your reCAPTCHA will look. ' . 'Note that this might differ on your actual pages.<br /></em>', $this->domain)), 'select' => array('select_theme' => array(__('Default Theme (Red)', $this->domain) => 'red', __('White Theme', $this->domain) => 'white', __('Black Theme', $this->domain) => 'blackglass', __('Clean Theme', $this->domain) => 'clean', __('Custom Theme (use CSS)', $this->domain) => 'custom'), 'select_lang' => $this->lang), 'checkbox' => array('cb1' => array(sprintf(__('This is for Custom Theme only. ' . 'Disable this and add your own CSS to style the Custom Theme. ' . 'More info <a href="%s#customization" target="_blank">here</a>.', $this->domain), BWP_CAPT_PLUGIN_URL) => 'enable_css'), 'cb2' => array(__('This is only useful when you do not use any minify or cache plugin.', $this->domain) => 'enable_selective')), 'input' => array('input_tab' => array('size' => 3, 'label' => '<br />' . __('This should be 4 if you ' . 'place the captcha before the textarea, ' . 'and 5 if you put it after. Set to 0 to disable.', $this->domain))), 'container' => array(), 'post' => array('select_lang' => sprintf(__('If you would like to add custom translations, ' . 'please read <a href="%s" target="_blank">this dedicated tip</a>.', $this->domain), 'http://betterwp.net/wordpress-tips/how-to-add-custom-translations-to-bwp-recaptcha/')));
                 // Get the default options
                 $options = $bwp_option_page->get_options(array('select_lang', 'select_theme', 'input_tab', 'enable_css'), $this->options);
                 // Get option from the database
                 $options = $bwp_option_page->get_db_options($page, $options);
                 $option_formats = array('input_tab' => 'int');
                 $option_super_admin = array();
                 // preview reCAPTCHA
                 add_action('bwp_option_action_before_submit_button', array($this, 'add_recaptcha'));
             }
         }
     }
     // Get option from user input
     if (isset($_POST['submit_' . $bwp_option_page->get_form_name()]) && isset($options) && is_array($options)) {
         // basic security check
         check_admin_referer($page);
         foreach ($options as $key => &$option) {
             if (isset($_POST[$key])) {
                 $bwp_option_page->format_field($key, $option_formats);
                 $option = trim(stripslashes($_POST[$key]));
             } else {
                 if (!isset($_POST[$key])) {
                     // for checkboxes that are not checked
                     $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($page, $options);
         global $blog_id;
         if (!$this->is_normal_admin() && $blog_id == 1) {
             // Update site options if is super admin and is on main site
             update_site_option($page, $options);
         }
         // refresh the options property to include updated options
         $this->options = array_merge($this->options, $options);
         // Update options successfully
         $this->add_notice(__('All options have been saved.', $this->domain));
     }
     if (empty($this->options['input_pubkey']) || empty($this->options['input_prikey'])) {
         // add notices if recaptcha API keys are missing
         $this->add_notice('<strong>' . __('Warning') . ':</strong> ' . sprintf(__('API key(s) missing. Please get an API key from ' . '<a href="%1$s">%1$s</a> (free!)', $this->domain), 'https://www.google.com/recaptcha/admin/create'));
     }
     if ('yes' == $this->options['enable_akismet'] && !defined('AKISMET_VERSION')) {
         // add a notice if Akismet integration is enabled but Akismet
         // plugin is not installed
         $this->add_notice('<strong>' . __('Notice') . ':</strong> ' . __('You are enabling Akismet integration but Akismet is not currently active. ' . 'Please activate Akismet for the integration to work.', $this->domain));
     }
     // Assign the form and option array
     $bwp_option_page->init($form, $options, $this->form_tabs);
     // Build the option page
     $bwp_option_page->generate_html_form();
 }
 /**
  * Build the option pages
  *
  * Utilizes BWP Option Page Builder (@see BWP_OPTION_PAGE)
  */
 public function build_option_pages()
 {
     if (!current_user_can(BWP_GXS_CAPABILITY)) {
         wp_die(__('You do not have sufficient permissions to access this page.'));
     }
     // Init the class
     $page = $_GET['page'];
     $bwp_option_page = new BWP_OPTION_PAGE($page, $this->site_options);
     $options = array();
     $dynamic_options = array();
     if (!empty($page)) {
         if ($page == BWP_GXS_OPTION_GENERATOR) {
             $bwp_option_page->set_current_tab(1);
             if (!self::is_normal_admin()) {
                 // add flush cache buttons for super admins
                 // @todo allow normal admins to flush the cache as well,
                 // but only for sitemaps on their sites
                 add_filter('bwp_option_submit_button', array($this, 'add_flush_cache_buttons'));
                 if (isset($_POST['flush_cache'])) {
                     check_admin_referer($page);
                     $this->_admin_flush_cache();
                 }
             }
             // add a clear log button
             add_filter('bwp_option_submit_button', array($this, 'add_clear_log_button'));
             if (isset($_POST['clear_log'])) {
                 // clear all sitemap logs including sitemap generation log
                 // and sitemap item log
                 check_admin_referer($page);
                 $this->logs = array('log' => array(), 'sitemap' => array());
                 $this->commit_logs();
                 $this->add_notice('<strong>' . __('Notice', $this->domain) . ':</strong> ' . __('All logs have been cleared successfully!', $this->domain));
             }
             $form = array('items' => array('heading', 'heading', 'section', 'section', 'section', 'heading', 'input', 'checkbox', 'input', 'heading', 'select', 'select', 'select', 'checkbox', 'checkbox', 'heading', 'checkbox', 'input', 'checkbox', 'checkbox', 'heading', 'checkbox', 'checkbox', 'heading', 'checkbox', 'section', 'section', 'input', 'heading', 'checkbox', 'checkbox', 'input', 'input', 'heading', 'input', 'input', 'heading', 'checkbox', 'checkbox', 'checkbox'), 'item_labels' => array(__('Your sitemaps', $this->domain), __('Sitemaps to generate', $this->domain), __('<strong>Enable</strong> following sitemaps', $this->domain), __('For post-based sitemaps, <strong>disable</strong> following post types:', $this->domain), __('For taxonomy-based sitemaps, <strong>disable</strong> following taxonomies:', $this->domain), __('Item limits', $this->domain), __('Global limit', $this->domain), __('Split <strong>post-based</strong> sitemaps', $this->domain), __('Split limit', $this->domain), __('Default values & Formatting', $this->domain), __('Default change frequency', $this->domain), __('Default priority', $this->domain), __('Minimum priority', $this->domain), __('Use GMT for Last Modified date', $this->domain), __('Compress sitemaps', $this->domain), __('Look and Feel', $this->domain), __('Make sitemaps look pretty', $this->domain), __('Custom XSLT stylesheet URL', $this->domain), __('Enable build stats', $this->domain), __('Enable credit', $this->domain), __('Virtual robots.txt', $this->domain), __('Add a sitemapindex entry to blog\'s robots.txt', $this->domain), __('Add sitemapindex entries from all blogs to primary blog\'s robots.txt', $this->domain), __('Ping search engines', $this->domain), __('Enable pinging', $this->domain), __('Search engines to ping', $this->domain), __('<strong>Disable pinging</strong> for following post types:', $this->domain), __('Ping limit for each search engine', $this->domain), __('Caching', $this->domain), __('Enable caching', $this->domain), __('Enable auto cache re-generation', $this->domain), __('Cache expiry time', $this->domain), __('Cache directory', $this->domain), __('Sitemap modules', $this->domain), __('Database query limit', $this->domain), __('Custom module directory', $this->domain), htmlspecialchars(__('Sitemap log & debug', $this->domain)), __('Enable sitemap log', $this->domain), __('Enable debug mode', $this->domain), __('Enable debug extra mode', $this->domain)), 'item_names' => array('heading_submit', 'heading_contents', 'sec_index', 'sec_post', 'sec_tax', 'heading_limit', 'input_item_limit', 'cb_enable_split', 'input_split_limit_post', 'heading_format', 'select_default_freq', 'select_default_pri', 'select_min_pri', 'cb14', 'cb_enable_gzip', 'heading_look', 'cb10', 'input_custom_xslt', 'cb3', 'cb6', 'heading_robot', 'cb_index_to_blog', 'cb_index_to_primary', 'heading_ping', 'cb_ping', 'cb_ping_list', 'sec_post_ping', 'input_ping_limit', 'heading_cache', 'cb_enable_cache', 'cb_enable_autogen', 'input_cache_age', 'input_cache_dir', 'heading_module', 'input_sql_limit', 'input_alt_module_dir', 'heading_debug', 'cb_log', 'cb_debug', 'cb_debug_extra'), 'heading' => array('heading_submit' => '', 'heading_contents' => '<em>' . sprintf(__('Choose appropriate sitemaps to generate. ' . 'For each sitemap, you can use filters to further ' . '<a href="%s#exclude_items" target="_blank">exclude items</a> ' . 'you do not need.', $this->domain), $this->plugin_url) . '</em>', 'heading_limit' => '<em>' . __('Limit the number of items to output in one sitemap. ', $this->domain) . sprintf(__('Avoid setting too high limits, i.e. ones that your server ' . 'can not handle. In such case, you might encounter white page error ' . 'due to timeout or memory issue. ' . 'Refer to this plugin\'s <a target="_blank" href="%s">FAQ section</a> for more info.', $this->domain), $this->plugin_url . 'faq/') . '</em>', 'heading_format' => '<em>' . __('Customize default values and some formating for your sitemaps. ' . 'Default values are only used when valid ones can not ' . 'be calculated.', $this->domain) . '</em>', 'heading_look' => '<em>' . __('Customize the look and feel of your sitemaps. ' . 'Note that an XSLT stylesheet will NOT be used ' . 'for the Google News Sitemap module ' . 'regardless of any setting in this section.', $this->domain) . '</em>', 'heading_robot' => '<em>' . sprintf(__('WordPress generates a %svirtual robots.txt%s ' . 'file for your blog by default. ' . 'You can add links to sitemapindex files generated by this plugin ' . 'to that robots.txt file using settings below.', $this->domain), !self::is_multisite() || self::is_subdomain_install() ? '<a href="' . home_url('robots.txt') . '" target="_blank">' : '', !self::is_multisite() || self::is_subdomain_install() ? '</a>' : '') . '</em>', 'heading_ping' => '<em>' . __('Whenever you post something new to your blog, ' . 'you can <em>ping</em> search engines with your sitemapindex ' . 'to tell them your blog just got updated.', $this->domain) . '</em>', 'heading_cache' => '<em>' . __('Cache your sitemaps for better performance. ' . 'If you are still configuring the plugin it\'s best to ' . 'disable caching or you might have to manually flush the cache ' . 'for any changes to show up.', $this->domain) . '</em>', 'heading_module' => '<em>' . sprintf(__('Extend this plugin using customizable modules. ' . 'More info <a href="%s#module_api">here</a>.', $this->domain), $this->plugin_url) . '</em>', 'heading_debug' => ''), 'sec_index' => array(array('checkbox', 'name' => 'cb17'), array('checkbox', 'name' => 'cb7'), array('checkbox', 'name' => 'cb9'), array('checkbox', 'name' => 'cb16'), array('checkbox', 'name' => 'cb13')), 'sec_post' => array(), 'sec_post_ping' => array(), 'sec_tax' => array(), 'cb_ping_list' => array(array('checkbox', 'name' => 'cb_ping_google'), array('checkbox', 'name' => 'cb_ping_bing')), '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_oldest_type' => array(__('second(s)', $this->domain) => 1, __('minute(s)', $this->domain) => 60, __('hour(s)', $this->domain) => 3600, __('day(s)', $this->domain) => 86400), 'select_default_freq' => array(), 'select_default_pri' => $this->priorities, 'select_min_pri' => $this->priorities), 'post' => array('select_default_freq' => sprintf('<a href="%s" target="_blank">' . __('read more', $this->domain) . '</a>', 'http://sitemaps.org/protocol.php#xmlTagDefinitions'), 'select_default_pri' => sprintf('<a href="%s" target="_blank">' . __('read more', $this->domain) . '</a>', 'http://sitemaps.org/protocol.php#xmlTagDefinitions'), 'select_min_pri' => sprintf('<a href="%s" target="_blank">' . __('read more', $this->domain) . '</a>', 'http://sitemaps.org/protocol.php#xmlTagDefinitions')), 'checkbox' => array('cb_enable_cache' => array(__('Your sitemaps are generated and then cached to reduce unnecessary work.', $this->domain) => 'enable_cache'), 'cb_enable_autogen' => array(__('Re-generate sitemap cache when expired. If you disable this, remember to manually flush the cache once in a while.', $this->domain) => 'enable_cache_auto_gen'), 'cb3' => array(__('print useful information such as build time, memory usage, SQL queries, etc.', $this->domain) => 'enable_stats'), 'cb_enable_gzip' => array(__('Use gzip to make sitemaps ~70% smaller. If you see an error after enabling this, it\'s very likely that you have gzip active on your server already.', $this->domain) => 'enable_gzip'), 'cb_index_to_primary' => array(sprintf(__('If you have for example 50 blogs, 50 sitemapindex entries will be added to your primary blog\'s <a href="%s" target="_blank">robots.txt</a>.', $this->domain), get_site_option('home') . '/robots.txt') => 'enable_global_robots'), 'cb7' => array(__('Taxonomy (including custom taxonomies).', $this->domain) => 'enable_sitemap_taxonomy'), 'cb9' => array(__('Date archives.', $this->domain) => 'enable_sitemap_date'), 'cb16' => array(__('Author archives.', $this->domain) => 'enable_sitemap_author'), 'cb13' => array(sprintf(__('External pages. More info <a href="%s#external_sitemap" target="_blank">here</a>.', $this->domain), $this->plugin_url) => 'enable_sitemap_external'), 'cb6' => array(__('some copyrighted info is also added to your sitemaps. Thanks!', $this->domain) => 'enable_credit'), 'cb10' => array(__('Default XSLT stylesheets will be used. Set your custom stylesheets below or filter the <code>bwp_gxs_xslt</code> hook.', $this->domain) => 'enable_xslt'), 'cb_index_to_blog' => array(sprintf(__('If you\'re on a Multi-site installation with <strong>Sub-domain</strong> enabled, each blog will have its own robots.txt. Blogs in <strong>sub-directory</strong> will not, however. Please read the <a href="%s#robots.txt" target="_blank">documentation</a> for more info.', $this->domain), $this->plugin_url) => 'enable_robots'), 'cb_enable_split' => array(__('Sitemaps like <code>post.xml</code> are split into <code>post_part1.xml</code>, <code>post_part2.xml</code>, etc. when limit reached.', $this->domain) => 'enable_sitemap_split_post'), 'cb14' => array(__('Disable this to use the local timezone setting in <em>Settings >> General</em>.', $this->domain) => 'enable_gmt'), 'cb17' => array(__('Site Address. For a multi-site installation of WordPress, this sitemap will list all appropriate blogs\' addresses within your network, not just the main blog\'s.', $this->domain) => 'enable_sitemap_site'), 'cb_ping' => array(__('Ping search engines when you publish new posts. By default all public posts are considered, unless explicitly disabled below.', $this->domain) => 'enable_ping'), 'cb_ping_google' => array(__('Google', $this->domain) => 'enable_ping_google'), 'cb_ping_bing' => array(__('Bing', $this->domain) => 'enable_ping_bing'), 'cb_log' => array(sprintf(__('No additional load is needed so enabling this is highly recommended. You can check the log <a href="%s">here</a>.', $this->domain), $this->get_admin_page(BWP_GXS_STATS)) => 'enable_log'), 'cb_debug' => array(__('When this is on, NO caching is used and <code>WP_DEBUG</code> is respected, useful when developing new modules.', $this->domain) => 'enable_debug'), 'cb_debug_extra' => array(sprintf(__('When this is on, NO headers are sent and sitemaps are NOT compressed, useful when debugging <em>Content Encoding Error</em>. More info <a href="%s#sitemap_log_debug" target="_blank">here</a>.', $this->domain), $this->plugin_url) => 'enable_debug_extra')), 'input' => array('input_item_limit' => array('size' => 5, 'label' => __('Maximum is <strong>50,000</strong>. ' . 'This setting is applied to all sitemaps.', $this->domain)), 'input_split_limit_post' => array('size' => 5, 'label' => __('Maximum is <strong>50,000</strong>. ' . 'Set to 0 to use the Global limit.', $this->domain)), 'input_custom_xslt' => array('size' => 91, 'label' => '<br />' . __('Expect an absolute URL, ' . 'e.g. <code>http://example.com/my-stylesheet.xsl</code>. ' . 'You must also have a stylesheet for the sitemapindex ' . 'that can be accessed through the above URL, ' . 'e.g. <code>my-stylesheet.xsl</code> and ' . '<code>my-stylesheetindex.xsl</code>. ' . 'Leave blank to use provided stylesheets.', $this->domain)), 'input_alt_module_dir' => array('size' => 91, 'label' => '<br />' . __('Expect an absolute path to the directory ' . 'where you put your custom modules ' . '(e.g. <code>/home/mysite/public_html/gxs-modules/</code>). ', $this->domain) . '<br />' . __('Override a built-in module by having a module ' . 'with the same filename in specified directory.', $this->domain)), 'input_cache_dir' => array('size' => 91, 'disabled' => $this->_get_cache_directory_from_constant() ? ' disabled="disabled" ' : '', 'value' => $this->_get_cache_directory_from_constant() ? strtoupper(__('set via constant (BWP_GXS_CACHE_DIR)', $this->domain)) : null, 'label' => '<br />' . __('Expect an absolute path to a writable directory ' . '(i.e. CHMOD to 755 or 777). ', $this->domain) . '<br />' . sprintf(__('Leave empty to use <code>%s</code>.', $this->domain), $this->_get_default_cache_directory())), 'input_sql_limit' => array('size' => 5, 'label' => __('Only get this many items when querying from Database. ' . 'This is to make sure we are not running too heavy queries.', $this->domain)), 'input_oldest' => array('size' => 3, 'label' => '&mdash;'), 'input_cache_age' => array('size' => 5, 'label' => '&mdash;'), 'input_ping_limit' => array('size' => 5, 'label' => __('time(s) per day. Increase this limit if ' . 'you publish a lot of posts in a single day.', $this->domain))), 'inline_fields' => array('input_cache_age' => array('select_time_type' => 'select')), 'inline' => array('cb_enable_autogen' => '<br /><br />'), 'container' => array('heading_submit' => array('<em>' . sprintf(__('Submit your <a href="%s" target="_blank">sitemapindex</a> ' . 'to major search engines like <a href="%s" target="_blank">Google</a>, ' . '<a href="%s" target="_blank">Bing</a>.', $this->domain), $this->sitemap_url, 'https://www.google.com/webmasters/tools/home?hl=en', 'http://www.bing.com/toolbox/webmasters/') . ' ' . sprintf(__('Only the sitemapindex needs to be submitted ' . 'as search engines will automatically recognize other included sitemaps. ' . 'More info can be found <a href="%s">here</a>.', $this->domain), 'https://support.google.com/webmasters/answer/75712?hl=en&ref_topic=4581190') . '</em>', $this->get_logs(true))), 'role' => array('cb_enable_gzip' => 'superadmin', 'heading_cache' => 'superadmin', 'cb_enable_cache' => 'superadmin', 'cb_enable_autogen' => 'superadmin', 'cb_index_to_primary' => 'superadmin', 'input_cache_age' => 'superadmin', 'input_cache_dir' => 'superadmin', 'heading_module' => 'superadmin', 'input_sql_limit' => 'superadmin', 'input_alt_module_dir' => 'superadmin', 'heading_debug' => 'superadmin', 'cb_log' => 'superadmin', 'cb_debug' => 'superadmin', 'cb_debug_extra' => 'superadmin'), 'env' => array('cb_index_to_primary' => 'multisite'));
             foreach ($this->frequencies as $freq) {
                 $changefreq[ucfirst($freq)] = $freq;
             }
             $form['select']['select_default_freq'] = $changefreq;
             $options = $bwp_option_page->get_options(array('input_item_limit', 'input_split_limit_post', 'input_alt_module_dir', 'input_cache_dir', 'input_sql_limit', 'input_cache_age', 'input_custom_xslt', 'input_exclude_post_type', 'input_exclude_post_type_ping', 'input_exclude_taxonomy', 'input_ping_limit', 'enable_gmt', 'enable_xslt', 'enable_cache', 'enable_cache_auto_gen', 'enable_stats', 'enable_credit', 'enable_sitemap_split_post', 'enable_robots', 'enable_global_robots', 'enable_sitemap_date', 'enable_sitemap_taxonomy', 'enable_sitemap_external', 'enable_sitemap_author', 'enable_sitemap_site', 'enable_gzip', 'enable_ping', 'enable_ping_google', 'enable_ping_bing', 'enable_log', 'enable_debug', 'enable_debug_extra', 'select_time_type', 'select_default_freq', 'select_default_pri', 'select_min_pri'), $this->options);
             // get option from the database
             $options = $bwp_option_page->get_db_options($page, $options);
             $option_formats = array('input_item_limit' => 'int', 'input_split_limit_post' => 'int', 'input_sql_limit' => 'int', 'input_cache_age' => 'int', 'input_ping_limit' => 'int', 'select_time_type' => 'int');
             $option_ignore = array('input_exclude_post_type', 'input_exclude_post_type_ping', 'input_exclude_taxonomy');
             $option_super_admin = $this->site_options;
         } elseif ($page == BWP_GXS_GOOGLE_NEWS) {
             $bwp_option_page->set_current_tab(2);
             $form = array('items' => array('heading', 'checkbox', 'input', 'select', 'checkbox', 'select', 'checkbox', 'checkbox', 'heading', 'select'), 'item_labels' => array(__('Add Google News Sitemap to your sitemapindex', $this->domain), __('Enable news sitemap', $this->domain), __('News name', $this->domain), __('News language', $this->domain), __('Enable keywords support', $this->domain), __('Get keywords from', $this->domain), __('Enable multi-category support', $this->domain), __('Ping search engines when a news article is published', $this->domain), __('News categories', $this->domain), __('The Google News sitemap will', $this->domain)), 'item_names' => array('h1', 'cb1', 'input_news_name', 'select_news_lang', 'cb2', 'select_news_keyword_type', 'cb4', 'cb3', 'h2', 'select_news_cat_action'), 'heading' => array('h1' => '<em>' . __('A Google News Sitemap is a file that ' . 'allows you to control which content ' . 'you submit to Google News. By creating and ' . 'submitting a Google News Sitemap, you\'re able ' . 'to help Google News discover and crawl your site\'s news articles ' . '&mdash; http://support.google.com/', $this->domain) . '</em>', 'h2' => '<em>' . __('Below you will be able to choose what categories ' . 'to use (or not use) in the news sitemap. ' . 'You can also assign genres to a specific category.', $this->domain) . '</em>'), 'post' => array('select_news_cat_action' => __('below selected categories in the news sitemap.', $this->domain)), 'select' => array('select_news_lang' => array(__('English', $this->domain) => 'en', __('Arabic', $this->domain) => 'ar', __('Chinese (simplified)', $this->domain) => 'zh-cn', __('Chinese (traditional)', $this->domain) => 'zh-tw', __('Dutch', $this->domain) => 'nl', __('French', $this->domain) => 'fr', __('German', $this->domain) => 'de', __('Hebrew', $this->domain) => 'he', __('Hindi', $this->domain) => 'hi', __('Italian', $this->domain) => 'it', __('Japanese', $this->domain) => 'ja', __('Norwegian', $this->domain) => 'no', __('Portuguese', $this->domain) => 'pt', __('Polish', $this->domain) => 'pl', __('Russian', $this->domain) => 'ru', __('Spanish', $this->domain) => 'es', __('Turkish', $this->domain) => 'tr', __('Vietnamese', $this->domain) => 'vi'), 'select_news_cat_action' => array(__('include', $this->domain) => 'inc', __('exclude', $this->domain) => 'exc'), 'select_news_keyword_type' => array(__('News categories', $this->domain) => 'cat', __('News tags', $this->domain) => 'tag')), 'input' => array('input_news_name' => array('size' => 70, 'label' => '<br />' . __('Set a different name for your news sitemap. ' . 'By default, your Site Title is used.', $this->domain))), 'checkbox' => array('cb1' => array(sprintf(__('A <code>post_google_news.xml</code> sitemap will be added to the main <a href="%s" target="_blank">sitemapindex.xml</a>. It is strongly recommended that you take a look at <a href="%s" target="_blank">Google\'s guidelines</a> before enabling this feature.', $this->domain), $this->sitemap_url, 'https://support.google.com/news/publisher/answer/74288?hl=en#sitemapguidelines') => 'enable_news_sitemap'), 'cb2' => array(sprintf(__('More info <a href="%s" target="_blank">here</a>.', $this->domain), 'https://support.google.com/news/publisher/answer/116037?hl=en&ref_topic=4359874') => 'enable_news_keywords'), 'cb3' => array(__('This ping works separately from the sitemapindex ping, and only occurs when you publish an article in one of the news categories set below.', $this->domain) => 'enable_news_ping'), 'cb4' => array(__('Enable this if you have posts assigned to more than one categories.', $this->domain) => 'enable_news_multicat')), 'inline_fields' => array(), 'post' => array(), 'container' => array('select_news_cat_action' => '', 'cb1' => '<em><strong>' . __('Note', $this->domain) . ':</strong> ' . __('The Google News sitemap is an extension (or sub-module) of ' . 'the <code>post.xml</code> sitemap, which means it also uses posts from ' . 'the <strong>Post</strong> post type, but only from categories that are selected.', $this->domain) . '</em>'));
             // Get the options
             $options = $bwp_option_page->get_options(array('enable_news_sitemap', 'enable_news_ping', 'enable_news_keywords', 'enable_news_multicat', 'select_news_lang', 'select_news_keyword_type', 'select_news_cat_action', 'select_news_cats', 'input_news_name', 'input_news_genres'), $this->options);
             // Get option from the database
             $options = $bwp_option_page->get_db_options($page, $options);
             $option_ignore = array('select_news_cats', 'input_news_genres');
             $option_formats = array();
             $option_super_admin = $this->site_options;
         } elseif ($page == BWP_GXS_STATS) {
             $bwp_option_page->set_current_tab(3);
             // no save changes button
             add_filter('bwp_option_submit_button', create_function('', 'return "";'));
             if ($this->_is_log_empty || 'yes' != $this->options['enable_log']) {
                 // no log is found, or logging is disabled, hide sidebar to save space
                 add_filter('bwp_info_showable', create_function('', 'return "";'));
             }
             $form = array('items' => array('heading'), 'item_labels' => array(__('Sitemap Generator\'s Log', $this->domain)), 'item_names' => array('h3'), 'heading' => array('h3' => 'yes' == $this->options['enable_log'] ? '<em>' . __('Below are details on how your sitemaps are generated ' . 'including <span style="color: #999999;">notices</span>, ' . '<span style="color: #FF0000;">errors</span> and ' . '<span style="color: #009900;">success messages</span>.', $this->domain) . '</em>' : '<em>' . __('Logging is not currently enabled. ' . 'You can enable this feature by checking ' . '"Enable sitemap log" in <strong>XML Sitemaps >> Sitemap log & debug</strong>.', $this->domain) . '</em>'), 'container' => array('h3' => 'yes' == $this->options['enable_log'] ? $this->get_logs() : ''));
             // get the options
             $options = array();
             // get option from the database
             $options = $bwp_option_page->get_db_options($page, $options);
             $option_ignore = array();
             $option_formats = array();
             $option_super_admin = $this->site_options;
         }
     }
     if ((isset($_POST['submit_' . $bwp_option_page->get_form_name()]) || isset($_POST['save_flush_cache'])) && isset($options) && is_array($options)) {
         // basic security check
         check_admin_referer($page);
         foreach ($options as $key => &$option) {
             if (in_array($key, $option_ignore) || self::is_normal_admin() && in_array($key, $option_super_admin)) {
                 // this option should not be handled here
                 // 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];
                     }
                 }
             }
         }
         if ($page == BWP_GXS_OPTION_GENERATOR) {
             // handle dynamic options based on public post types and taxonomies
             $ept = array();
             // exclude post types from sitemap
             $eppt = array();
             // exclude post types from pinging
             $etax = array();
             // exclude taxonomies from sitemap
             foreach ($_POST as $o => $v) {
                 if (strpos($o, 'ept_') === 0) {
                     $ept[] = trim(str_replace('ept_', '', $o));
                 } elseif (strpos($o, 'eppt_') === 0) {
                     $eppt[] = trim(str_replace('eppt_', '', $o));
                 } else {
                     if (strpos($o, 'etax_') === 0) {
                         $etax[] = trim(str_replace('etax_', '', $o));
                     }
                 }
             }
             $options['input_exclude_post_type'] = implode(',', $ept);
             $options['input_exclude_post_type_ping'] = implode(',', $eppt);
             $options['input_exclude_taxonomy'] = implode(',', $etax);
             // no more than 50000 URLs per sitemap
             $options['input_item_limit'] = 50000 < $options['input_item_limit'] ? 50000 : $options['input_item_limit'];
             $options['input_split_limit_post'] = 50000 < $options['input_split_limit_post'] ? 50000 : $options['input_split_limit_post'];
         } elseif ($page == BWP_GXS_GOOGLE_NEWS) {
             // save google news categories and genres
             $news_cats = array();
             $news_genres = array();
             $categories = get_categories(array('hide_empty' => 0));
             foreach ($categories as $category) {
                 if (!empty($_POST[$category->slug])) {
                     $news_cats[] = $category->term_id;
                 }
                 if (isset($_POST[$category->slug . '_genres']) && is_array($_POST[$category->slug . '_genres'])) {
                     $genres = $_POST[$category->slug . '_genres'];
                     $genres_string = array();
                     foreach ($genres as $genre) {
                         $genres_string[] = trim($genre);
                     }
                     $news_genres['cat_' . $category->term_id] = implode(', ', $genres_string);
                 }
             }
             $options['select_news_cats'] = implode(',', $news_cats);
             $options['input_news_genres'] = $news_genres;
         }
         // update per-blog options
         update_option($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($page, $options);
         }
         // refresh the options property to include updated options
         $this->options = array_merge($this->options, $options);
         // show success messages when settings are saved
         $this->add_notice(__('All options have been saved.', $this->domain));
         // flush cache if needed
         if (isset($_POST['save_flush_cache'])) {
             $this->_admin_flush_cache();
         }
     }
     if ($page == BWP_GXS_OPTION_GENERATOR) {
         // handle other non-POST actions for XML Sitemap setting page
         // add dynamic checkboxes to the current form
         $this->_add_checkboxes_to_form('sec_post', 'ept_', $form, $dynamic_options);
         $this->_add_checkboxes_to_form('sec_post_ping', 'eppt_', $form, $dynamic_options);
         $this->_add_checkboxes_to_form('sec_tax', 'etax_', $form, $dynamic_options);
         if ($this->options['enable_cache'] == 'yes') {
             // show a warning if caching is enabled but cache directory is
             // not writable
             $this->cache_directory = $this->_get_cache_directory();
             if (!@file_exists($this->cache_directory) || !@is_writable($this->cache_directory)) {
                 $this->add_notice('<strong>' . __('Warning') . ':</strong> ' . sprintf(__('Cache directory (<code>%s</code>) does not exist or is not writable. ' . 'Please try CHMODing it to either 755 or 777, or disable caching to hide ' . 'this warning (not recommended).', $this->domain), $this->cache_directory));
             }
         }
     } elseif ($page == BWP_GXS_GOOGLE_NEWS) {
         $form['container']['select_news_cat_action'] = $this->get_news_cats();
     }
     // assign the form and option array
     $bwp_option_page->init($form, $options + $dynamic_options, $this->form_tabs);
     // build the option page
     echo $bwp_option_page->generate_html_form();
 }
 /**
  * Build the option pages
  *
  * Utilizes BWP Option Page Builder (@see BWP_OPTION_PAGE)
  */
 function build_option_pages()
 {
     if (!current_user_can(BWP_CAPT_CAPABILITY)) {
         wp_die(__('You do not have sufficient permissions to access this page.'));
     }
     // Init the class
     $page = $_GET['page'];
     $bwp_option_page = new BWP_OPTION_PAGE($page, $this->site_options, 'bwp-recaptcha');
     $options = array();
     if (!empty($page)) {
         if ($page == BWP_CAPT_OPTION_GENERAL) {
             $bwp_option_page->set_current_tab(1);
             // Option Structures - Form
             $form = array('items' => array('heading', 'section', 'checkbox', 'input', 'input', 'heading', 'section', 'select', 'input', 'input', 'heading', 'checkbox', 'select'), 'item_labels' => array(__('What is reCAPTCHA?', 'bwp-recaptcha'), __('This plugin will be', 'bwp-recaptcha'), __('Use main site\'s keys', 'bwp-recaptcha'), __('Public Key', 'bwp-recaptcha'), __('Private Key', 'bwp-recaptcha'), __('Visibility Options (applied to comment forms)', 'bwp-recaptcha'), __('Hide the CAPTCHA for', 'bwp-recaptcha'), __('If wrong or empty response', 'bwp-recaptcha'), __('Show the error message', 'bwp-recaptcha'), __('Show the error message', 'bwp-recaptcha'), __('Akismet Integration (applied to comment forms)', 'bwp-recaptcha'), __('Integrate with Akismet?', 'bwp-recaptcha'), __('If correct CAPTCHA response', 'bwp-recaptcha')), 'item_names' => array('h1', 'sec1', 'cb7', 'input_pubkey', 'input_prikey', 'h2', 'sec2', 'select_response', 'input_error', 'input_back', 'h3', 'cb6', 'select_akismet_react'), 'heading' => array('h1' => __('reCAPTCHA is a free CAPTCHA service that helps to digitize books, newspapers and old time radio shows. You can read more about reCAPTCHA <a href="http://www.google.com/recaptcha/learnmore" target="_blank">here</a>.', 'bwp-recaptcha'), 'h2' => __('<em>This section allows you to determine when to show reCAPTCHA and how this plugin reacts to errors.</em>', 'bwp-recaptcha'), 'h3' => __('<em>Integrate with Akismet for better end-user experience. reCAPTCHA is optional and <strong>NO</strong> spam comment will be added to the spam/moderation queue, except likely legitimate comments. This makes the task of identifying sincere comments much easier. This integration is currently in beta stage.</em>', 'bwp-recaptcha')), 'sec1' => array(array('checkbox', 'name' => 'cb1'), array('checkbox', 'name' => 'cb2'), array('checkbox', 'name' => 'cb8')), 'sec2' => array(array('checkbox', 'name' => 'cb3'), array('checkbox', 'name' => 'cb4'), array('checkbox', 'name' => 'cb5')), 'select' => array('select_lang' => $this->lang, 'select_cap' => $this->caps, 'select_response' => array(__('Redirect commenter back to the comment form', 'bwp-recaptcha') => 'redirect', __('Show an error page just like WordPress does', 'bwp-recaptcha') => 'back'), 'select_akismet_react' => array(__('Approve comment immediately', 'bwp-recaptcha') => '1', __('Hold comment in moderation queue', 'bwp-recaptcha') => 'hold', __('Put comment in spam queue', 'bwp-recaptcha') => 'spam')), 'checkbox' => array('cb1' => array(__('enabled for comment forms.', 'bwp-recaptcha') => 'enable_comment'), 'cb2' => array(__('enabled for registration form (user/site registration).', 'bwp-recaptcha') => 'enable_registration'), 'cb8' => array(__('enabled for login form.', 'bwp-recaptcha') => 'enable_login'), 'cb3' => array(__('registered users <em>(even without any capabilities)</em>.', 'bwp-recaptcha') => 'hide_registered'), 'cb4' => array(__('users who can', 'bwp-recaptcha') => 'hide_cap'), 'cb5' => array(__('visitors who have at least', 'bwp-recaptcha') => 'hide_approved'), 'cb6' => array(__('reCAPTCHA will only show when Akismet identifies a comment as spam. Highly recommended if you do not want to force your visitors to type the captcha every time.', 'bwp-recaptcha') => 'enable_akismet'), 'cb7' => array(__('uncheck to use different key pairs for this site.', 'bwp-recaptcha') => 'use_global_keys')), 'input' => array('input_pubkey' => array('size' => 30, 'label' => __('A public key used to request captchas from reCAPTCHA server.', 'bwp-recaptcha')), 'input_prikey' => array('size' => 30, 'label' => __('A private (secret) key used to authenticate user\'s response.', 'bwp-recaptcha')), 'input_error' => array('size' => 90, 'label' => __('when redirect commenter back to the comment form (or when used in other forms such as contact forms).', 'bwp-recaptcha')), 'input_back' => array('size' => 90, 'label' => __('when show the normal error page with no redirection.', 'bwp-recaptcha')), 'input_approved' => array('size' => 3, 'label' => __('approved comment(s).', 'bwp-recaptcha'))), 'container' => array('cb2' => __('<em><strong>Note:</strong> For this plugin to work, you will need a pair of API keys (public and private), which is available for free <a href="https://www.google.com/recaptcha/admin/create" target="_blank">here</a>. Once you have created those two keys for this domain, simply paste them below.</em>', 'bwp-recaptcha'), 'select_akismet_react' => __('<em><strong>Note:</strong> Now you may wonder, why put the comment in the spam queue? The benefit is Akismet will be able to mark the comment as False Positive, and thus will not possibly block that comment in the future. However, it is best to just put the comment in moderation queue as next time Akismet will put such comment in moderation queue immediately without the need of a CAPTCHA.</em>', 'bwp-recaptcha')), 'inline_fields' => array('cb4' => array('select_cap' => 'select'), 'cb5' => array('input_approved' => 'input')));
             // Get the default options
             $options = $bwp_option_page->get_options(array('use_global_keys', 'input_pubkey', 'input_prikey', 'input_error', 'input_approved', 'select_cap', 'hide_registered', 'hide_cap', 'hide_approved', 'enable_registration', 'enable_login', 'enable_comment', 'input_back', 'select_response', 'enable_akismet', 'select_akismet_react'), $this->options);
             // Get option from the database
             $options = $bwp_option_page->get_db_options($page, $options);
             $option_formats = array('input_approved' => 'int', 'input_error' => 'html', 'input_back' => 'html');
             $option_super_admin = array();
             // show appropriate fields based on multi-site setting
             add_action('bwp_option_action_before_submit_button', array($this, 'modify_option_page'));
         } else {
             if ($page == BWP_CAPT_OPTION_THEME) {
                 $bwp_option_page->set_current_tab(2);
                 // Option Structures - Form
                 $form = array('items' => array('select', 'checkbox', 'checkbox', 'select', 'input', 'heading'), 'item_labels' => array(__('Choose a theme', 'bwp-recaptcha'), __('Use CSS provided by this plugin?', 'bwp-recaptcha'), __('Load CSS, JS selectively?', 'bwp-recaptcha'), __('Choose a language for built-in themes', 'bwp-recaptcha'), __('Tabindex for captcha input field', 'bwp-recaptcha'), __('Preview your reCAPTCHA', 'bwp-recaptcha')), 'item_names' => array('select_theme', 'cb1', 'cb2', 'select_lang', 'input_tab', 'h1'), 'heading' => array('h1' => __('<em>Below you will see how your reCAPTCHA will look. Note that this might differ on your actual pages.<br /></em>', 'bwp-recaptcha')), 'select' => array('select_theme' => array(__('Default Theme (Red)', 'bwp-recaptcha') => 'red', __('White Theme', 'bwp-recaptcha') => 'white', __('Black Theme', 'bwp-recaptcha') => 'blackglass', __('Clean Theme', 'bwp-recaptcha') => 'clean', __('Custom Theme (use CSS)', 'bwp-recaptcha') => 'custom'), 'select_lang' => $this->lang), 'checkbox' => array('cb1' => array(__('This stylesheet is used to style the custom theme as well as the registration page. You can disable this or add appropriate filters to use your own.', 'bwp-recaptcha') => 'enable_css'), 'cb2' => array(__('This is only useful when you do not use any minify or cache plugin.', 'bwp-recaptcha') => 'enable_selective')), 'input' => array('input_tab' => array('size' => 3, 'label' => __('Basically, this should be 4 if you place the captcha before the textarea, and 5 if you put it after. Set to 0 to disable.', 'bwp-recaptcha'))), 'container' => array('select_theme' => sprintf(__('<em><strong>Note:</strong> The four built-in captcha themes will look OK in most WordPress themes; However, some times it is better to control how reCAPTCHA looks using CSS. Please read <a href="%s#customization" target="_blank">this guide</a> if you would like to do so.</em>', 'bwp-recaptcha'), BWP_CAPT_PLUGIN_URL), 'select_lang' => sprintf(__('<em><strong>Note:</strong> Above you can select some built-in languages. If you would like to add your own language, please read <a href="%s#customization" target="_blank">this guide</a>.</em>', 'bwp-recaptcha'), BWP_CAPT_PLUGIN_URL)));
                 // Get the default options
                 $options = $bwp_option_page->get_options(array('select_lang', 'select_theme', 'input_tab', 'enable_css', 'enable_selective'), $this->options);
                 // Get option from the database
                 $options = $bwp_option_page->get_db_options($page, $options);
                 $option_formats = array('input_tab' => 'int');
                 $option_super_admin = array();
                 // preview reCAPTCHA
                 add_action('bwp_option_action_before_submit_button', array($this, 'add_recaptcha'));
             }
         }
     }
     // Get option from user input
     if (isset($_POST['submit_' . $bwp_option_page->get_form_name()]) && isset($options) && is_array($options)) {
         check_admin_referer($page);
         foreach ($options as $key => &$option) {
             if ($this->is_normal_admin() && in_array($key, $option_super_admin)) {
             } else {
                 if (isset($_POST[$key])) {
                     $bwp_option_page->format_field($key, $option_formats);
                 }
                 if (!isset($_POST[$key])) {
                     $option = '';
                 } else {
                     if (isset($option_formats[$key]) && 0 == $_POST[$key] && 'int' == $option_formats[$key]) {
                         $option = 0;
                     } else {
                         if (isset($option_formats[$key]) && empty($_POST[$key]) && 'int' == $option_formats[$key]) {
                             $option = $this->options_default[$key];
                         } else {
                             if (!empty($_POST[$key])) {
                                 // should add more validation here though
                                 $option = trim(stripslashes($_POST[$key]));
                             } else {
                                 $option = '';
                             }
                         }
                     }
                 }
             }
         }
         update_option($page, $options);
         // Update site options if is super admin and is on main site
         global $blog_id;
         if (!$this->is_normal_admin() && $blog_id == 1) {
             update_site_option($page, $options);
         }
         // Update options successfully
         $this->add_notice(__('All options have been saved.', 'bwp-recaptcha'));
     }
     // show notice if one of the api keys is missing
     $this->options = array_merge($this->options, $options);
     if (empty($this->options['input_pubkey']) || empty($this->options['input_prikey'])) {
         $this->add_notice('<strong>' . __('Warning') . ':</strong> ' . __("API key(s) missing. Please get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a> (free!)", 'bwp-recaptcha'));
     }
     if ('yes' == $this->options['enable_akismet'] && !defined('AKISMET_VERSION')) {
         $this->add_notice('<strong>' . __('Notice') . ':</strong> ' . __('You are enabling Akismet integration but Akismet is not currently active. Please activate Akismet for the integration to work.', 'bwp-recaptcha'));
     }
     // Assign the form and option array
     $bwp_option_page->init($form, $options, $this->form_tabs);
     // Build the option page
     $bwp_option_page->generate_html_form();
 }
 /**
  * Build the option pages
  *
  * Utilizes BWP Option Page Builder (@see BWP_OPTION_PAGE)
  */
 function build_option_pages()
 {
     if (!current_user_can(BWP_GXS_CAPABILITY)) {
         wp_die(__('You do not have sufficient permissions to access this page.'));
     }
     // Init the class
     $page = $_GET['page'];
     $bwp_option_page = new BWP_OPTION_PAGE($page, $this->site_options);
     $options = array();
     $dynamic_options = array();
     if (!empty($page)) {
         if ($page == BWP_GXS_STATS) {
             $bwp_option_page->set_current_tab(1);
             // Clear logs = @since 1.1.0
             if (isset($_POST['clear_log']) && !$this->is_normal_admin()) {
                 check_admin_referer($page);
                 $this->logs = array('log' => array(), 'sitemap' => array());
                 $this->commit_logs();
                 $this->add_notice('<strong>' . __('Notice', 'bwp-simple-gxs') . ':</strong> ' . __("All logs have been cleared successfully!", 'bwp-simple-gxs'));
             }
             $form = array('items' => array('heading', 'heading', 'heading', 'heading', 'checkbox', 'section', 'heading', 'checkbox', 'checkbox'), 'item_labels' => array(__('What are Sitemaps?', 'bwp-simple-gxs'), __('Your sitemaps', 'bwp-simple-gxs'), __('Submit your sitemaps', 'bwp-simple-gxs'), __('Pinging search engines', 'bwp-simple-gxs'), __('Enable pinging functionality?', 'bwp-simple-gxs'), __('Enable pinging individual SE', 'bwp-simple-gxs'), __('Sitemap Generator\'s Log', 'bwp-simple-gxs'), __('Enable logging?', 'bwp-simple-gxs'), __('Enable debugging?', 'bwp-simple-gxs')), 'item_names' => array('h1', 'h2', 'h4', 'h5', 'cb1', 'sec1', 'h3', 'cb2', 'cb3'), 'sec1' => array(array('checkbox', 'name' => 'cb4'), array('checkbox', 'name' => 'cb6')), 'heading' => array('h1' => __('In its simplest form, a Sitemap is an XML file that lists URLs for a site along with additional metadata about each URL (when it was last updated, how often it usually changes, and how important it is, relative to other URLs in the site) so that search engines can more intelligently crawl the site &mdash; <em>http://www.sitemaps.org/</em>', 'bwp-simple-gxs') . '<br /><br />' . __('This plugin helps you generate both Sitemap Index files as well as normal Sitemap files. A Sitemap Index, as its name suggests, is one kind of sitemaps that allows you to group multiple sitemap files inside it.', 'bwp-simple-gxs'), 'h2' => __('<em>Basic information about all your sitemaps.</em>', 'bwp-simple-gxs'), 'h3' => __('<em>More detailed information about how your sitemaps are generated including <span style="color: #999999;">notices</span>, <span style="color: #FF0000;">errors</span> and <span style="color: #009900;">success messages</span>.</em>', 'bwp-simple-gxs'), 'h4' => sprintf(__('<em>Submit your sitemapindex to major search engines like <a href="%s" target="_blank">Google</a>, <a href="%s" target="_blank">Bing</a>.</em>', 'bwp-simple-gxs'), 'https://www.google.com/webmasters/tools/home?hl=en', 'http://www.bing.com/toolbox/webmasters/'), 'h5' => __('<em>Now when you post something new to your blog, you can <em>ping</em> those search engines to tell them your blog just got updated. Pinging could be less effective than you think it is but you should enable such feature anyway.</em>', 'bwp-simple-gxs')), 'input' => array(), 'checkbox' => array('cb1' => array(__('Selected SE below will be pinged when you publish new posts.', 'bwp-simple-gxs') => 'enable_ping'), 'cb2' => array(__('No additional load is needed so enabling this is recommended.', 'bwp-simple-gxs') => 'enable_log'), 'cb3' => array(__('Minor errors will be printed on screen. Also, when debug is on, no caching is used, useful when you develop new modules.', 'bwp-simple-gxs') => 'enable_debug'), 'cb4' => array(__('Google', 'bwp-simple-gxs') => 'enable_ping_google'), 'cb6' => array(__('Bing', 'bwp-simple-gxs') => 'enable_ping_bing')), 'container' => array('h4' => sprintf(__('After you activate this plugin, all sitemaps should be available right away. The next step is to submit the sitemapindex to major search engines. You only need the <strong>sitemapindex</strong> and nothing else, those search engines will automatically recognize other included sitemaps. You can read a small <a href="%s">How-to</a> if you are interested.', 'bwp-simple-gxs'), 'http://help.yahoo.com/l/us/yahoo/smallbusiness/store/promote/sitemap/sitemap-06.html'), 'h3' => $this->get_logs(), 'h2' => $this->get_logs(true)));
             // Add a clear log button - @since 1.1.0
             if (!$this->is_normal_admin()) {
                 add_filter('bwp_option_submit_button', array($this, 'add_clear_log_button'));
             }
             // Get the options
             $options = $bwp_option_page->get_options(array('enable_ping', 'enable_ping_google', 'enable_ping_bing', 'enable_log', 'enable_debug'), $this->options);
             // Get option from the database
             $options = $bwp_option_page->get_db_options($page, $options);
             $option_ignore = array('input_update_services');
             $option_formats = array();
             // [WPMS Compatible]
             $option_super_admin = $this->site_options;
         } else {
             if ($page == BWP_GXS_OPTION_GENERATOR) {
                 $bwp_option_page->set_current_tab(2);
                 //add_filter('bwp_ad_showable', function() { return false;});
                 $form = array('items' => array('input', 'select', 'select', 'select', 'checkbox', 'checkbox', 'input', 'checkbox', 'checkbox', 'checkbox', 'checkbox', 'heading', 'checkbox', 'checkbox', 'checkbox', 'section', 'section', 'section', 'heading', 'input', 'input', 'heading', 'checkbox', 'checkbox', 'input', 'input'), 'item_labels' => array(__('Output no more than', 'bwp-simple-gxs'), __('Default change frequency', 'bwp-simple-gxs'), __('Default priority', 'bwp-simple-gxs'), __('Minimum priority', 'bwp-simple-gxs'), __('Use GMT for Last Modified date?', 'bwp-simple-gxs'), __('Style your sitemaps with an XSLT stylesheet?', 'bwp-simple-gxs'), __('Custom XSLT stylesheet URL', 'bwp-simple-gxs'), __('Show build stats in sitemaps?', 'bwp-simple-gxs'), __('Enable credit?', 'bwp-simple-gxs'), __('Enable Gzip?', 'bwp-simple-gxs'), __('Clean unexpected output before sitemap generation?', 'bwp-simple-gxs'), __('Sitemap Index Options', 'bwp-simple-gxs'), __('Automatically split post-based sitemaps into smaller sitemaps?', 'bwp-simple-gxs'), __('Add sitemapindex to individual blog\'s virtual robots.txt?', 'bwp-simple-gxs'), __('Add sitemapindex from all blogs within network to primary blog\'s virtual robots.txt?', 'bwp-simple-gxs'), __('In sitemapindex, include', 'bwp-simple-gxs'), __('Exclude following post types:', 'bwp-simple-gxs'), __('Exclude following taxonomies:', 'bwp-simple-gxs'), __('Module Options', 'bwp-simple-gxs'), __('Alternate module directory', 'bwp-simple-gxs'), __('Get no more than', 'bwp-simple-gxs'), __('Caching Options', 'bwp-simple-gxs'), __('Enable caching?', 'bwp-simple-gxs'), __('Enable auto cache re-generation?', 'bwp-simple-gxs'), __('Cached sitemaps will last for', 'bwp-simple-gxs'), __('Cached sitemaps are stored in (auto detected)', 'bwp-simple-gxs')), 'item_names' => array('input_item_limit', 'select_default_freq', 'select_default_pri', 'select_min_pri', 'cb14', 'cb10', 'input_custom_xslt', 'cb3', 'cb6', 'cb4', 'cb15', 'h5', 'cb12', 'cb11', 'cb5', 'sec1', 'sec2', 'sec3', 'h4', 'input_alt_module_dir', 'input_sql_limit', 'h3', 'cb1', 'cb2', 'input_cache_age', 'input_cache_dir'), 'heading' => array('h3' => __('<em>Cache your sitemaps for better performance.</em>', 'bwp-simple-gxs'), 'h4' => sprintf(__('<em>This plugin uses modules to build sitemap data so it is recommended that you extend this plugin using modules rather than hooks. Some of the settings below only affect modules extending the base module class. Read more about using modules <a href="%s#using-modules">here</a>.</em>', 'bwp-simple-gxs'), $this->plugin_url), 'h5' => __('<em>Here you can change some settings that affect the default Sitemap Index file.</em>', 'bwp-simple-gxs')), 'sec1' => array(array('checkbox', 'name' => 'cb7'), array('checkbox', 'name' => 'cb9'), array('checkbox', 'name' => 'cb13'), array('checkbox', 'name' => 'cb16'), array('checkbox', 'name' => 'cb17')), 'sec2' => array(), 'sec3' => array(), 'select' => array('select_time_type' => array(__('second(s)', 'bwp-simple-gxs') => 1, __('minute(s)', 'bwp-simple-gxs') => 60, __('hour(s)', 'bwp-simple-gxs') => 3600, __('day(s)', 'bwp-simple-gxs') => 86400), 'select_oldest_type' => array(__('second(s)', 'bwp-simple-gxs') => 1, __('minute(s)', 'bwp-simple-gxs') => 60, __('hour(s)', 'bwp-simple-gxs') => 3600, __('day(s)', 'bwp-simple-gxs') => 86400), 'select_default_freq' => array(), 'select_default_pri' => $this->priority, 'select_min_pri' => $this->priority), 'post' => array('select_default_freq' => sprintf('<a href="%s" target="_blank">' . __('read more', 'bwp-simple-gxs') . '</a>', 'http://sitemaps.org/protocol.php#xmlTagDefinitions'), 'select_default_pri' => sprintf('<a href="%s" target="_blank">' . __('read more', 'bwp-simple-gxs') . '</a>', 'http://sitemaps.org/protocol.php#xmlTagDefinitions'), 'select_min_pri' => sprintf('<a href="%s" target="_blank">' . __('read more', 'bwp-simple-gxs') . '</a>', 'http://sitemaps.org/protocol.php#xmlTagDefinitions')), 'checkbox' => array('cb1' => array(__('your sitemaps are generated and then cached to reduce unnecessary work.', 'bwp-simple-gxs') => 'enable_cache'), 'cb2' => array(__('when a cached sitemap expires, this plugin will try to generate the cache again. If you disable this, remember to manually flush the cache once in a while.', 'bwp-simple-gxs') . ' <input type="submit" class="button-secondary action" name="flush_cache" value="' . __('Flush the cache', 'bwp-simple-gxs') . '" />' => 'enable_cache_auto_gen'), 'cb3' => array(__('tell you useful information such as build time, memory usage, SQL queries, etc.', 'bwp-simple-gxs') => 'enable_stats'), 'cb4' => array(__('make your sitemaps ~ 70% smaller. <strong>Important:</strong> If you see an error after enabling this, it\'s very likely that you have gzip active on your server already.', 'bwp-simple-gxs') => 'enable_gzip'), 'cb15' => array(__('only disable this when sitemaps appear in either blank page or plain text.', 'bwp-simple-gxs') => 'enable_php_clean'), 'cb5' => array(sprintf(__("If you have like 50 blogs, 50 <code>Sitemap: http://example.com/sitemapindex.xml</code> entries will be added to your primary blog's robots.txt, i.e. <code>%s</code>.", 'bwp-simple-gxs'), get_site_option('home') . '/robots.txt') => 'enable_global_robots'), 'cb7' => array(__("taxonomy archives' sitemaps, including custom taxonomies.", 'bwp-simple-gxs') => 'enable_sitemap_taxonomy'), 'cb9' => array(__("date archives' sitemaps.", 'bwp-simple-gxs') => 'enable_sitemap_date'), 'cb13' => array(__("external pages' sitemap. This allows you to add links to pages that do not belong to WordPress to the sitemap.", 'bwp-simple-gxs') => 'enable_sitemap_external'), 'cb6' => array(__('some copyrighted info is also added to your sitemaps. Thanks!', 'bwp-simple-gxs') => 'enable_credit'), 'cb10' => array(__('This will load the default style sheet provided by this plugin. You can set a custom style sheet below or filter the <code>bwp_gxs_xslt</code> hook.', 'bwp-simple-gxs') => 'enable_xslt'), 'cb11' => array(sprintf(__('If you\'re on a Multi-site installation with Sub-domain enabled, each site will have its own robots.txt, sites in sub-directory will not. Please read the <a href="%s#toc-robots" target="_blank">documentation</a> for more info.', 'bwp-simple-gxs'), $this->plugin_url) => 'enable_robots'), 'cb12' => array(__('e.g. post1.xml, post2.xml, etc. And each sitemap will contain', 'bwp-simple-gxs') => 'enable_sitemap_split_post'), 'cb14' => array(__('If you disable this, make sure you also use <code>date_default_timezone_set</code> to correctly set up a timezone for your application.', 'bwp-simple-gxs') => 'enable_gmt'), 'cb16' => array(__('author archives\' sitemap.', 'bwp-simple-gxs') => 'enable_sitemap_author'), 'cb17' => array(__('site\'s home URL sitemap. For a multi-site installation of WordPress, this sitemap will list all domains within your network, not just the main blog. This also supports WPMU Domain Mapping plugin.', 'bwp-simple-gxs') => 'enable_sitemap_site')), 'input' => array('input_item_limit' => array('size' => 5, 'label' => __('item(s) in one sitemap. You can not go over 50,000.', 'bwp-simple-gxs')), 'input_split_limit_post' => array('size' => 5, 'label' => __('item(s). Again , you can not go over 50,000.', 'bwp-simple-gxs')), 'input_alt_module_dir' => array('size' => 91, 'label' => __('Input a full path to the directory where you put your own modules (e.g. <code>/home/mysite/public_html/gxs-modules/</code>), you can also override a built-in module by having a module with the same filename in this directory. A filter is also available if you would like to use PHP instead.', 'bwp-simple-gxs')), 'input_cache_dir' => array('size' => 91, 'disabled' => ' disabled="disabled"', 'label' => __('The cache directory must be writable (i.e. CHMOD to 755 or 777).', 'bwp-simple-gxs')), 'input_sql_limit' => array('size' => 5, 'label' => __('item(s) in one SQL query. This helps you avoid running too heavy queries.', 'bwp-simple-gxs')), 'input_oldest' => array('size' => 3, 'label' => '&mdash;'), 'input_cache_age' => array('size' => 5, 'label' => '&mdash;'), 'input_custom_xslt' => array('size' => 56, 'label' => __('expected to be an absolute URL, e.g. <code>http://example.com/my-stylesheet.xsl</code>. You must also have a style sheet for the sitemapindex that can be accessed through the above URL, e.g. <code>my-stylesheet.xsl</code> and <code>my-stylesheetindex.xsl</code>). Please leave blank if you do not wish to use.', 'bwp-simple-gxs'))), 'inline_fields' => array('input_cache_age' => array('select_time_type' => 'select'), 'cb12' => array('input_split_limit_post' => 'input')), 'container' => array('input_item_limit' => sprintf(__('<em><strong>Note:</strong> If you encounter white page problem, please refer to the <a target="_blank" href="%s">FAQ section</a> to know how to change this limit appropriately to make this plugin work. Also note that, for post-based sitemaps, this option will be overridden by the limit you set in the Sitemap Index Options below.</em>', 'bwp-simple-gxs'), $this->plugin_url . 'faq/')));
                 foreach ($this->frequency as $freq) {
                     $changefreq[ucfirst($freq)] = $freq;
                 }
                 $form['select']['select_default_freq'] = $changefreq;
                 // Get the options
                 $options = $bwp_option_page->get_options(array('input_item_limit', 'input_split_limit_post', 'input_alt_module_dir', 'input_cache_dir', 'input_sql_limit', 'input_cache_age', 'input_custom_xslt', 'input_exclude_post_type', 'input_exclude_taxonomy', 'enable_gmt', 'enable_robots', 'enable_xslt', 'enable_cache', 'enable_cache_auto_gen', 'enable_stats', 'enable_credit', 'enable_sitemap_split_post', 'enable_global_robots', 'enable_sitemap_date', 'enable_sitemap_taxonomy', 'enable_sitemap_external', 'enable_sitemap_author', 'enable_sitemap_site', 'enable_gzip', 'enable_php_clean', 'select_time_type', 'select_default_freq', 'select_default_pri', 'select_min_pri'), $this->options);
                 // Get option from the database
                 $options = $bwp_option_page->get_db_options($page, $options);
                 // Get dynamic options
                 if (isset($_POST['submit_' . $bwp_option_page->get_form_name()])) {
                     check_admin_referer($page);
                     $ept = array();
                     $etax = array();
                     foreach ($_POST as $o => $v) {
                         if (strpos($o, 'ept_') === 0) {
                             $ept[] = trim(str_replace('ept_', '', $o));
                         } else {
                             if (strpos($o, 'etax_') === 0) {
                                 $etax[] = trim(str_replace('etax_', '', $o));
                             }
                         }
                     }
                     $options['input_exclude_post_type'] = implode(',', $ept);
                     $options['input_exclude_taxonomy'] = implode(',', $etax);
                 }
                 // Build dynamic options
                 $post_types = get_post_types(array('public' => true), 'objects');
                 $taxonomies = get_taxonomies(array('public' => true), '');
                 $exclude_options = array('post_types' => explode(',', $options['input_exclude_post_type']), 'taxonomies' => explode(',', $options['input_exclude_taxonomy']));
                 $dynamic_options = array();
                 foreach ($post_types as $post_type) {
                     if ('attachment' == $post_type->name) {
                         continue;
                     }
                     $key = 'ept_' . $post_type->name;
                     $form['sec2'][] = array('checkbox', 'name' => $key);
                     $form['checkbox'][$key] = array(__($post_type->label) => $key);
                     if (in_array($post_type->name, $exclude_options['post_types'])) {
                         $dynamic_options[$key] = 'yes';
                     } else {
                         $dynamic_options[$key] = '';
                     }
                 }
                 foreach ($taxonomies as $taxonomy) {
                     if ('post_format' == $taxonomy->name) {
                         continue;
                     }
                     $key = 'etax_' . $taxonomy->name;
                     $form['sec3'][] = array('checkbox', 'name' => $key);
                     $form['checkbox'][$key] = array(__($taxonomy->label) => $key);
                     if (in_array($taxonomy->name, $exclude_options['taxonomies'])) {
                         $dynamic_options[$key] = 'yes';
                     } else {
                         $dynamic_options[$key] = '';
                     }
                 }
                 $option_formats = array('input_item_limit' => 'int', 'input_split_limit_post' => 'int', 'input_sql_limit' => 'int', 'input_cache_age' => 'int', 'select_time_type' => 'int');
                 $option_ignore = array('input_cache_dir', 'input_exclude_post_type', 'input_exclude_taxonomy');
                 // [WPMS Compatible]
                 $option_super_admin = $this->site_options;
             } else {
                 if ($page == BWP_GXS_GOOGLE_NEWS) {
                     $bwp_option_page->set_current_tab(3);
                     // Save news categories settings
                     if (isset($_POST['submit_bwp_gxs_google_news'])) {
                         check_admin_referer($page);
                         // News cats & News genres
                         $news_cats = array();
                         $news_genres = array();
                         $categories = get_categories(array('hide_empty' => 0));
                         foreach ($categories as $category) {
                             if (!empty($_POST[$category->slug])) {
                                 $news_cats[] = $category->term_id;
                             }
                             if (isset($_POST[$category->slug . '_genres']) && is_array($_POST[$category->slug . '_genres'])) {
                                 $genres = $_POST[$category->slug . '_genres'];
                                 $genres_string = array();
                                 foreach ($genres as $genre) {
                                     $genres_string[] = trim($genre);
                                 }
                                 $news_genres['cat_' . $category->term_id] = implode(', ', $genres_string);
                             }
                         }
                         $this->options['select_news_cats'] = implode(',', $news_cats);
                         $this->options['input_news_genres'] = $news_genres;
                     }
                     $form = array('items' => array('heading', 'checkbox', 'checkbox', 'checkbox', 'checkbox', 'select', 'heading', 'select'), 'item_labels' => array(__('What is a Google News Sitemap?', 'bwp-simple-gxs'), __('Enable this module?', 'bwp-simple-gxs'), __('Enable Multi-category Mode?', 'bwp-simple-gxs'), __('Ping Search Engines when you publish a news article?', 'bwp-simple-gxs'), __('Use keywords in News Sitemap?', 'bwp-simple-gxs'), __('News Sitemap\'s language', 'bwp-simple-gxs'), __('News Categories', 'bwp-simple-gxs'), __('This module will', 'bwp-simple-gxs')), 'item_names' => array('h1', 'cb1', 'cb4', 'cb3', 'cb2', 'select_news_lang', 'h2', 'select_news_cat_action'), 'heading' => array('h1' => __('A Google News Sitemap is a file that allows you to control which content you submit to Google News. By creating and submitting a Google News Sitemap, you\'re able to help Google News discover and crawl your site\'s articles &mdash; <em>http://support.google.com/</em>', 'bwp-simple-gxs'), 'h2' => __('<em>Below you will be able to choose what categories to use (or not use) in the news sitemap. You can also assign genres to a specific category.</em>', 'bwp-simple-gxs')), 'post' => array('select_news_cat_action' => __('below selected categories in the news sitemap.', 'bwp-simple-gxs')), 'select' => array('select_news_lang' => array(__('English', 'bwp-simple-gxs') => 'en', __('Dutch', 'bwp-simple-gxs') => 'nl', __('French', 'bwp-simple-gxs') => 'fr', __('German', 'bwp-simple-gxs') => 'de', __('Italian', 'bwp-simple-gxs') => 'it', __('Norwegian', 'bwp-simple-gxs') => 'no', __('Portuguese', 'bwp-simple-gxs') => 'pt', __('Polish', 'bwp-simple-gxs') => 'pl', __('Russian', 'bwp-simple-gxs') => 'ru', __('Simplified Chinese', 'bwp-simple-gxs') => 'zh-cn', __('Spanish', 'bwp-simple-gxs') => 'es', __('Turkish', 'bwp-simple-gxs') => 'tr', __('Vietnamese', 'bwp-simple-gxs') => 'vi'), 'select_news_cat_action' => array(__('include', 'bwp-simple-gxs') => 'inc', __('exclude', 'bwp-simple-gxs') => 'exc'), 'select_news_keyword_type' => array(__('news categories', 'bwp-simple-gxs') => 'cat', __('news tags', 'bwp-simple-gxs') => 'tag')), 'input' => array(), 'checkbox' => array('cb1' => array(__('A new <code>post_google_news.xml</code> sitemap will be added to the main <code>sitemapindex.xml</code>.', 'bwp-simple-gxs') => 'enable_news_sitemap'), 'cb2' => array(__('Keywords are derived from', 'bwp-simple-gxs') => 'enable_news_keywords'), 'cb3' => array(__('This ping works separately from the sitemapindex ping, and only occurs when you publish an article in one of the news categories set below.', 'bwp-simple-gxs') => 'enable_news_ping'), 'cb4' => array(__('This mode is meant for News Blogs that have posts assigned to more than one categories. It is an advanced feature and should only be enabled if you do have similar blogs.', 'bwp-simple-gxs') => 'enable_news_multicat')), 'inline_fields' => array('cb2' => array('select_news_keyword_type' => 'select')), 'post' => array('select_news_keyword_type' => __('. Do <strong>NOT</strong> use news tags if your news sitemap contains a lot of posts as it can be very inefficient to do so. This will be improved in future versions.', 'bwp-simple-gxs')), 'container' => array('select_news_cat_action' => $this->get_news_cats()));
                     // Get the options
                     $options = $bwp_option_page->get_options(array('enable_news_sitemap', 'enable_news_ping', 'enable_news_keywords', 'enable_news_multicat', 'select_news_lang', 'select_news_keyword_type', 'select_news_cat_action', 'select_news_cats', 'input_news_genres'), $this->options);
                     // Get option from the database
                     $options = $bwp_option_page->get_db_options($page, $options);
                     $options['select_news_cats'] = $this->options['select_news_cats'];
                     $options['input_news_genres'] = $this->options['input_news_genres'];
                     $option_ignore = array('select_news_cats', 'input_news_genres');
                     $option_formats = array();
                     $option_super_admin = $this->site_options;
                 }
             }
         }
     }
     // Flush the cache
     if (isset($_POST['flush_cache']) && !$this->is_normal_admin()) {
         check_admin_referer($page);
         if ($deleted = $this->flush_cache()) {
             $this->add_notice('<strong>' . __('Notice', 'bwp-simple-gxs') . ':</strong> ' . sprintf(__("<strong>%d</strong> cached sitemaps have been flushed successfully!", 'bwp-simple-gxs'), $deleted));
         } else {
             $this->add_notice('<strong>' . __('Notice', 'bwp-simple-gxs') . ':</strong> ' . __("Could not delete any cached sitemaps. Please manually check the cache directory.", 'bwp-simple-gxs'));
         }
     }
     // Get option from user input
     if (isset($_POST['submit_' . $bwp_option_page->get_form_name()]) && isset($options) && is_array($options)) {
         check_admin_referer($page);
         $need_flushed = false;
         foreach ($options as $key => &$option) {
             $pre_option = $option;
             // Get rid of options that do not have a key
             if (preg_match('/^[0-9]+$/i', $key)) {
                 unset($options[$key]);
                 continue;
             }
             // [WPMS Compatible]
             if ($this->is_normal_admin() && in_array($key, $option_super_admin)) {
             } else {
                 if (in_array($key, $option_ignore)) {
                 } else {
                     if (isset($_POST[$key])) {
                         $bwp_option_page->format_field($key, $option_formats);
                     }
                     if (!isset($_POST[$key])) {
                         $option = '';
                     } else {
                         if (isset($option_formats[$key]) && 0 == $_POST[$key] && 'int' == $option_formats[$key]) {
                             $option = 0;
                         } else {
                             if (isset($option_formats[$key]) && empty($_POST[$key]) && 'int' == $option_formats[$key]) {
                                 $option = $this->options_default[$key];
                             } else {
                                 if (!empty($_POST[$key])) {
                                     $option = trim(stripslashes($_POST[$key]));
                                 } else {
                                     $option = $this->options_default[$key];
                                 }
                             }
                         }
                     }
                     // Mark that we need to flush rewrite rules
                     if (false !== strpos($key, 'enable_sitemap_') && $pre_option != $option) {
                         $need_flushed = true;
                     }
                 }
             }
         }
         update_option($page, $options);
         // Flush rewrite rules if needed
         if ($need_flushed) {
             self::flush_rewrite_rules();
         }
         // [WPMS Compatible]
         if (!$this->is_normal_admin()) {
             update_site_option($page, $options);
         }
         // Update options successfully
         $this->add_notice(__("All options have been saved.", 'bwp-simple-gxs'));
     }
     // [WPMS Compatible]
     if (!$this->is_multisite() && $page == BWP_GXS_OPTION_GENERATOR) {
         $bwp_option_page->kill_html_fields($form, array(14));
     }
     if ($this->is_normal_admin()) {
         switch ($page) {
             case BWP_GXS_OPTION_GENERATOR:
                 $bwp_option_page->kill_html_fields($form, array(9, 10, 13, 14, 18, 19, 20, 21, 22, 23, 24, 25));
                 break;
             case BWP_GXS_STATS:
                 $bwp_option_page->kill_html_fields($form, array(3, 4, 5, 6, 7, 8));
                 add_filter('bwp_option_submit_button', create_function('', 'return "";'));
                 break;
         }
     }
     if (!@file_exists($this->options['input_cache_dir']) || !@is_writable($this->options['input_cache_dir'])) {
         $this->add_notice('<strong>' . __('Warning') . ':</strong> ' . __("Cache directory does not exist or is not writable. Please read more about directory permission <a href='http://www.zzee.com/solutions/unix-permissions.shtml'>here</a> (Unix).", 'bwp-simple-gxs'));
     }
     // Assign the form and option array
     $bwp_option_page->init($form, $options + $dynamic_options, $this->form_tabs);
     // Build the option page
     echo $bwp_option_page->generate_html_form();
 }
    /**
     * Build the option pages
     *
     * Utilizes BWP Option Page Builder (@see BWP_OPTION_PAGE)
     */
    function build_option_pages()
    {
        if (!current_user_can(BWP_RC_CAPABILITY)) {
            wp_die(__('You do not have sufficient permissions to access this page.'));
        }
        // Init the class
        $page = $_GET['page'];
        $bwp_option_page = new BWP_OPTION_PAGE($page, array(), 'bwp-rc');
        $options = array();
        if (!empty($page)) {
            if ($page == BWP_RC_OPTION_GENERAL) {
                $bwp_option_page->set_current_tab(1);
                // Option Structures - Form
                $form = array('items' => array('input', 'input', 'select', 'input', 'select', 'checkbox', 'heading', 'checkbox', 'checkbox', 'input', 'input', 'select', 'input', 'input', 'heading', 'input', 'input', 'input', 'checkbox', 'checkbox', 'checkbox'), 'item_labels' => array(__('Show at most', 'bwp-rc'), __('Show at most', 'bwp-rc'), __('Choose an output method', 'bwp-rc'), __('Group at most', 'bwp-rc'), __('Show', 'bwp-rc'), __('Enable AJAX navigation?', 'bwp-rc'), __('Formatting Options', 'bwp-rc'), __('Enable gravatars?', 'bwp-rc'), __('Convert smilies?', 'bwp-rc'), __('Trim post titles to', 'bwp-rc'), __('Trim comments to', 'bwp-rc'), __('With long words, this plugin should', 'bwp-rc'), __('Split into chunks of', 'bwp-rc'), __('Choose a date format', 'bwp-rc'), __('Miscellaneous', 'bwp-rc'), __('Show this message', 'bwp-rc'), __('Show this message', 'bwp-rc'), __('Hide comments by specific ids', 'bwp-rc'), __('Disable trackbacks/pingbacks from this website?', 'bwp-rc'), __('Use CSS provided by this plugin?', 'bwp-rc'), __('Give the author credits?', 'bwp-rc')), 'heading' => array('h1' => __('<em>This section allows you to customize how recent comments would appear on your website. Currently, options in this section are global which mean they will affect all recent comment list instances you create.</em>', 'bwp-rc'), 'h2' => __('<em>Other options that fit nowhere.</em>', 'bwp-rc')), 'item_names' => array('input_comments', 'input_tbs', 'select_output_method', 'input_group_comments', 'select_order', 'cb7', 'h1', 'cb1', 'cb2', 'input_title_trim', 'input_trim', 'select_long_method', 'input_chunk', 'input_date', 'h2', 'input_no_found', 'input_trimmed', 'input_ignore_ids', 'cb4', 'cb5', 'cb6'), 'checkbox' => array('cb1' => array(__('and each gravatar will be', 'bwp-rc') => 'enable_gravatars'), 'cb2' => array(__('Smilies such as <code>:-)</code> and <code>:-P</code> will be converted to icons.', 'bwp-rc') => 'enable_smilies'), 'cb4' => array(sprintf(__('All trackbacks/pingbacks originating from <code>%s</code> will be ignored.', 'bwp-rc'), get_option('home')) => 'disable_own_tb'), 'cb5' => array(__('If you disable this, be sure to add needed styles to your own stylesheets.', 'bwp-rc') => 'enable_css'), 'cb6' => array(__('A link to this plugin\'s official page will be added to the end of the of output of the first recent comment instance (i.e. only once). Thank you!', 'bwp-rc') => 'enable_credit'), 'cb7' => array(__('Navigation links will be added to the end of your comment list so that visitors can browse through them conveniently. You can also edit the templates for those links in the Template tab.', 'bwp-rc') => 'enable_ajax_nav')), 'select' => array('select_output_method' => array(__('Do not show trackbacks/pingbacks', 'bwp-rc') => 'only_comments', __('Show all comment types together', 'bwp-rc') => 'all_comments', __('Show all comment types, but separately', 'bwp-rc') => 'all_sep_comments'), 'select_order' => array(__('Newer comments first', 'bwp-rc') => 'desc', __('Older comments first', 'bwp-rc') => 'asc'), 'select_long_method' => array(__('Let the style handle the overflow', 'bwp-rc') => 'long_overflow', __('Split the words into smaller chunks', 'bwp-rc') => 'long_break')), 'input' => array('input_comments' => array('size' => 5, 'label' => __('recent comments.', 'bwp-rc')), 'input_tbs' => array('size' => 5, 'label' => __('recent trackbacks/pingbacks (used when choose "separate" as output method.)', 'bwp-rc')), 'input_group_comments' => array('size' => 5, 'label' => __('comments for each post (0 to disable)', 'bwp-rc')), 'input_date' => array('size' => 10, 'label' => __('To choose an appropriate format, please consult <a href="http://codex.wordpress.org/Formatting_Date_and_Time" target="_blank">WordPress Codex</a>.', 'bwp-rc')), 'input_gravatar_width' => array('size' => 5, 'label' => __('pxs wide.', 'bwp-rc')), 'input_title_trim' => array('size' => 5, 'label' => __('words. If you specify <code>0</code>, no trim will occur.', 'bwp-rc')), 'input_trim' => array('size' => 5, 'label' => __('words. If you specify <code>0</code>, no trim will occur (not recommended).', 'bwp-rc')), 'input_chunk' => array('size' => 5, 'label' => __('characters. If you choose to split the long words, it will be split into chunks with such characters maximum.', 'bwp-rc')), 'input_no_found' => array('size' => 40, 'label' => __('when no comment/pingbacks found.', 'bwp-rc')), 'input_trimmed' => array('size' => 40, 'label' => __('when the comment excerpt is trimmed to empty.', 'bwp-rc')), 'input_ignore_ids' => array('size' => 20, 'label' => __('Separate user ids by commas, e.g. 1,2,3. Leave blank if not used.', 'bwp-rc'))), 'container' => array('cb7' => __('<em><strong>Note:</strong> If you use the template function <code>bwp_get_recent_comments()</code> or widgets to show the comment list, you can override the options here. Please note that you can not override options for the global list.</em>', 'bwp-rc'), 'input_chunk' => __('<em><strong>Note:</strong> Long words (without spaces) posted by visitors, such as <code>YEAHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH</code>, might break your layout. If you use the default css provided by this plugin, it should handle such behaviour already (by adding <code>overflow: hidden</code> to the <code>recent-comment-text</code> class.) Splitting long words might result in unexpected results so it\'s best to just stick to css. If you want, you can use both methods, of course!</em>', 'bwp-rc')), 'inline_fields' => array('cb1' => array('input_gravatar_width' => 'input')));
                // Get the default options
                $options = $bwp_option_page->get_options(array('input_comments', 'input_tbs', 'select_output_method', 'input_group_comments', 'select_order', 'enable_gravatars', 'input_gravatar_width', 'enable_smilies', 'input_title_trim', 'input_trim', 'select_long_method', 'input_chunk', 'input_date', 'enable_css', 'enable_credit', 'input_ignore_ids', 'disable_own_tb', 'input_no_found', 'input_trimmed', 'enable_selective', 'enable_ajax_nav'), $this->options);
                // Get option from the database
                $options = $bwp_option_page->get_db_options($page, $options);
                $option_formats = array('input_comments' => 'int', 'input_tbs' => 'int', 'input_group_comments' => 'int', 'input_gravatar_width' => 'int', 'input_title_trim' => 'int', 'input_trim' => 'int', 'input_chunk' => 'int', 'input_no_found' => 'html', 'input_trimmed' => 'html');
            } else {
                if ($page == BWP_RC_OPTION_TEMPLATE) {
                    $bwp_option_page->set_current_tab(2);
                    //add_filter('bwp_ad_showable', function() { return false;});
                    // Option Structures - Form
                    $form = array('items' => array('heading', 'textarea', 'textarea', 'textarea', 'textarea', 'heading', 'textarea', 'textarea', 'heading', 'textarea', 'textarea'), 'item_labels' => array(__('Templates for your recent comment list', 'bwp-rc'), __('Template for comments', 'bwp-rc'), __('Template for trackbacks/pingbacks', 'bwp-rc'), __('Template for comments by you', 'bwp-rc'), sprintf(__('Template for paginated comments on a separate page &mdash; <a href="%s#comments_on_page" target="_blank">more info</a>', 'bwp-rc'), $this->plugin_url), __('Templates for grouped comments', 'bwp-rc'), __('Header template for a comment group, should start with <code>&lt;li&gt;</code> and end with <code>&lt;ul&gt;</code>', 'bwp-rc'), __('Footer template for a comment group, should start with <code>&lt;/ul&gt;</code> and end with <code>&lt;/li&gt;</code>', 'bwp-rc'), __('Templates for AJAX navigation', 'bwp-rc'), __('<em>View older comments</em> template', 'bwp-rc'), __('<em>View newer comments</em> template ', 'bwp-rc')), 'item_names' => array('h1', 'template_comment', 'template_tbpb', 'template_owner', 'template_paged_comment', 'h2', 'template_group_header', 'template_group_footer', 'h3', 'template_ajax_older', 'template_ajax_newer'), 'heading' => array('h1' => __('<em>This section allows you to define your own template. Use tags listed below to add appropriate contents. Please note that after you press reset, you still have to press submit changes for the changes to be saved.</em>', 'bwp-rc'), 'h2' => __('<em>Edit the header and footer templates for a comment group. All tags listed above can be used.</em>', 'bwp-rc'), 'h3' => __('<em>Edit the Older and Newer buttons for AJAX navigation. Make sure the CSS classes, i.e. <strong>bwp-rc-older-nav</strong> and <strong>bwp-rc-newer-nav</strong> are left untouched. If you would like to add more classes to style, add them like this: <code>class="bwp-rc-older-nav my-class1 my-class2"</code>.</em>', 'bwp-rc')), 'textarea' => array('template_comment' => array('cols' => 70, 'rows' => 5), 'template_paged_comment' => array('cols' => 70, 'rows' => 5), 'template_owner' => array('cols' => 70, 'rows' => 5), 'template_tbpb' => array('cols' => 70, 'rows' => 5), 'template_group_header' => array('cols' => 70, 'rows' => 5), 'template_group_footer' => array('cols' => 70, 'rows' => 5), 'template_ajax_older' => array('cols' => 70, 'rows' => 2), 'template_ajax_newer' => array('cols' => 70, 'rows' => 2)), 'inline' => array('template_comment' => '<br /><br /><input type="submit" class="button" name="reset_comment" value="' . __('Reset', 'bwp-rc') . '" />', 'template_paged_comment' => '<br /><br /><input type="submit" class="button" name="reset_paged" value="' . __('Reset', 'bwp-rc') . '" />', 'template_owner' => '<br /><br /><em>' . __('Leave this blank if you do not wish to use.', 'bwp-rc') . '</em>', 'template_tbpb' => '<br /><br /><input type="submit" class="button" name="reset_tbpb" value="' . __('Reset', 'bwp-rc') . '" />', 'template_group_header' => '<br /><br /><input type="submit" class="button" name="reset_group_header" value="' . __('Reset', 'bwp-rc') . '" />', 'template_group_footer' => '<br /><br /><input type="submit" class="button" name="reset_group_footer" value="' . __('Reset', 'bwp-rc') . '" />', 'template_ajax_older' => '<br /><br /><input type="submit" class="button" name="reset_ajax_older" value="' . __('Reset', 'bwp-rc') . '" />', 'template_ajax_newer' => '<br /><br /><input type="submit" class="button" name="reset_ajax_newer" value="' . __('Reset', 'bwp-rc') . '" />'), 'container' => array('h1' => '
	<code>%excerpt%</code> - <em>' . __('Trimmed down comment', 'bwp-rc') . '</em><br />
	<code>%link%</code> - <em>' . __('The comment\'s permalink', 'bwp-rc') . '</em><br />
	<code>%author%</code> - <em>' . __('The name of the visitor', 'bwp-rc') . '</em><br />
	<code>%author_url%</code> - <em>' . __('Link to the author\'s website or trackback/pingback\'s source', 'bwp-rc') . '</em><br />
	<code>%author_archive%</code> - <em>' . __('Link to the author\'s post archive, if none found, author\'s name will be used', 'bwp-rc') . '</em><br />
	<code>%time%</code> - <em>' . __('The timestamp of the comment', 'bwp-rc') . '</em><br />
	<code>%avatar%</code> - <em>' . __('Avatar of the visitor (in HTML)', 'bwp-rc') . '</em><br />
	<code>%post_title%</code> - <em>' . __('Title of the post', 'bwp-rc') . '</em><br />
	<code>%post_title_attr%</code> - <em>' . __('Title of the post that has been properly escaped for title attribute', 'bwp-rc') . '</em><br />
	<code>%post_link%</code> - <em>' . __('The post\'s permalink', 'bwp-rc') . '</em><br />
	<code>%comment_count%</code> - <em>' . __('The post\'s comment count', 'bwp-rc') . '</em><br />
	<code>%home%</code> - <em>' . __('The URL to your homepage', 'bwp-rc') . '</em><br />
	<code>%comment_number%</code> - <em>' . __('A comment\'s ordinal number (#1, #2, #3, etc.)', 'bwp-rc') . '</em>'));
                    // Get the default options
                    $options = $bwp_option_page->get_options(array('template_comment', 'template_paged_comment', 'template_tbpb', 'template_owner', 'template_group_header', 'template_group_footer', 'template_ajax_older', 'template_ajax_newer'), $this->options);
                    // Get option from the database
                    $options = $bwp_option_page->get_db_options($page, $options);
                    $option_formats = array('template_comment' => 'html', 'template_paged_comment' => 'html', 'template_tbpb' => 'html', 'template_owner' => 'html', 'template_group_header' => 'html', 'template_group_footer' => 'html', 'template_ajax_older' => 'html', 'template_ajax_newer' => 'html');
                    // Reset button
                    if (isset($_POST['reset_comment'])) {
                        $options['template_comment'] = $this->options_default['template_comment'];
                    }
                    if (isset($_POST['reset_tbpb'])) {
                        $options['template_tbpb'] = $this->options_default['template_tbpb'];
                    }
                    if (isset($_POST['reset_paged'])) {
                        $options['template_paged_comment'] = $this->options_default['template_paged_comment'];
                    }
                    if (isset($_POST['reset_group_header'])) {
                        $options['template_group_header'] = $this->options_default['template_group_header'];
                    }
                    if (isset($_POST['reset_group_footer'])) {
                        $options['template_group_footer'] = $this->options_default['template_group_footer'];
                    }
                    if (isset($_POST['reset_ajax_older'])) {
                        $options['template_ajax_older'] = $this->options_default['template_ajax_older'];
                    }
                    if (isset($_POST['reset_ajax_newer'])) {
                        $options['template_ajax_newer'] = $this->options_default['template_ajax_newer'];
                    }
                } else {
                    if ($page == BWP_RC_INSTANCES) {
                        $bwp_option_page->set_current_tab(3);
                        // Option Structures - Form
                        $form = array('items' => array('heading', 'select', 'heading'), 'item_labels' => array(__('List of all instances you have created', 'bwp-rc'), __('Choose an instance to delete', 'bwp-rc'), __('Reset all instances', 'bwp-rc')), 'item_names' => array('h1', 'sel1', 'h2'), 'heading' => array('h1' => __('Here you can see all instances you have created and currently you can delete any instance you don\'t use anymore.', 'bwp-rc'), 'h2' => __('If for some reasons you can not delelete an instance above (mostly because of malformed instances produced by previous versions\' bugs), you will have to reset all your instances here. Don\'t worry, though, all instances should be re-created automatically after you refresh public pages with comment instances on them.', 'bwp-rc')), 'select' => array('sel1' => array(__('----------', 'bwp-rc') => '')), 'container' => array('sel1' => '<input type="submit" class="button" name="delete_instance" value="' . __('Delete selected instance', 'bwp-rc') . '" />', 'h2' => '<input type="submit" class="button" name="reset_instances" value="' . __('Reset all instances now!', 'bwp-rc') . '" />'));
                        if (isset($_POST['delete_instance']) && !empty($_POST['sel1']) && isset($this->instances[$_POST['sel1']])) {
                            check_admin_referer($page);
                            delete_option($_POST['sel1']);
                            unset($this->instances[$_POST['sel1']]);
                            update_option(BWP_RC_INSTANCES, $this->instances);
                        } else {
                            if (isset($_POST['reset_instances'])) {
                                $this->reset_instances();
                            }
                        }
                        $options = NULL;
                        // @since 1.0.1
                        if (!is_array($this->instances)) {
                            $this->reset_instances();
                        }
                        foreach ($this->instances as $instance_name => $instance) {
                            if ($instance_name != BWP_RC_LIST) {
                                $form['select']['sel1'][$this->str_replace_first('bwp_rc_instance_', '', $instance_name)] = $instance_name;
                            }
                        }
                        $option_formats = array();
                        add_filter('bwp_option_submit_button', create_function('', 'return "";'));
                    }
                }
            }
        }
        // Get option from user input
        if (isset($_POST['submit_' . $bwp_option_page->get_form_name()]) && isset($options) && is_array($options)) {
            check_admin_referer($page);
            foreach ($options as $key => &$option) {
                if (isset($_POST[$key])) {
                    $bwp_option_page->format_field($key, $option_formats);
                }
                if (!isset($_POST[$key])) {
                    $option = '';
                } else {
                    if (isset($option_formats[$key]) && 0 == $_POST[$key] && 'int' == $option_formats[$key]) {
                        $option = 0;
                    } else {
                        if (isset($option_formats[$key]) && empty($_POST[$key]) && 'int' == $option_formats[$key]) {
                            $option = $this->options_default[$key];
                        } else {
                            if (!empty($_POST[$key])) {
                                $option = trim(stripslashes($_POST[$key]));
                            } else {
                                $option = '';
                            }
                        }
                    }
                }
            }
            update_option($page, $options);
            // Update options successfully
            $this->add_notice(__('All options have been saved.', 'bwp-rc'));
            // Do this for this plugin only
            $this->options = array_merge($this->options, $options);
        }
        // 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();
        // update the comment list automatically
        do_action('bwp_rc_form_loaded');
    }