Exemple #1
0
 function log($message = '', $type = 'notice')
 {
     global $wp_filesystem;
     WP_Filesystem();
     // if we're not active, don't do anything
     if (!$this->active || !file_exists($this->logfile)) {
         return false;
     }
     // get the existing log
     $existing = $wp_filesystem->get_contents($this->logfile);
     // format our entry
     $entry = '[' . date('Y-d-m G:i:s', current_time('timestamp')) . '][' . sanitize_text_field($type) . ']';
     // flag it with the process ID
     $entry .= '[' . SearchWP::instance()->getPid() . ']';
     // sanitize the message
     $message = sanitize_text_field(esc_html($message));
     $message = str_replace('=>', '=>', $message);
     // put back array identifiers
     $message = str_replace('->', '->', $message);
     // put back property identifiers
     $message = str_replace(''', "'", $message);
     // put back apostrophe's
     // finally append the message
     $entry .= ' ' . $message;
     // append the entry
     $log = $existing . "\n" . $entry;
     // write log
     $wp_filesystem->put_contents($this->logfile, $log);
     error_log($log);
 }
 /**
  * Perform a search via SearchWP
  *
  * @since 1.0
  *
  * @param string $query The search query
  *
  * @uses sanitize_text_field() to sanitize input
  * @uses add_filter() to hook into SearchWP (if applicable) to allow custom pagination and prevent full Post object loading
  * @uses SearchWP::instance() to retrieve the SearchWP singleton (if applicable)
  * @uses SearchWP::search() to perform a SearchWP-powered search (if applicable)
  *
  * @return array Search results comprised of Post IDs
  */
 function searchwp($query = '')
 {
     $posts = array(0);
     if (class_exists('SearchWP')) {
         $searchwp = SearchWP::instance();
         // set up custom posts per page
         add_filter('searchwp_posts_per_page', array($this, 'get_posts_per_page'));
         // prevent loading Post objects, we only want IDs
         add_filter('searchwp_load_posts', '__return_false');
         $engine = isset($_REQUEST['swpengine']) ? sanitize_text_field($_REQUEST['swpengine']) : 'default';
         // grab our post IDs
         $results = $searchwp->search($engine, $query);
         // if no results were found we need to force our impossible array
         if (!empty($results)) {
             $posts = $results;
         }
     }
     return $posts;
 }
    function plugin_row()
    {
        if (!class_exists('SearchWP')) {
            ?>
			<tr class="plugin-update-tr searchwp">
				<td colspan="3" class="plugin-update">
					<div class="update-message">
						<?php 
            _e('SearchWP must be active for Term Highlight to work', 'searchwp');
            ?>
					</div>
				</td>
			</tr>
		<?php 
        } else {
            $searchwp = SearchWP::instance();
            if (version_compare($searchwp->version, '1.9.5', '<')) {
                ?>
				<tr class="plugin-update-tr searchwp">
					<td colspan="3" class="plugin-update">
						<div class="update-message">
							<?php 
                _e('SearchWP Term Highlight requires SearchWP 1.9.5 or greater', 'searchwp');
                ?>
						</div>
					</td>
				</tr>
			<?php 
            }
        }
    }
    /**
     * Back-end widget form.
     *
     * @see WP_Widget::form()
     *
     * @param array $instance Previously saved values from database.
     *
     * @return string|void
     */
    public function form($instance)
    {
        $widget_title = isset($instance['title']) ? $instance['title'] : __('Search', 'swplas');
        $widget_placeholder = isset($instance['placeholder']) ? $instance['placeholder'] : __('Search for...', 'swplas');
        $widget_destination = isset($instance['destination']) ? $instance['destination'] : '';
        // we'll piggyback SearchWP itself to pull a list of search engines
        $widget_engine = isset($instance['engine']) ? $instance['engine'] : 'default';
        $engines = array();
        if (class_exists('SearchWP')) {
            $engines['default'] = 'Default';
            $searchwp = SearchWP::instance();
            $searchwp_engines = $searchwp->settings['engines'];
            foreach ($searchwp_engines as $engine => $engine_settings) {
                if (isset($engine_settings['searchwp_engine_label'])) {
                    $engines[$engine] = $engine_settings['searchwp_engine_label'];
                }
            }
        }
        // we're going to utilize SearchWP_Live_Search_Form to populate the config dropdown
        $widget_config = isset($instance['config']) ? $instance['config'] : 'default';
        if (!class_exists('SearchWP_Live_Search_Form')) {
            include_once dirname(__FILE__) . '/class-form.php';
        }
        $form = new SearchWP_Live_Search_Form();
        $form->setup();
        ?>

		<p>
			<label for="<?php 
        echo $this->get_field_id('title');
        ?>
"><?php 
        _e('Title:');
        ?>
</label>
			<input class="widefat" id="<?php 
        echo $this->get_field_id('title');
        ?>
" name="<?php 
        echo $this->get_field_name('title');
        ?>
" type="text" value="<?php 
        echo esc_attr($widget_title);
        ?>
">
		</p>
		<?php 
        if (!empty($engines)) {
            ?>
		<p>
			<label for="<?php 
            echo $this->get_field_id('engine');
            ?>
"><?php 
            _e('SearchWP Engine:');
            ?>
</label>
			<select name="<?php 
            echo $this->get_field_name('engine');
            ?>
" id="<?php 
            echo $this->get_field_id('engine');
            ?>
">
				<?php 
            foreach ($engines as $engine_name => $engine_label) {
                ?>
					<option value="<?php 
                echo esc_attr($engine_name);
                ?>
" <?php 
                selected($widget_engine, $engine_name);
                ?>
><?php 
                echo esc_html($engine_label);
                ?>
</option>
				<?php 
            }
            ?>
			</select>
		</p>
		<?php 
        }
        ?>
		<p>
			<label for="<?php 
        echo $this->get_field_id('config');
        ?>
"><?php 
        _e('Configuration:');
        ?>
</label>
			<select name="<?php 
        echo $this->get_field_name('config');
        ?>
" id="<?php 
        echo $this->get_field_id('config');
        ?>
">
				<?php 
        foreach ($form->configs as $config => $val) {
            ?>
					<option value="<?php 
            echo esc_attr($config);
            ?>
" <?php 
            selected($widget_config, $config);
            ?>
><?php 
            echo esc_html($config);
            ?>
</option>
				<?php 
        }
        ?>
			</select>
		</p>
		<?php 
        $swpuniqid = uniqid('swp');
        ?>
		<p><a href="#" class="button searchwp-widget-<?php 
        echo $swpuniqid;
        ?>
"><?php 
        _e('Advanced', 'searchwp');
        ?>
</a></p>
		<div class="searchwp-live-search-widget-advanced" style="display:none;">
			<p>
				<label for="<?php 
        echo $this->get_field_id('placeholder');
        ?>
"><?php 
        _e('Placholder:');
        ?>
</label>
				<input class="widefat" id="<?php 
        echo $this->get_field_id('placeholder');
        ?>
" name="<?php 
        echo $this->get_field_name('placeholder');
        ?>
" type="placeholder" value="<?php 
        echo esc_attr($widget_placeholder);
        ?>
">
			</p>
			<p>
				<label for="<?php 
        echo $this->get_field_id('destination');
        ?>
"><?php 
        _e('Destination fallback URL (optional):');
        ?>
</label>
				<input class="widefat" id="<?php 
        echo $this->get_field_id('destination');
        ?>
" name="<?php 
        echo $this->get_field_name('destination');
        ?>
" type="text" value="<?php 
        echo esc_attr($widget_destination);
        ?>
">
			</p>
		</div>
		<script type="text/javascript">
			jQuery(document).ready(function($){
				$('.searchwp-widget-<?php 
        echo $swpuniqid;
        ?>
').click(function(){
					var $advanced = $(this).parents().find('.searchwp-live-search-widget-advanced');
					if($advanced.is(':visible')){
						$advanced.hide();
					}else{
						$advanced.show();
					}
					return false;
				});
			});
		</script>
	<?php 
    }
 /**
  * Constructor
  *
  * @param array $args
  * @since 1.0
  */
 function __construct($args = array())
 {
     global $wpdb, $searchwp;
     do_action('searchwp_log', 'SearchWPSearch __construct()');
     $defaults = array('terms' => '', 'engine' => 'default', 'page' => 1, 'posts_per_page' => intval(get_option('posts_per_page')), 'order' => $this->order, 'load_posts' => true);
     $this->db_prefix = $wpdb->prefix . SEARCHWP_DBPREFIX;
     // process our arguments
     $args = wp_parse_args($args, $defaults);
     $this->searchwp = SearchWP::instance();
     // instantiate our stemmer for later
     $this->stemmer = new SearchWPStemmer();
     do_action('searchwp_log', '$args = ' . var_export($args, true));
     // if we have a valid engine, perform the query
     if ($this->searchwp->is_valid_engine($args['engine'])) {
         // this filter is also applied in the SearchWP class search methods
         // TODO: should this be applied in both places? which?
         $sanitizeTerms = apply_filters('searchwp_sanitize_terms', true, $args['engine']);
         if (!is_bool($sanitizeTerms)) {
             $sanitizeTerms = true;
         }
         // whitelist search terms
         $pre_whitelist_terms = is_array($args['terms']) ? implode(' ', $args['terms']) : $args['terms'];
         $whitelisted_terms = $this->searchwp->extract_terms_using_pattern_whitelist($pre_whitelist_terms, false);
         // TODO: if $whitelisted_terms has matches with spaces, there will be dupes: do we need to loop through and remove?
         // store the original search query (e.g. logging)
         $pre_search_original_terms = '';
         if (!empty($searchwp->original_query)) {
             $pre_search_original_terms = trim($searchwp->original_query);
         } elseif (!empty($args['terms'])) {
             // might have been instantiated directly, use the terms from the args
             $pre_search_original_terms = is_array($args['terms']) ? implode(' ', $args['terms']) : $args['terms'];
             $pre_search_original_terms = trim($pre_search_original_terms);
         }
         if ($sanitizeTerms) {
             $terms = $this->searchwp->sanitize_terms($args['terms']);
         } else {
             $terms = $args['terms'];
             do_action('searchwp_log', 'Opted out of internal sanitization');
         }
         if (is_array($whitelisted_terms)) {
             $whitelisted_terms = array_filter(array_map('trim', $whitelisted_terms), 'strlen');
         }
         if (is_array($terms)) {
             $terms = array_filter(array_map('trim', $terms), 'strlen');
             $terms = array_merge($terms, $whitelisted_terms);
         } else {
             $terms .= ' ' . implode(' ', $whitelisted_terms);
         }
         // make sure the terms are unique, especially after whitelist matching
         if (is_array($terms)) {
             $terms = array_unique($terms);
             $terms = array_filter($terms, 'strlen');
         }
         $engine = $args['engine'];
         // allow dev to customize post statuses are included
         $this->post_statuses = (array) apply_filters('searchwp_post_statuses', $this->post_statuses, $engine);
         foreach ($this->post_statuses as $post_status_key => $post_status_value) {
             $this->post_statuses[$post_status_key] = sanitize_key($post_status_value);
         }
         do_action('searchwp_log', '$terms = ' . var_export($terms, true));
         if ('DESC' != strtoupper(apply_filters('searchwp_search_query_order', $args['order'])) && 'ASC' != strtoupper($args['order'])) {
             $args['order'] = 'DESC';
         }
         // filter the terms just before querying
         $terms = apply_filters('searchwp_pre_search_terms', $terms, $engine);
         do_action('searchwp_log', 'searchwp_pre_search_terms $terms = ' . var_export($terms, true));
         $this->terms = $terms;
         $this->engine = $engine;
         $this->settings = empty($searchwp) ? get_option(SEARCHWP_PREFIX . 'settings') : $searchwp->settings;
         $this->page = absint($args['page']);
         $this->postsPer = intval($args['posts_per_page']);
         $this->order = $args['order'];
         $this->load_posts = is_bool($args['load_posts']) ? $args['load_posts'] : true;
         $this->offset = isset($args['offset']) && !empty($args['offset']) ? absint($args['offset']) : 0;
         // if it's a native search we can piggyback default includes and excludes
         if (is_search()) {
             $this->set_default_include_and_exclude();
         }
         // perform our query
         $this->posts = $this->query();
         // log this
         if (!empty($pre_search_original_terms) && apply_filters('searchwp_log_search', true, $engine, $pre_search_original_terms, count($this->posts))) {
             $pre_search_original_terms = sanitize_text_field($pre_search_original_terms);
             $pre_search_original_terms = trim($pre_search_original_terms);
             // respect database schema
             if (200 < strlen($pre_search_original_terms)) {
                 $pre_search_original_terms = substr($pre_search_original_terms, 0, 199);
             }
             if (!empty($pre_search_original_terms)) {
                 /** @noinspection PhpUnusedLocalVariableInspection */
                 $log_result = $wpdb->insert($this->db_prefix . 'log', array('event' => 'search', 'query' => $pre_search_original_terms, 'hits' => count($this->posts), 'engine' => $engine, 'wpsearch' => 0), array('%s', '%s', '%d', '%s', '%d'));
             }
         }
     }
 }
Exemple #6
0
    function plugin_row()
    {
        if (!class_exists('SearchWP')) {
            return;
        }
        $searchwp = SearchWP::instance();
        if (version_compare($searchwp->version, '2.0.3', '<')) {
            ?>
			<tr class="plugin-update-tr searchwp">
				<td colspan="3" class="plugin-update">
					<div class="update-message">
						<?php 
            _e('SearchWP Fuzzy Matches requires SearchWP 2.0.3 or greater', $searchwp->textDomain);
            ?>
					</div>
				</td>
			</tr>
		<?php 
        }
    }
 /**
  * Singleton
  *
  * @return SearchWP
  * @since 1.0
  */
 public static function instance()
 {
     if (!isset(self::$instance) && !self::$instance instanceof SearchWP) {
         // store background indexer request
         if (isset($_REQUEST['swpnonce'])) {
             searchwp_delete_option('indexnonce');
             searchwp_add_option('indexnonce', sanitize_text_field($_REQUEST['swpnonce']));
         }
         self::$instance = new SearchWP();
         self::$instance->init();
         // we want to purge a post from the index when comments are manipulated
         add_action('comment_post', array(self::$instance, 'purge_post_via_comment'));
         add_action('edit_comment', array(self::$instance, 'purge_post_via_comment'));
         add_action('trash_comment', array(self::$instance, 'purge_post_via_comment'));
         add_action('delete_comment', array(self::$instance, 'purge_post_via_comment'));
         add_action('delete_attachment', array(self::$instance, 'purge_post_via_edit'), 999);
         // purge a post from the index when a related term is deleted
         add_action('set_object_terms', array(self::$instance, 'purge_post_via_term'), 10, 6);
         // process the purge queue once everything is said and done
         add_action('shutdown', array(self::$instance, 'setup_purge_queue'));
         add_action('after_setup_theme', array(self::$instance, 'set_settings_cap'));
     }
     return self::$instance;
 }
 function do_searchwp_search($query_args)
 {
     // limit the pool WP Job Manager works from by providing our own post__in
     if (!empty($this->query) && class_exists('SearchWP')) {
         // we'll do our own keyword search (added in 1.21.4)
         remove_filter('posts_clauses', 'get_job_listings_keyword_search');
         remove_filter('posts_clauses', 'get_resumes_keyword_search');
         // instantiate SearchWP
         $engine = SearchWP::instance();
         // prevent pagination
         $query_args['posts_per_page'] = $this->posts_per_page;
         add_filter('searchwp_posts_per_page', array($this, 'posts_per_page'));
         // we only want post IDs
         add_filter('searchwp_load_posts', '__return_false');
         // perform the search
         $results = array(0);
         // fallback default
         if ($this->page) {
             // this is a resume search
             $results = $engine->search($this->search_engine_name, $this->query, $this->page);
         } else {
             $results = $engine->search($this->search_engine_name, $this->query);
         }
         // there is a chance this hook is being used elsewhere so before we blatantly
         // override post__in let's make sure we intersect it
         // make sure if it's defined it's an array
         if (!empty($query_args['post__in'])) {
             // make sure it's an array
             $source = $query_args['post__in'];
             if (is_string($source)) {
                 $source = explode(',', $source);
             }
             $source = array_map('trim', $source);
             $source = array_map('absint', $source);
             $source = array_unique($source);
             $query_args['post__in'] = $source;
         }
         // check to see if it's already being limited
         if (isset($query_args['post__in']) && is_array($query_args['post__in']) && count($query_args['post__in'])) {
             $query_args['post__in'] = array_intersect($query_args['post__in'], $results);
             // we may have (correctly) just zeroed out the results set
             // the radius limiter sets post__in to an array of results within that radius
             // but the keyword match may net zero results here, which is accurate
             if (empty($query_args['post__in'])) {
                 $query_args['post__in'] = array(0);
             }
         } else {
             // post__in wasn't set so let's just set it
             $query_args['post__in'] = $results;
             // if it was empty, we want to be sure it's empty
             if (empty($query_args['post__in'])) {
                 // no results, so force that
                 $query_args['post__in'] = array(0);
             }
         }
         // sort the results by SearchWP relevance
         if (!empty($query_args['post__in'])) {
             $query_args['orderby'] = 'post__in';
         }
         if (0 == count($results)) {
             // a search was submitted, but no results were found
             // so we need to force that by limiting post__in to
             // an impossible results set
             $query_args['post__in'] = array(0);
         }
         // if the developer really wants to, they can override the WP Job Manager restricted post_type
         if ($this->override_post_types) {
             // SearchWP's engine configuration will restrict this
             $query_args['post_type'] = 'any';
             $query_args['post_status'] = 'any';
         }
     }
     return $query_args;
 }
 /**
  * Search through the Docs for a given term.
  *
  * @param string $original_term term to search for.
  *
  * @return array Array with post ID's
  */
 public function search($original_term)
 {
     do_action('wpkb_search', $original_term);
     // use SearchWP if possible
     if (class_exists('SearchWP')) {
         $engine = \SearchWP::instance();
         $posts = $engine->search('wpkb_search', $original_term);
         if (is_array($posts)) {
             return $posts;
         }
         return array();
     }
     global $wpdb;
     // go for an easy escape if the original term is very short
     if (strlen($original_term) < 3) {
         return array();
     }
     // start building SQL query string
     $params = array();
     $string = '';
     $string .= "SELECT wpp.id";
     $string .= " FROM {$wpdb->posts} wpp";
     $string .= " LEFT JOIN {$wpdb->term_relationships} wptr ON wpp.id = wptr.object_id";
     $string .= " LEFT JOIN {$wpdb->term_taxonomy} wptt ON wptr.term_taxonomy_id = wptt.term_taxonomy_id";
     $string .= " LEFT JOIN {$wpdb->terms} wpt ON wpt.term_id = wptt.term_id";
     // only query post type doc
     $string .= " WHERE wpp.post_type = 'wpkb-article'";
     // only query published docs
     $string .= " AND wpp.post_status = 'publish'";
     // query each search word in post title, post content, docs keyword and docs category
     $string .= " AND (";
     // query title & content
     $string .= " wpp.post_title LIKE %s OR wpp.post_content LIKE '%s'";
     $params[] = '%%' . $original_term . '%%';
     $params[] = '%%' . $original_term . '%%';
     // query keywords
     $string .= " OR ( wptt.taxonomy = 'wpkb-keyword' AND wpt.name LIKE '%s' )";
     $params[] = '%%' . $original_term . '%%';
     // query category
     $string .= " OR ( wptt.taxonomy = 'wpkb-category' AND wpt.name LIKE '%s' )";
     $params[] = '%%' . $original_term . '%%';
     // close opened AND parenthesis
     $string .= " )";
     // group by post id
     $string .= " GROUP BY wpp.id";
     // prepare sql query string
     $query = $wpdb->prepare($string, $params);
     // execute query
     $results = $wpdb->get_results($query);
     if (!is_array($results) || count($results) === 0) {
         return array();
     }
     $ids = array_map(function ($p) {
         return $p->id;
     }, $results);
     $posts = get_posts(array('post_type' => Plugin::POST_TYPE_NAME, 'post__in' => $ids));
     return $posts;
 }
Exemple #10
0
 /**
  * Constructor
  *
  * @param array $args
  * @since 1.0
  */
 function __construct($args = array())
 {
     global $wpdb, $searchwp;
     do_action('searchwp_log', 'SearchWPSearch __construct()');
     $defaults = array('terms' => '', 'engine' => 'default', 'page' => 1, 'posts_per_page' => intval(get_option('posts_per_page')), 'order' => $this->order, 'load_posts' => true);
     $this->db_prefix = $wpdb->prefix . SEARCHWP_DBPREFIX;
     // process our arguments
     $args = wp_parse_args($args, $defaults);
     $this->searchwp = SearchWP::instance();
     // instantiate our stemmer for later
     $this->stemmer = new SearchWPStemmer();
     do_action('searchwp_log', '$args = ' . var_export($args, true));
     // if we have a valid engine, perform the query
     if ($this->searchwp->isValidEngine($args['engine'])) {
         // this filter is also applied in the SearchWP class search methods
         // TODO: should this be applied in both places? which?
         $sanitizeTerms = apply_filters('searchwp_sanitize_terms', true, $args['engine']);
         if (!is_bool($sanitizeTerms)) {
             $sanitizeTerms = true;
         }
         // whitelist search terms
         $pre_whitelist_terms = is_array($args['terms']) ? implode(' ', $args['terms']) : ' ' . $args['terms'] . ' ';
         $whitelisted_terms = $this->searchwp->extract_terms_using_pattern_whitelist($pre_whitelist_terms, false);
         // TODO: if $whitelisted_terms has matches with spaces, there will be dupes: do we need to loop through and remove?
         if ($sanitizeTerms) {
             $terms = $this->searchwp->sanitizeTerms($args['terms']);
         } else {
             $terms = $args['terms'];
             do_action('searchwp_log', 'Opted out of internal sanitization');
         }
         if (is_array($whitelisted_terms)) {
             $whitelisted_terms = array_filter(array_map('trim', $whitelisted_terms), 'strlen');
         }
         if (is_array($terms)) {
             $terms = array_filter(array_map('trim', $terms), 'strlen');
             $terms = array_merge($terms, $whitelisted_terms);
         } else {
             $terms .= ' ' . implode(' ', $whitelisted_terms);
         }
         // make sure the terms are unique, especially after whitelist matching
         if (is_array($terms)) {
             $terms = array_unique($terms);
             $terms = array_filter($terms, 'strlen');
         }
         $engine = $args['engine'];
         // allow dev to customize post statuses are included
         $this->post_statuses = (array) apply_filters('searchwp_post_statuses', $this->post_statuses, $engine);
         foreach ($this->post_statuses as $post_status_key => $post_status_value) {
             $this->post_statuses[$post_status_key] = sanitize_key($post_status_value);
         }
         do_action('searchwp_log', '$terms = ' . var_export($terms, true));
         if (strtoupper(apply_filters('searchwp_search_query_order', $args['order'])) != 'DESC' && strtoupper($args['order']) != 'ASC') {
             $args['order'] = 'DESC';
         }
         // filter the terms just before querying
         $terms = apply_filters('searchwp_pre_search_terms', $terms, $engine);
         do_action('searchwp_log', 'searchwp_pre_search_terms $terms = ' . var_export($terms, true));
         $this->terms = $terms;
         $this->engine = $engine;
         $this->settings = empty($searchwp) ? get_option(SEARCHWP_PREFIX . 'settings') : $searchwp->settings;
         $this->page = absint($args['page']);
         $this->postsPer = intval($args['posts_per_page']);
         $this->order = $args['order'];
         $this->load_posts = is_bool($args['load_posts']) ? $args['load_posts'] : true;
         // perform our query
         $this->posts = $this->query();
     }
 }
    /**
     * Callback for plugin row display
     */
    function plugin_row()
    {
        $searchwp = SearchWP::instance();
        if (version_compare($searchwp->version, '1.0.8', '<')) {
            ?>
            <tr class="plugin-update-tr searchwp">
                <td colspan="3" class="plugin-update">
                    <div class="update-message">
						<?php 
            esc_html_e('SearchWP Term Archive Priority requires SearchWP 1.0.8 or greater', 'searchwp');
            ?>
                    </div>
                </td>
            </tr>
		<?php 
        }
    }
    function plugin_row()
    {
        if (!class_exists('SearchWP')) {
            ?>
			<tr class="plugin-update-tr searchwp">
				<td colspan="3" class="plugin-update">
					<div class="update-message">
						<?php 
            _e('SearchWP must be active to use this Extension');
            ?>
					</div>
				</td>
			</tr>
		<?php 
        } else {
            ?>
			<?php 
            $searchwp = SearchWP::instance();
            ?>
			<?php 
            if (version_compare($searchwp->version, '1.3.3', '<')) {
                ?>
				<tr class="plugin-update-tr searchwp">
					<td colspan="3" class="plugin-update">
						<div class="update-message">
							<?php 
                _e('SearchWP Xpdf Integration requires SearchWP 1.3.3 or greater', 'searchwp');
                ?>
						</div>
					</td>
				</tr>
			<?php 
            }
            ?>
		<?php 
        }
    }