rebase from live enviornment

This commit is contained in:
Rachit Bhargava
2024-01-09 22:14:20 -05:00
parent ff0b49a046
commit 3a22fcaa4a
15968 changed files with 2344674 additions and 45234 deletions

View File

@@ -0,0 +1,76 @@
<?php
/**
* Plugin Name: Pantheon MU Plugin Loader
* Description: Loads the MU plugins required to run the site
* Author: Pantheon Systems
* Author URI: https://pantheon.io
* Version: 1.0
*/
if ( defined( 'WP_INSTALLING' ) && WP_INSTALLING ) {
return;
}
// Add mu-plugins here.
$pantheon_mu_plugins = [
'pantheon-mu-plugin/pantheon.php',
];
foreach ( $pantheon_mu_plugins as $file ) {
require_once WPMU_PLUGIN_DIR . '/' . $file;
}
unset( $file );
add_action( 'pre_current_active_plugins', function () use ( $pantheon_mu_plugins ) {
global $plugins, $wp_list_table;
// Add our own mu-plugins to the page.
foreach ( $pantheon_mu_plugins as $plugin_file ) {
// Do not apply markup/translate as it'll be cached.
$plugin_data = get_plugin_data( WPMU_PLUGIN_DIR . "/$plugin_file", false, false );
if ( empty( $plugin_data['Name'] ) ) {
$plugin_data['Name'] = $plugin_file;
}
$plugins['mustuse'][ $plugin_file ] = $plugin_data;
}
// Recount totals.
$GLOBALS['totals']['mustuse'] = count( $plugins['mustuse'] );
// Only apply the rest if we're actually looking at the page.
if ( $GLOBALS['status'] !== 'mustuse' ) {
return;
}
// Reset the list table's data.
$wp_list_table->items = $plugins['mustuse'];
foreach ( $wp_list_table->items as $plugin_file => $plugin_data ) {
$wp_list_table->items[ $plugin_file ] = _get_plugin_data_markup_translate( $plugin_file, $plugin_data, false, true );
}
$total_this_page = $GLOBALS['totals']['mustuse'];
if ( $GLOBALS['orderby'] ) {
uasort( $wp_list_table->items, [ $wp_list_table, '_order_callback' ] );
}
// Force showing all plugins.
// See https://core.trac.wordpress.org/ticket/27110.
$plugins_per_page = $total_this_page;
$wp_list_table->set_pagination_args( [
'total_items' => $total_this_page,
'per_page' => $plugins_per_page,
] );
});
add_filter( 'network_admin_plugin_action_links', function ( $actions, $plugin_file, $plugin_data, $context ) use ( $pantheon_mu_plugins ) {
if ( $context !== 'mustuse' || ! in_array( $plugin_file, $pantheon_mu_plugins, true ) ) {
return $actions;
}
$actions[] = sprintf( '<span style="color:#333">File: <code>%s</code></span>', $plugin_file );
return $actions;
}, 10, 4 );

View File

@@ -0,0 +1,3 @@
# Ignore composer files.
/vendor
composer.lock

View File

@@ -0,0 +1 @@
* @pantheon-systems/cms-platform

View File

@@ -0,0 +1,16 @@
# editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = tab
[{.jshintrc,*.json,*.yml}]
indent_style = space
indent_size = 2
[{*.txt,wp-config-sample.php}]
end_of_line = crlf

View File

@@ -0,0 +1,63 @@
#login {
width: 500px;
}
#return-to-pantheon {
margin-bottom: 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
#return-to-pantheon .left {
font-size: 16px;
font-weight: 400;
line-height: 1.4;
}
#return-to-pantheon a{
display: flex;
align-items: center;
justify-content: space-between;
color: #000000;
padding: 5px 10px;
background: #F8DD44;
color: #000000 !important;
text-decoration: none !important;
font-size: 12px;
text-align: center;
border-radius: 10px;
min-width: 130px
}
#return-to-pantheon a:hover {
-webkit-transition: all 0.25s;
-moz-transition: all 0.25s;
transition: all 0.25s;
background: #EFD01B;
color: #333333 !important;
}
#return-to-pantheon .fist-icon {
display: inline-block;
width: 12px;
margin-right: 5px;
}
@media (max-width: 499px) {
#login {
width: 320px;
}
#return-to-pantheon {
flex-direction: column;
}
#return-to-pantheon .left {
order: 2;
}
#return-to-pantheon .right {
margin-bottom: 25px;
order: 1;
}
}

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="14px" height="32px" viewBox="0 0 14 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
<title>Group 11</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="WP---button" transform="translate(-322.000000, -538.000000)" fill="#333333">
<g id="Group" transform="translate(311.000000, 534.000000)">
<g id="Group-11" transform="translate(11.000000, 4.000000)">
<path d="M1.54822908,0 L4.52272957,6.90999702 L0.736842105,6.90999702 L1.98837032,9.82347541 L9.66224514,9.82347541 L1.54822908,0 L1.54822908,0 Z M11.589856,24.7575559 L10.3368651,21.8425037 L8.57849426,21.8425037 L8.54163298,21.7553741 L6.11083637,16.1102593 L4.6957728,16.1102593 L7.16386951,21.8425037 L2.66269769,21.8425037 L10.7780302,31.6679821 L7.80265209,24.7575559 L11.589856,24.7575559 L11.589856,24.7575559 Z" id="Fill-1"></path>
<path d="M6.3944081,15.35938 L5.16291955,12.493687 L4.54724842,12.493687 L5.77976089,15.3559463 L3.74741716,15.3559463 L6.2165378,21.0911952 L1.18058487,21.0911952 C0.756241333,21.0911952 0.522640287,21.0911952 0.330873868,20.4898718 C0.102099894,19.7718033 0,18.2748614 0,15.6365067 C0,12.9982951 0.102099894,11.5016393 0.330873868,10.7831416 C0.522640287,10.1818182 0.756241333,10.1818182 1.18058487,10.1818182 L6.73391219,10.1818182 L8.96270314,15.35938 L6.3944081,15.35938 Z M12.6233793,18.7798987 C12.7164101,18.7798987 12.9331895,18.892924 12.9331895,19.9363338 C12.9331895,20.9791714 12.7164101,21.0911952 12.6233793,21.0911952 L8.86294364,21.0911952 L7.86842046,18.7798987 L12.6233793,18.7798987 Z M12.6233793,12.493687 L8.3441065,12.493687 L7.34958333,10.1818182 L12.6233793,10.1818182 C12.7164101,10.1818182 12.9331895,10.2944143 12.9331895,11.3369657 C12.9331895,12.3800894 12.7164101,12.493687 12.6233793,12.493687 Z M13.063228,15.9142057 C13.1571364,15.9142057 13.3739159,16.0268018 13.3739159,17.0699255 C13.3739159,18.1130492 13.1571364,18.225073 13.063228,18.225073 L7.6291147,18.225073 L6.63415269,15.9142057 L13.063228,15.9142057 Z M13.063228,13.0485127 C13.1571364,13.0485127 13.3739159,13.1601073 13.3739159,14.2036602 C13.3739159,15.2463547 13.1571364,15.35938 13.063228,15.35938 L9.57837427,15.35938 L8.58297345,13.0485127 L13.063228,13.0485127 Z" id="Path"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,8 @@
jQuery(document).ready(function( $ ) {
$('#return-to-pantheon')
.detach()
.prependTo('#loginform')
.show();
});

View File

@@ -0,0 +1,97 @@
<?php
/**
* WP-CLI commands for the Pantheon mu-plugin.
*
* @package pantheon
*/
namespace Pantheon\CLI;
use Pantheon_Cache;
use WP_CLI;
// Support the old pantheon-cache command but return a deprecation notice.
WP_CLI::add_command( 'pantheon-cache set-maintenance-mode', '\\Pantheon\\CLI\\__deprecated_maintenance_mode_output' );
WP_CLI::add_command( 'pantheon cache set-maintenance-mode', '\\Pantheon\\CLI\\set_maintenance_mode_command' );
WP_CLI::add_command( 'pantheon set-maintenance-mode', '\\Pantheon\\CLI\\set_maintenance_mode_command' );
/**
* Sets maintenance mode status.
*
* Enable maintenance mode to work on your site while serving cached pages
* to visitors and bots, or everyone except administators.
*
* ## DEPRECATION NOTICE
*
* This command is deprecated and will be removed in a future release.
* Use `pantheon set-maintenance-mode` instead.
*
* ## USAGE
*
* wp pantheon-cache set-maintenance-mode <status> (deprecated) or
* wp pantheon cache set-maintenance-mode <status>
*
* ## OPTIONS
*
* <status>
* : Maintenance mode status.
* ---
* options:
* - disabled
* - anonymous
* - everyone
* ---
*
* @subcommand set-maintenance-mode
*
* @deprecated 1.0.0
*/
function __deprecated_maintenance_mode_output( $args ) {
$allowed_args = [ 'disabled', 'anonymous', 'everyone' ];
$replacement_command = ( ! empty( $args && count( $args ) === 1 ) && in_array( $args[0], $allowed_args, true ) ) ? 'set-maintenance-mode ' . $args[0] : false;
// translators: %s is the replacement command.
WP_CLI::warning( WP_CLI::colorize( '%y' . sprintf( __( 'This command is deprecated and will be removed in a future release. Use `wp pantheon %s` instead.', 'pantheon-systems' ), $replacement_command ) . '%n' ) );
WP_CLI::line( __( 'Run `wp pantheon set-maintenance-mode --help` for more information.', 'pantheon-systems' ) );
// The command should fail before we get here, but in case it doesn't, display an error.
if ( false === $replacement_command ) {
WP_CLI::error( __( 'Invalid arguments. Run `wp pantheon set-maintenance-mode --help` for more infomation.', 'pantheon-systems' ) );
}
set_maintenance_mode_command( $args );
}
/**
* Sets maintenance mode status.
*
* Enable maintenance mode to work on your site while serving cached pages
* to visitors and bots, or everyone except administators.
*
* ## OPTIONS
*
* <status>
* : Maintenance mode status.
* ---
* options:
* - disabled
* - anonymous
* - everyone
* ---
*
* @subcommand set-maintenance-mode
*/
function set_maintenance_mode_command( $args ) {
list( $status ) = $args;
$out = Pantheon_Cache()->default_options;
if ( ! empty( $status )
&& in_array( $status, [ 'anonymous', 'everyone' ], true ) ) {
$out['maintenance_mode'] = $status;
} else {
$out['maintenance_mode'] = 'disabled';
}
update_option( Pantheon_Cache::SLUG, $out );
WP_CLI::success( sprintf( 'Maintenance mode set to: %s', $out['maintenance_mode'] ) );
}

View File

@@ -0,0 +1,704 @@
<?php
/**
* File mostly copied from wp-admin/includes/network.php.
*
* Changes:
* - Multisite instructions on step2
* - Text area rows increased
* - Allow altering config filename
* - Allow altering config contents
* - Remove if file_exists .htaccess
*/
/**
* Check for an existing network.
*
* @since 3.0.0
*
* @global wpdb $wpdb WordPress database abstraction object.
*
* @return string|false Base domain if network exists, otherwise false.
*/
function network_domain_check() {
global $wpdb;
$sql = $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $wpdb->site ) );
if ( $wpdb->get_var( $sql ) ) { // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
return $wpdb->get_var( "SELECT domain FROM $wpdb->site ORDER BY id ASC LIMIT 1" );
}
return false;
}
/**
* Allow subdomain installation
*
* @since 3.0.0
* @return bool Whether subdomain installation is allowed
*/
function allow_subdomain_install() {
$domain = preg_replace( '|https?://([^/]+)|', '$1', get_option( 'home' ) );
if ( parse_url( get_option( 'home' ), PHP_URL_PATH ) || 'localhost' === $domain || preg_match( '|^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$|', $domain ) ) {
return false;
}
return true;
}
/**
* Allow subdirectory installation.
*
* @since 3.0.0
*
* @global wpdb $wpdb WordPress database abstraction object.
*
* @return bool Whether subdirectory installation is allowed
*/
function allow_subdirectory_install() {
global $wpdb;
/**
* Filters whether to enable the subdirectory installation feature in Multisite.
*
* @since 3.0.0
*
* @param bool $allow Whether to enable the subdirectory installation feature in Multisite.
* Default false.
*/
if ( apply_filters( 'allow_subdirectory_install', false ) ) {
return true;
}
if ( defined( 'ALLOW_SUBDIRECTORY_INSTALL' ) && ALLOW_SUBDIRECTORY_INSTALL ) {
return true;
}
$post = $wpdb->get_row( "SELECT ID FROM $wpdb->posts WHERE post_date < DATE_SUB(NOW(), INTERVAL 1 MONTH) AND post_status = 'publish'" );
if ( empty( $post ) ) {
return true;
}
return false;
}
/**
* Get base domain of network.
*
* @since 3.0.0
* @return string Base domain.
*/
function get_clean_basedomain() {
$existing_domain = network_domain_check();
if ( $existing_domain ) {
return $existing_domain;
}
$domain = preg_replace( '|https?://|', '', get_option( 'siteurl' ) );
$slash = strpos( $domain, '/' );
if ( $slash ) {
$domain = substr( $domain, 0, $slash );
}
return $domain;
}
/**
* Prints step 1 for Network installation process.
*
* @todo Realistically, step 1 should be a welcome screen explaining what a Network is and such.
* Navigating to Tools > Network should not be a sudden "Welcome to a new install process!
* Fill this out and click here." See also contextual help todo.
*
* @since 3.0.0
*
* @global bool $is_apache
*
* @param false|WP_Error $errors Optional. Error object. Default false.
*/
function network_step1( $errors = false ) {
if ( defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) {
echo '<div class="error"><p><strong>' . esc_html__( 'Error:' ) . '</strong> ' . sprintf(
/* translators: %s: DO_NOT_UPGRADE_GLOBAL_TABLES */
esc_html__( 'The constant %s cannot be defined when creating a network.' ),
'<code>DO_NOT_UPGRADE_GLOBAL_TABLES</code>'
) . '</p></div>';
echo '</div>';
require_once ABSPATH . 'wp-admin/admin-footer.php';
die();
}
$active_plugins = get_option( 'active_plugins' );
if ( ! empty( $active_plugins ) ) {
echo '<div class="notice notice-warning"><p><strong>' . esc_html__( 'Warning:' ) . '</strong> ' . sprintf(
/* translators: %s: URL to Plugins screen. */
wp_kses_post( __( 'Please <a href="%s">deactivate your plugins</a> before enabling the Network feature.' ) ),
esc_url_raw( admin_url( 'plugins.php?plugin_status=active' ) )
) . '</p></div>';
echo '<p>' . esc_html__( 'Once the network is created, you may reactivate your plugins.' ) . '</p>';
echo '</div>';
require_once ABSPATH . 'wp-admin/admin-footer.php';
die();
}
$hostname = get_clean_basedomain();
$has_ports = strstr( $hostname, ':' );
if ( ( false !== $has_ports && ! in_array( $has_ports, [ ':80', ':443' ], true ) ) ) {
echo '<div class="error"><p><strong>' . esc_html__( 'Error:' ) . '</strong> ' . esc_html__( 'You cannot install a network of sites with your server address.' ) . '</p></div>';
echo '<p>' . sprintf(
/* translators: %s: Port number. */
esc_html__( 'You cannot use port numbers such as %s.' ),
'<code>' . $has_ports . '</code>' // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
) . '</p>';
echo '<a href="' . esc_url( admin_url() ) . '">' . esc_html__( 'Go to Dashboard' ) . '</a>';
echo '</div>';
require_once ABSPATH . 'wp-admin/admin-footer.php';
die();
}
echo '<form method="post">';
wp_nonce_field( 'install-network-1' );
$error_codes = [];
if ( is_wp_error( $errors ) ) {
echo '<div class="error"><p><strong>' . esc_html__( 'Error: The network could not be created.' ) . '</strong></p>';
foreach ( $errors->get_error_messages() as $error ) {
echo "<p>$error</p>"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
echo '</div>';
$error_codes = $errors->get_error_codes();
}
if ( ! empty( $_POST['sitename'] ) && ! in_array( 'empty_sitename', $error_codes, true ) ) {
$site_name = $_POST['sitename'];
} else {
/* translators: %s: Default network title. */
$site_name = sprintf( __( '%s Sites' ), get_option( 'blogname' ) );
}
if ( ! empty( $_POST['email'] ) && ! in_array( 'invalid_email', $error_codes, true ) ) {
$admin_email = $_POST['email'];
} else {
$admin_email = get_option( 'admin_email' );
}
?>
<p><?php esc_html_e( 'Welcome to the Network installation process!' ); ?></p>
<p><?php esc_html_e( 'Fill in the information below and you&#8217;ll be on your way to creating a network of WordPress sites. Configuration files will be created in the next step.' ); ?></p>
<?php
if ( isset( $_POST['subdomain_install'] ) ) {
$subdomain_install = (bool) $_POST['subdomain_install'];
} elseif ( apache_mod_loaded( 'mod_rewrite' ) ) { // Assume nothing.
$subdomain_install = true;
} elseif ( ! allow_subdirectory_install() ) {
$subdomain_install = true;
} else {
$subdomain_install = false;
}
if ( allow_subdomain_install() && allow_subdirectory_install() ) :
?>
<h3><?php esc_html_e( 'Addresses of Sites in your Network' ); ?></h3>
<p><?php esc_html_e( 'Please choose whether you would like sites in your WordPress network to use sub-domains or sub-directories.' ); ?>
<strong><?php esc_html_e( 'You cannot change this later.' ); ?></strong></p>
<p><?php esc_html_e( 'You will need a wildcard DNS record if you are going to use the virtual host (sub-domain) functionality.' ); ?></p>
<?php // @todo Link to an MS readme? ?>
<table class="form-table" role="presentation">
<tr>
<th><label><input type="radio" name="subdomain_install" value="1"<?php checked( $subdomain_install ); ?> /> <?php esc_html_e( 'Sub-domains' ); ?></label></th>
<td>
<?php
printf(
/* translators: 1: Host name. */
wp_kses_post( _x( 'like <code>site1.%1$s</code> and <code>site2.%1$s</code>', 'subdomain examples' ) ),
$hostname // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
?>
</td>
</tr>
<tr>
<th><label><input type="radio" name="subdomain_install" value="0"<?php checked( ! $subdomain_install ); ?> /> <?php esc_html_e( 'Sub-directories' ); ?></label></th>
<td>
<?php
printf(
/* translators: 1: Host name. */
wp_kses_post( _x( 'like <code>%1$s/site1</code> and <code>%1$s/site2</code>', 'subdirectory examples' ) ),
$hostname // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
?>
</td>
</tr>
</table>
<?php
endif;
if ( WP_CONTENT_DIR !== ABSPATH . 'wp-content' && ( allow_subdirectory_install() || ! allow_subdomain_install() ) ) {
echo '<div class="error inline"><p><strong>' . esc_html__( 'Warning:' ) . '</strong> ' . esc_html__( 'Subdirectory networks may not be fully compatible with custom wp-content directories.' ) . '</p></div>';
}
$is_www = ( 0 === strpos( $hostname, 'www.' ) );
if ( $is_www ) :
?>
<h3><?php esc_html_e( 'Server Address' ); ?></h3>
<p>
<?php
printf(
/* translators: 1: Site URL, 2: Host name, 3: www. */
esc_html__( 'You should consider changing your site domain to %1$s before enabling the network feature. It will still be possible to visit your site using the %3$s prefix with an address like %2$s but any links will not have the %3$s prefix.' ),
'<code>' . substr( $hostname, 4 ) . '</code>', // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'<code>' . $hostname . '</code>', // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'<code>www</code>'
);
?>
</p>
<table class="form-table" role="presentation">
<tr>
<th scope='row'><?php esc_html_e( 'Server Address' ); ?></th>
<td>
<?php
printf(
/* translators: %s: Host name. */
esc_html__( 'The internet address of your network will be %s.' ),
'<code>' . $hostname . '</code>' // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
?>
</td>
</tr>
</table>
<?php endif; ?>
<h3><?php esc_html_e( 'Network Details' ); ?></h3>
<table class="form-table" role="presentation">
<?php if ( 'localhost' === $hostname ) : ?>
<tr>
<th scope="row"><?php esc_html_e( 'Sub-directory Installation' ); ?></th>
<td>
<?php
printf(
/* translators: 1: localhost, 2: localhost.localdomain */
esc_html__( 'Because you are using %1$s, the sites in your WordPress network must use sub-directories. Consider using %2$s if you wish to use sub-domains.' ),
'<code>localhost</code>',
'<code>localhost.localdomain</code>'
);
// Uh oh!
if ( ! allow_subdirectory_install() ) {
echo ' <strong>' . esc_html__( 'Warning:' ) . ' ' . esc_html__( 'The main site in a sub-directory installation will need to use a modified permalink structure, potentially breaking existing links.' ) . '</strong>';
}
?>
</td>
</tr>
<?php elseif ( ! allow_subdomain_install() ) : ?>
<tr>
<th scope="row"><?php esc_html_e( 'Sub-directory Installation' ); ?></th>
<td>
<?php
esc_html_e( 'Because your installation is in a directory, the sites in your WordPress network must use sub-directories.' );
// Uh oh!
if ( ! allow_subdirectory_install() ) {
echo ' <strong>' . esc_html__( 'Warning:' ) . ' ' . esc_html__( 'The main site in a sub-directory installation will need to use a modified permalink structure, potentially breaking existing links.' ) . '</strong>';
}
?>
</td>
</tr>
<?php elseif ( ! allow_subdirectory_install() ) : ?>
<tr>
<th scope="row"><?php esc_html_e( 'Sub-domain Installation' ); ?></th>
<td>
<?php
esc_html_e( 'Because your installation is not new, the sites in your WordPress network must use sub-domains.' );
echo ' <strong>' . esc_html__( 'The main site in a sub-directory installation will need to use a modified permalink structure, potentially breaking existing links.' ) . '</strong>';
?>
</td>
</tr>
<?php endif; ?>
<?php if ( ! $is_www ) : ?>
<tr>
<th scope='row'><?php esc_html_e( 'Server Address' ); ?></th>
<td>
<?php
printf(
/* translators: %s: Host name. */
esc_html__( 'The internet address of your network will be %s.' ),
'<code>' . $hostname . '</code>' // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
?>
</td>
</tr>
<?php endif; ?>
<tr>
<th scope='row'><label for="sitename"><?php esc_html_e( 'Network Title' ); ?></label></th>
<td>
<input name='sitename' id='sitename' type='text' size='45' value='<?php echo esc_attr( $site_name ); ?>' />
<p class="description">
<?php esc_html_e( 'What would you like to call your network?' ); ?>
</p>
</td>
</tr>
<tr>
<th scope='row'><label for="email"><?php esc_html_e( 'Network Admin Email' ); ?></label></th>
<td>
<input name='email' id='email' type='text' size='45' value='<?php echo esc_attr( $admin_email ); ?>' />
<p class="description">
<?php esc_html_e( 'Your email address.' ); ?>
</p>
</td>
</tr>
</table>
<?php submit_button( __( 'Install' ), 'primary', 'submit' ); ?>
</form>
<?php
}
/**
* Prints step 2 for Network installation process.
*
* @since 3.0.0
*
* @global wpdb $wpdb WordPress database abstraction object.
* @global bool $is_nginx Whether the server software is Nginx or something else.
*
* @param false|WP_Error $errors Optional. Error object. Default false.
*/
function network_step2( $errors = false ) {
global $wpdb, $is_nginx;
$hostname = get_clean_basedomain();
$slashed_home = trailingslashit( get_option( 'home' ) );
$base = parse_url( $slashed_home, PHP_URL_PATH );
$document_root_fix = str_replace( '\\', '/', realpath( $_SERVER['DOCUMENT_ROOT'] ) );
$abspath_fix = str_replace( '\\', '/', ABSPATH );
$home_path = 0 === strpos( $abspath_fix, $document_root_fix ) ? $document_root_fix . $base : get_home_path();
$wp_siteurl_subdir = preg_replace( '#^' . preg_quote( $home_path, '#' ) . '#', '', $abspath_fix );
$rewrite_base = ! empty( $wp_siteurl_subdir ) ? ltrim( trailingslashit( $wp_siteurl_subdir ), '/' ) : '';
$config_filename = 'wp-config.php';
$config_filename = apply_filters( 'pantheon.multisite.config_filename', 'wp-config.php' );
$location_of_wp_config = $abspath_fix;
if ( ! file_exists( ABSPATH . $config_filename ) && file_exists( dirname( ABSPATH ) . '/' . $config_filename ) ) {
$location_of_wp_config = dirname( $abspath_fix );
}
$location_of_wp_config = trailingslashit( $location_of_wp_config );
// Wildcard DNS message.
if ( is_wp_error( $errors ) ) {
echo '<div class="error">' . esc_html( $errors->get_error_message() ) . '</div>';
}
if ( $_POST ) {
if ( allow_subdomain_install() ) {
$subdomain_install = allow_subdirectory_install() ? ! empty( $_POST['subdomain_install'] ) : true;
} else {
$subdomain_install = false;
}
} elseif ( is_multisite() ) {
$subdomain_install = is_subdomain_install();
?>
<p><?php esc_html_e( 'The original configuration steps are shown here for reference.' ); ?></p>
<?php
} else {
$subdomain_install = (bool) $wpdb->get_var( "SELECT meta_value FROM $wpdb->sitemeta WHERE site_id = 1 AND meta_key = 'subdomain_install'" );
?>
<div class="error"><p><strong><?php esc_html_e( 'Warning:' ); ?></strong> <?php esc_html_e( 'An existing WordPress network was detected.' ); ?></p></div>
<p><?php esc_html_e( 'Please complete the configuration steps. To create a new network, you will need to empty or remove the network database tables.' ); ?></p>
<?php
}
$subdir_match = $subdomain_install ? '' : '([_0-9a-zA-Z-]+/)?';
$subdir_replacement_01 = $subdomain_install ? '' : '$1';
$subdir_replacement_12 = $subdomain_install ? '$1' : '$2';
if ( $_POST || ! is_multisite() ) {
?>
<h3><?php esc_html_e( 'Enabling the Network' ); ?></h3>
<p><?php esc_html_e( 'Complete the following steps to enable the features for creating a network of sites.' ); ?></p>
<div class="notice notice-warning inline"><p>
<?php
if ( file_exists( $home_path . 'web.config' ) ) {
echo '<strong>' . esc_html__( 'Caution:' ) . '</strong> ';
printf(
/* translators: 1: wp-config.php, 2: web.config */
esc_html__( 'You should back up your existing %1$s and %2$s files.' ),
'<code>' . $config_filename . '</code>', // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'<code>web.config</code>'
);
} else {
echo '<strong>' . esc_html__( 'Caution:' ) . '</strong> ';
printf(
/* translators: %s: wp-config.php */
esc_html__( 'You should back up your existing %s file.' ),
'<code>' . $config_filename . '</code>', // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
}
?>
</p></div>
<?php
}
?>
<ol>
<li><p id="network-wpconfig-rules-description">
<?php
printf(
/* translators: 1: wp-config.php, 2: Location of wp-config file, 3: Translated version of "That's all, stop editing! Happy publishing." */
esc_html__( 'Add the following to your %1$s file in %2$s <strong>above</strong> the line reading %3$s:' ),
'<code>' . $config_filename . '</code>', // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'<code>' . $location_of_wp_config . '</code>', // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
// translators: This string should only be translated if wp-config-sample.php is localized.
// You can check the localized release package or https://i18n.svn.wordpress.org/<locale code>/branches/<wp version>/dist/wp-config-sample.php.
'<code>/* ' . esc_html__( 'That&#8217;s all, stop editing! Happy publishing.' ) . ' */</code>'
);
?>
</p>
<p class="configuration-rules-label"><label for="network-wpconfig-rules">
<?php
printf(
/* translators: %s: File name (wp-config.php, .htaccess or web.config). */
esc_html__( 'Network configuration rules for %s' ),
'<code>' . $config_filename . '</code>' // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
?>
</label></p>
<textarea id="network-wpconfig-rules" class="code" readonly="readonly" cols="100" rows="31" aria-describedby="network-wpconfig-rules-description">
<?php ob_start(); ?>
if ( !empty( $_ENV['PANTHEON_ENVIRONMENT'] )) {
$site_name = $_ENV['PANTHEON_SITE_NAME'];
// Override $hostname value as needed.
switch ( $_ENV['PANTHEON_ENVIRONMENT'] ) {
case 'live':
$hostname = $_SERVER['HTTP_HOST'];
break;
case 'test':
$hostname = 'test-' . $site_name . '.pantheonsite.io';
break;
case 'dev':
$hostname = 'dev-' . $site_name . '.pantheonsite.io';
break;
case 'lando':
$hostname = $site_name . '.lndo.site';
break;
default:
$hostname = $_ENV['PANTHEON_ENVIRONMENT'] . '-' . $site_name . '.pantheonsite.io';
break;
}
} else {
// Override with a default hostname.
$hostname = '<?php echo $hostname; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>';
}
define( 'MULTISITE', true );
define( 'SUBDOMAIN_INSTALL', <?php echo $subdomain_install ? 'true' : 'false'; ?> );
define( 'DOMAIN_CURRENT_SITE', $hostname );
define( 'PATH_CURRENT_SITE', '<?php echo $base; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>' );
define( 'SITE_ID_CURRENT_SITE', 1 );
define( 'BLOG_ID_CURRENT_SITE', 1 );
<?php
$config_file_contents = ob_get_contents();
ob_end_clean();
$config_file_contents = apply_filters( 'pantheon.multisite.config_contents', $config_file_contents );
echo $config_file_contents; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
?>
</textarea>
<?php
$keys_salts = [
'AUTH_KEY' => '',
'SECURE_AUTH_KEY' => '',
'LOGGED_IN_KEY' => '',
'NONCE_KEY' => '',
'AUTH_SALT' => '',
'SECURE_AUTH_SALT' => '',
'LOGGED_IN_SALT' => '',
'NONCE_SALT' => '',
];
foreach ( $keys_salts as $c => $v ) {
if ( defined( $c ) ) {
unset( $keys_salts[ $c ] );
}
}
if ( ! empty( $keys_salts ) ) {
$keys_salts_str = '';
$from_api = wp_remote_get( 'https://api.wordpress.org/secret-key/1.1/salt/' );
if ( is_wp_error( $from_api ) ) {
foreach ( $keys_salts as $c => $v ) {
$keys_salts_str .= "\ndefine( '$c', '" . wp_generate_password( 64, true, true ) . "' );";
}
} else {
$from_api = explode( "\n", wp_remote_retrieve_body( $from_api ) );
foreach ( $keys_salts as $c => $v ) {
$keys_salts_str .= "\ndefine( '$c', '" . substr( array_shift( $from_api ), 28, 64 ) . "' );";
}
}
$num_keys_salts = count( $keys_salts );
?>
<p id="network-wpconfig-authentication-description">
<?php
if ( 1 === $num_keys_salts ) {
printf(
/* translators: %s: wp-config.php */
esc_html__( 'This unique authentication key is also missing from your %s file.' ),
'<code>' . $config_filename . '</code>', // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
} else {
printf(
/* translators: %s: wp-config.php */
esc_html__( 'These unique authentication keys are also missing from your %s file.' ),
'<code>' . $config_filename . '</code>', // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
}
?>
<?php esc_html_e( 'To make your installation more secure, you should also add:' ); ?>
</p>
<p class="configuration-rules-label"><label for="network-wpconfig-authentication"><?php esc_html_e( 'Network configuration authentication keys' ); ?></label></p>
<textarea id="network-wpconfig-authentication" class="code" readonly="readonly" cols="100" rows="<?php echo $num_keys_salts; ?>" aria-describedby="network-wpconfig-authentication-description"><?php echo esc_textarea( $keys_salts_str ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></textarea>
<?php
}
?>
</li>
<?php
if ( iis7_supports_permalinks() ) :
// IIS doesn't support RewriteBase, all your RewriteBase are belong to us.
$iis_subdir_match = ltrim( $base, '/' ) . $subdir_match;
$iis_rewrite_base = ltrim( $base, '/' ) . $rewrite_base;
$iis_subdir_replacement = $subdomain_install ? '' : '{R:1}';
$web_config_file = '<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="WordPress Rule 1" stopProcessing="true">
<match url="^index\.php$" ignoreCase="false" />
<action type="None" />
</rule>';
if ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) {
$web_config_file .= '
<rule name="WordPress Rule for Files" stopProcessing="true">
<match url="^' . $iis_subdir_match . 'files/(.+)" ignoreCase="false" />
<action type="Rewrite" url="' . $iis_rewrite_base . WPINC . '/ms-files.php?file={R:1}" appendQueryString="false" />
</rule>';
}
$web_config_file .= '
<rule name="WordPress Rule 2" stopProcessing="true">
<match url="^' . $iis_subdir_match . 'wp-admin$" ignoreCase="false" />
<action type="Redirect" url="' . $iis_subdir_replacement . 'wp-admin/" redirectType="Permanent" />
</rule>
<rule name="WordPress Rule 3" stopProcessing="true">
<match url="^" ignoreCase="false" />
<conditions logicalGrouping="MatchAny">
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" />
</conditions>
<action type="None" />
</rule>
<rule name="WordPress Rule 4" stopProcessing="true">
<match url="^' . $iis_subdir_match . '(wp-(content|admin|includes).*)" ignoreCase="false" />
<action type="Rewrite" url="' . $iis_rewrite_base . '{R:1}" />
</rule>
<rule name="WordPress Rule 5" stopProcessing="true">
<match url="^' . $iis_subdir_match . '([_0-9a-zA-Z-]+/)?(.*\.php)$" ignoreCase="false" />
<action type="Rewrite" url="' . $iis_rewrite_base . '{R:2}" />
</rule>
<rule name="WordPress Rule 6" stopProcessing="true">
<match url="." ignoreCase="false" />
<action type="Rewrite" url="index.php" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
';
echo '<li><p id="network-webconfig-rules-description">';
printf(
/* translators: 1: File name (.htaccess or web.config), 2: File path. */
wp_kses_post( __( 'Add the following to your %1$s file in %2$s, <strong>replacing</strong> other WordPress rules:' ) ),
'<code>web.config</code>',
'<code>' . $home_path . '</code>' // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
echo '</p>';
if ( ! $subdomain_install && WP_CONTENT_DIR !== ABSPATH . 'wp-content' ) {
echo '<p><strong>' . esc_html__( 'Warning:' ) . ' ' . esc_html__( 'Subdirectory networks may not be fully compatible with custom wp-content directories.' ) . '</strong></p>';
}
?>
<p class="configuration-rules-label"><label for="network-webconfig-rules">
<?php
printf(
/* translators: %s: File name (wp-config.php, .htaccess or web.config). */
esc_html__( 'Network configuration rules for %s' ),
'<code>web.config</code>'
);
?>
</label></p>
<textarea id="network-webconfig-rules" class="code" readonly="readonly" cols="100" rows="20" aria-describedby="network-webconfig-rules-description"><?php echo esc_textarea( $web_config_file ); ?></textarea>
</li>
</ol>
<?php
elseif ( $is_nginx ) : // End iis7_supports_permalinks(). Link to Nginx documentation instead.
echo '<li><p>';
printf(
/* translators: %s: Documentation URL. */
wp_kses_post( __( 'It seems your network is running with Nginx web server. <a href="%s">Learn more about further configuration</a>.' ) ),
'https://wordpress.org/support/article/nginx/'
);
echo '</p></li>';
else : // End $is_nginx. Construct an .htaccess file instead.
$ms_files_rewriting = '';
if ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) {
$ms_files_rewriting = "\n# uploaded files\nRewriteRule ^";
$ms_files_rewriting .= $subdir_match . "files/(.+) {$rewrite_base}" . WPINC . "/ms-files.php?file={$subdir_replacement_12} [L]" . "\n"; // phpcs:ignore Generic.Strings.UnnecessaryStringConcat.Found
}
$htaccess_file = <<<EOF
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase {$base}
RewriteRule ^index\.php$ - [L]
{$ms_files_rewriting}
# add a trailing slash to /wp-admin
RewriteRule ^{$subdir_match}wp-admin$ {$subdir_replacement_01}wp-admin/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^{$subdir_match}(wp-(content|admin|includes).*) {$rewrite_base}{$subdir_replacement_12} [L]
RewriteRule ^{$subdir_match}(.*\.php)$ {$rewrite_base}$subdir_replacement_12 [L]
RewriteRule . index.php [L]
EOF;
echo '<li><p id="network-htaccess-rules-description">';
printf(
/* translators: 1: File name (.htaccess or web.config), 2: File path. */
wp_kses_post( __( 'Add the following to your %1$s file in %2$s, <strong>replacing</strong> other WordPress rules:' ) ),
'<code>.htaccess</code>',
'<code>' . $home_path . '</code>' // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
echo '</p>';
if ( ! $subdomain_install && WP_CONTENT_DIR !== ABSPATH . 'wp-content' ) {
echo '<p><strong>' . esc_html__( 'Warning:' ) . ' ' . esc_html__( 'Subdirectory networks may not be fully compatible with custom wp-content directories.' ) . '</strong></p>';
}
?>
<p class="configuration-rules-label"><label for="network-htaccess-rules">
<?php
printf(
/* translators: %s: File name (wp-config.php, .htaccess or web.config). */
esc_html__( 'Network configuration rules for %s' ),
'<code>.htaccess</code>'
);
?>
</label></p>
<textarea id="network-htaccess-rules" class="code" readonly="readonly" cols="100" rows="<?php echo substr_count( $htaccess_file, "\n" ) + 1; ?>" aria-describedby="network-htaccess-rules-description"><?php echo esc_textarea( $htaccess_file ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></textarea>
</li>
</ol>
<?php
endif; // End IIS/Nginx/Apache code branches.
if ( ! is_multisite() ) {
?>
<p><?php esc_html_e( 'Once you complete these steps, your network is enabled and configured. You will have to log in again.' ); ?> <a href="<?php echo esc_url( wp_login_url() ); ?>"><?php esc_html_e( 'Log In' ); ?></a></p>
<?php
}
}

View File

@@ -0,0 +1,118 @@
<?php
/**
* File mostly copied from wp-admin/network.php.
*
* Changes:
* - s/__DIR__.'\//ABSPATH . 'wp-admin\//g
* - s/ABSPATH . 'wp-admin\/includes\/network.php/__DIR__ . '\/includes-network.php/g'
*/
define( 'WP_INSTALLING_NETWORK', true );
/** WordPress Administration Bootstrap */
require_once ABSPATH . 'wp-admin/admin.php';
if ( ! current_user_can( 'setup_network' ) ) {
wp_die( esc_html__( 'Sorry, you are not allowed to manage options for this site.' ) );
}
if ( is_multisite() ) {
if ( ! is_network_admin() ) {
wp_safe_redirect( network_admin_url( 'setup.php' ) );
exit;
}
if ( ! defined( 'MULTISITE' ) ) {
wp_die( esc_html__( 'The Network creation panel is not for WordPress MU networks.' ) );
}
}
require_once __DIR__ . '/includes-network.php';
// We need to create references to ms global tables to enable Network.
foreach ( $wpdb->tables( 'ms_global' ) as $table => $prefixed_table ) {
$wpdb->$table = $prefixed_table;
}
if ( ! network_domain_check() && ( ! defined( 'WP_ALLOW_MULTISITE' ) || ! WP_ALLOW_MULTISITE ) ) {
wp_die(
printf( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
/* translators: 1: WP_ALLOW_MULTISITE, 2: wp-config.php */
esc_html__( 'You must define the %1$s constant as true in your %2$s file to allow creation of a Network.' ),
'<code>WP_ALLOW_MULTISITE</code>',
'<code>wp-config.php</code>'
)
);
}
if ( is_network_admin() ) {
// Used in the HTML title tag.
$page_title = esc_html__( 'Network Setup' );
} else {
// Used in the HTML title tag.
$page_title = __( 'Create a Network of WordPress Sites' );
}
$network_help = wp_kses_post( '<p>' . __( 'This screen allows you to configure a network as having subdomains (<code>site1.example.com</code>) or subdirectories (<code>example.com/site1</code>). Subdomains require wildcard subdomains to be enabled in Apache and DNS records, if your host allows it.' ) . '</p>' .
'<p>' . __( 'Choose subdomains or subdirectories; this can only be switched afterwards by reconfiguring your installation. Fill out the network details, and click Install. If this does not work, you may have to add a wildcard DNS record (for subdomains) or change to another setting in Permalinks (for subdirectories).' ) . '</p>' .
'<p>' . __( 'The next screen for Network Setup will give you individually-generated lines of code to add to your wp-config.php and .htaccess files. Make sure the settings of your FTP client make files starting with a dot visible, so that you can find .htaccess; you may have to create this file if it really is not there. Make backup copies of those two files.' ) . '</p>' .
'<p>' . __( 'Add the designated lines of code to wp-config.php (just before <code>/*...stop editing...*/</code>) and <code>.htaccess</code> (replacing the existing WordPress rules).' ) . '</p>' .
'<p>' . __( 'Once you add this code and refresh your browser, multisite should be enabled. This screen, now in the Network Admin navigation menu, will keep an archive of the added code. You can toggle between Network Admin and Site Admin by clicking on the Network Admin or an individual site name under the My Sites dropdown in the Toolbar.' ) . '</p>' .
'<p>' . __( 'The choice of subdirectory sites is disabled if this setup is more than a month old because of permalink problems with &#8220;/blog/&#8221; from the main site. This disabling will be addressed in a future version.' ) . '</p>' .
'<p><strong>' . __( 'For more information:' ) . '</strong></p>' .
'<p>' . __( '<a href="https://wordpress.org/support/article/create-a-network/">Documentation on Creating a Network</a>' ) . '</p>' .
'<p>' . __( '<a href="https://wordpress.org/support/article/tools-network-screen/">Documentation on the Network Screen</a>' ) . '</p>' ); // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
get_current_screen()->add_help_tab(
[
'id' => 'network',
'title' => __( 'Network' ),
'content' => $network_help,
]
);
get_current_screen()->set_help_sidebar(
'<p><strong>' . __( 'For more information:' ) . '</strong></p>' .
'<p>' . __( '<a href="https://wordpress.org/support/article/create-a-network/">Documentation on Creating a Network</a>' ) . '</p>' .
'<p>' . __( '<a href="https://wordpress.org/support/article/tools-network-screen/">Documentation on the Network Screen</a>' ) . '</p>' .
'<p>' . __( '<a href="https://wordpress.org/support/">Support</a>' ) . '</p>'
);
require_once ABSPATH . 'wp-admin/admin-header.php';
?>
<div class="wrap">
<h1><?php echo esc_html( $page_title ); ?></h1>
<?php
if ( $_POST ) {
check_admin_referer( 'install-network-1' );
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
// Create network tables.
install_network();
$base = parse_url( trailingslashit( get_option( 'home' ) ), PHP_URL_PATH );
$subdomain_install = allow_subdomain_install() ? ! empty( $_POST['subdomain_install'] ) : false;
if ( ! network_domain_check() ) {
$result = populate_network( 1, get_clean_basedomain(), sanitize_email( $_POST['email'] ), wp_unslash( $_POST['sitename'] ), $base, $subdomain_install );
if ( is_wp_error( $result ) ) {
if ( 1 === count( $result->get_error_codes() ) && 'no_wildcard_dns' === $result->get_error_code() ) {
network_step2( $result );
} else {
network_step1( $result );
}
} else {
network_step2();
}
} else {
network_step2();
}
} elseif ( is_multisite() || network_domain_check() ) {
network_step2();
} else {
network_step1();
}
?>
</div>
<?php require_once ABSPATH . 'wp-admin/admin-footer.php'; ?>

View File

@@ -0,0 +1,69 @@
<?php
/**
* Modify the WordPress login form for Pantheon
*/
/**
* Should we proceed with adding the return to Pantheon button?
*
* Only if we are on a Pantheon subdomain
*/
$show_return_to_pantheon_button = apply_filters( 'show_return_to_pantheon_button', (
(
false !== stripos( get_site_url(), 'pantheonsite.io' ) ||
( isset( $_SERVER['HTTP_HOST'] ) && false !== stripos( $_SERVER['HTTP_HOST'], 'pantheonsite.io' ) )
)
) );
if ( $show_return_to_pantheon_button ) {
/**
* Enqueue Pantheon login styles
*
* @return void
*/
function Pantheon_Enqueue_Login_style() {
wp_enqueue_style( 'pantheon-login-mods', plugin_dir_url( __FILE__ ) . 'assets/css/return-to-pantheon-button.css', false, PANTHEON_MU_PLUGIN_VERSION );
}
add_action( 'login_enqueue_scripts', 'Pantheon_Enqueue_Login_style', 10 );
/**
* Enqueue Pantheon login scripts
*
* @return void
*/
function Pantheon_Enqueue_Login_script() {
wp_enqueue_script( 'pantheon-login-mods', plugin_dir_url( __FILE__ ) . 'assets/js/return-to-pantheon-button.js', [ 'jquery' ], PANTHEON_MU_PLUGIN_VERSION, true );
}
add_action( 'login_enqueue_scripts', 'Pantheon_Enqueue_Login_script', 1 );
/**
* Print return to Pantheon link HTML
*
* @return void
*/
function Return_To_Pantheon_Button_HTML() {
$pantheon_dashboard_url = 'https://dashboard.pantheon.io/sites/' . $_ENV['PANTHEON_SITE'] . '#' . $_ENV['PANTHEON_ENVIRONMENT'];
$pantheon_fist_icon_url = plugin_dir_url( __FILE__ ) . 'assets/images/pantheon-fist-icon-black.svg';
$login_message = apply_filters( 'pantheon_wp_login_text', esc_html__( 'Login to your WordPress Site', 'pantheon' ) );
?>
<div id="return-to-pantheon" style="display: none;">
<div class="left">
<?php echo $login_message; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div>
<div class="right">
<a href="<?php echo esc_url( $pantheon_dashboard_url ); ?>">
<img class="fist-icon" src="<?php echo esc_url( $pantheon_fist_icon_url ); ?>">
<?php esc_html_e( 'Return to Pantheon', 'pantheon' ); ?>
</a>
</div>
</div>
<?php
}
add_action( 'login_header', 'Return_To_Pantheon_Button_HTML', 10 );
}

View File

@@ -0,0 +1,57 @@
<?php
/**
* If a site has multisite enabled, but has not had the final installation
* steps completed, alert the user and provide links.
*
* @package pantheon
*/
/**
* Detects if a user is using the correct upstream and framework and give them appropriate next steps to finalize WPMS setup.
*
* @return void
*/
function pantheon_multisite_install_finalize_message() {
?>
<div class="notice notice-info is-dismissible">
<?php
if ( isset( $_ENV['PANTHEON_ENVIRONMENT'] ) ) {
if ( getenv( 'FRAMEWORK' ) === 'wordpress_network' ) {
?>
<p><?php esc_html_e( 'Your WordPress Multisite is almost ready!', 'pantheon' ); ?></p>
<p>
<?php
printf(
wp_kses_post(
// translators: %s is the link to the Pantheon Multisite Configuration documentation.
__( 'Visit <a href="%s">Pantheon Multisite Configuration</a> for documentation on how to finalize configuration of your site network.', 'pantheon' )
),
'https://pantheon.io/docs/guides/multisite/config/#install-the-wordpress-site-network'
);
?>
</p>
<?php
} else {
?>
<p><?php esc_html_e( 'You are trying to configure a WordPress Multisite with a wrong upstream!', 'pantheon' ); ?></p>
<p>
<?php
printf(
wp_kses_post(
// translators: %s is the link to the Pantheon Support page.
__( 'Make sure that you have the correct upstream configuration for WPMS. If you do not have that capability or to check if you are eligible, please <a href="%s">Contact Support</a>.', 'pantheon' )
), 'https://pantheon.io/support'
);
?>
</p>
<?php
}
}
?>
</div>
<?php
}
add_action( 'admin_notices', 'pantheon_multisite_install_finalize_message' );

View File

@@ -0,0 +1,46 @@
<?php
/**
* Network Setup
*
* @package pantheon-mu-plugin
*/
namespace Pantheon\NetworkSetup;
/**
* Alter network setup pages to include Pantheon-specific instructions.
*/
/**
* Replace the WordPress core Network Setup page from the Settings menu.
*/
function pantheon_remove_network_setup() {
global $submenu;
if ( isset( $submenu['tools.php'][50] ) ) {
unset( $submenu['tools.php'][50] );
}
}
/**
* Register the Pantheon network setup submenu page.
*/
function pantheon_add_network_setup() {
add_management_page(
__( 'Create a Network of WordPress Sites', 'network-setup' ),
__( 'Network Setup', 'network-setup' ),
'setup_network',
'setup_network',
__NAMESPACE__ . '\\pantheon_render_network_setup_page'
);
}
/**
* Render the Pantheon network setup page.
*/
function pantheon_render_network_setup_page() {
global $wpdb;
require_once __DIR__ . '/network/network.php';
}
add_action( 'admin_menu', __NAMESPACE__ . '\\pantheon_remove_network_setup' );
add_action( 'admin_menu', __NAMESPACE__ . '\\pantheon_add_network_setup' );

View File

@@ -0,0 +1,547 @@
<?php
/**
* Pantheon Page Cache
*
* @package pantheon-mu-plugin
*/
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
class Pantheon_Cache {
/**
* Define the capability required to see and modify the settings page.
*
* @var string
*/
public $options_capability = 'manage_options';
/**
* Define the default options, which are overridden by what's in wp_options.
*
* @var array
*/
public $default_options = [];
/**
* Stores the options for this plugin (from wp_options).
*
* @var array
*/
public $options = [];
/**
* Store the Paths to be flushed at shutdown.
*
* @var array
*/
public $paths = [];
/**
* The slug for the plugin, used in various places like the options page.
*/
const SLUG = 'pantheon-cache';
/**
* Holds the singleton instance.
*
* @static
* @var object
*/
protected static $instance;
/**
* Get a reference to the singleton.
*
* @return object The singleton instance.
*/
public static function instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new Pantheon_Cache();
self::$instance->setup();
}
return self::$instance;
}
protected function __construct() {
/** Don't do anything */
}
/**
* Setup the actions and filters we need to hook into, and initialize any properties we need.
*
* @return void
*/
protected function setup() {
$this->options = get_option( self::SLUG, [] );
$this->default_options = [
'default_ttl' => 600,
'maintenance_mode' => 'disabled',
];
$this->options = wp_parse_args( $this->options, $this->default_options );
add_action( 'init', [ $this, 'action_init_do_maintenance_mode' ] );
add_action( 'admin_init', [ $this, 'action_admin_init' ] );
add_action( 'admin_menu', [ $this, 'action_admin_menu' ] );
add_action( 'load-plugin-install.php', [ $this, 'action_load_plugin_install' ] );
add_action( 'admin_post_pantheon_cache_flush_site', [ $this, 'flush_site' ] );
add_action( 'send_headers', [ $this, 'cache_add_headers' ] );
add_filter( 'rest_post_dispatch', [ $this, 'filter_rest_post_dispatch_send_cache_control' ], 10, 2 );
add_action( 'admin_notices', function () {
global $wp_object_cache;
if ( empty( $wp_object_cache->missing_redis_message ) ) {
return;
}
$wp_object_cache->missing_redis_message = 'Alert! The Pantheon Redis service needs to be enabled before the WP Redis object cache will function properly.';
}, 9 ); // Before the message is displayed in the plugin notice.
add_action( 'shutdown', [ $this, 'cache_clean_urls' ], 999 );
}
/**
* Displays maintenance mode when enabled.
*/
public function action_init_do_maintenance_mode() {
$do_maintenance_mode = false;
if ( in_array( $this->options['maintenance_mode'], [ 'anonymous', 'everyone' ], true )
&& ! is_user_logged_in() ) {
$do_maintenance_mode = true;
}
if ( 'everyone' === $this->options['maintenance_mode']
&& is_user_logged_in()
&& ! current_user_can( 'manage_options' ) ) {
$do_maintenance_mode = true;
}
if ( defined( 'WP_CLI' ) && WP_CLI ) {
$do_maintenance_mode = false;
}
if ( 'wp-login.php' === $GLOBALS['pagenow'] ) {
$do_maintenance_mode = false;
}
/**
* Modify maintenance mode behavior with more advanced conditionals.
*
* @var boolean $do_maintenance_mode Whether or not to do maintenance mode.
*/
$do_maintenance_mode = apply_filters( 'pantheon_cache_do_maintenance_mode', $do_maintenance_mode );
if ( ! $do_maintenance_mode ) {
return;
}
wp_die(
esc_html__( 'Briefly unavailable for scheduled maintenance. Check back in a minute.' ),
esc_html__( 'Maintenance' ),
503
);
}
/**
* Prep the Settings API.
*
* @return void
*/
public function action_admin_init() {
register_setting( self::SLUG, self::SLUG, [ self::$instance, 'sanitize_options' ] );
add_settings_section( 'general', false, '__return_false', self::SLUG );
add_settings_field( 'default_ttl', null, [ self::$instance, 'default_ttl_field' ], self::SLUG, 'general' );
add_settings_field( 'maintenance_mode', null, [ self::$instance, 'maintenance_mode_field' ], self::SLUG, 'general' );
}
/**
* Add the settings page to the menu.
*
* @return void
*/
public function action_admin_menu() {
add_options_page( __( 'Pantheon Page Cache', 'pantheon-cache' ), __( 'Pantheon Page Cache', 'pantheon-cache' ), $this->options_capability, self::SLUG, [ self::$instance, 'view_settings_page' ] );
}
/**
* Check to see if JavaScript should trigger the opening of the plugin install box
*/
public function action_load_plugin_install() {
if ( empty( $_GET['action'] ) || 'pantheon-load-infobox' !== $_GET['action'] ) {
return;
}
add_action( 'admin_footer', [ $this, 'action_admin_footer_trigger_plugin_open' ] );
}
/**
* Trigger the opening of the Pantheon Advanced Page Cache infobox
*/
public function action_admin_footer_trigger_plugin_open() {
?>
<script>
jQuery(document).ready(function(){
// Wait until the click event handler is bound by core JavaScript
setTimeout(function(){
jQuery('.plugin-card-pantheon-advanced-page-cache a.open-plugin-details-modal').trigger('click');
}, 1 )
});
</script>
<?php
}
/**
* Add the HTML for the default TTL field.
*
* @return void
*/
public function default_ttl_field() {
echo '<h3>' . esc_html__( 'Default Time to Live (TTL)', 'pantheon-cache' ) . '</h3>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '<p>' . esc_html__( 'Maximum time a cached page will be served. A higher TTL typically improves site performance.', 'pantheon-cache' ) . '</p>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '<input type="text" name="' . self::SLUG . '[default_ttl]" value="' . $this->options['default_ttl'] . '" size="5" /> ' . esc_html__( 'seconds', 'pantheon-cache' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
/**
* Add the HTML for the maintenance mode field.
*
* @return void
*/
public function maintenance_mode_field() {
echo '<h3>' . esc_html__( 'Maintenance Mode', 'pantheon-cache' ) . '</h3>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '<p>' . esc_html__( 'Enable maintenance mode to work on your site while serving cached pages to:', 'pantheon-cache' ) . '</p>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '<label style="display: block; margin-bottom: 5px;"><input type="radio" name="' . self::SLUG . '[maintenance_mode]" value="" ' . checked( 'disabled', $this->options['maintenance_mode'], false ) . ' /> ' . esc_html__( 'Disabled', 'pantheon-cache' ) . '</label>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '<label style="display: block; margin-bottom: 5px;"><input type="radio" name="' . self::SLUG . '[maintenance_mode]" value="anonymous" ' . checked( 'anonymous', $this->options['maintenance_mode'], false ) . ' /> ' . esc_html__( 'Logged-Out Visitors', 'pantheon-cache' ) . '</label>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '<label style="display: block; margin-bottom: 5px;"><input type="radio" name="' . self::SLUG . '[maintenance_mode]" value="everyone" ' . checked( 'everyone', $this->options['maintenance_mode'], false ) . ' /> ' . esc_html__( 'Everyone except Administrators', 'pantheon-cache' ) . '</label>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
/**
* Sanitize our options.
*
* @param array $in The POST values.
* @return array The sanitized POST values.
*/
public function sanitize_options( $in ) {
$out = $this->default_options;
// Validate default_ttl.
$out['default_ttl'] = absint( $in['default_ttl'] );
if ( $out['default_ttl'] < 60 && isset( $_ENV['PANTHEON_ENVIRONMENT'] ) && 'live' === $_ENV['PANTHEON_ENVIRONMENT'] ) {
$out['default_ttl'] = 60;
}
if ( ! empty( $in['maintenance_mode'] )
&& in_array( $in['maintenance_mode'], [ 'anonymous', 'everyone' ], true ) ) {
$out['maintenance_mode'] = $in['maintenance_mode'];
} else {
$out['maintenance_mode'] = 'disabled';
}
return $out;
}
/**
* Output the settings page.
*
* @return void
*/
public function view_settings_page() {
?>
<div class="wrap">
<h2><?php esc_html_e( 'Pantheon Page Cache', 'pantheon-cache' ); ?></h2>
<?php if ( ! empty( $_GET['cache-cleared'] ) && 'true' === $_GET['cache-cleared'] ) : ?>
<div class="updated below-h2">
<p><?php esc_html_e( 'Site cache flushed.', 'pantheon-cache' ); ?></p>
</div>
<?php endif ?>
<?php if ( class_exists( 'Pantheon_Advanced_Page_Cache\Purger' ) ) : // translators: %s is a link. ?>
<div class="notice notice-success"><p><?php echo wp_kses_post( sprintf( __( 'Pantheon Advanced Page Cache activated. <a target="_blank" href="%s">Learn more</a>', 'pantheon-cache' ), 'https://docs.pantheon.io/guides/wordpress-configurations/wordpress-cache-plugin' ) ); ?></p></div>
<?php else : // translators: %s is a link. ?>
<div class="notice notice-warning"><p><?php echo wp_kses_post( sprintf( __( 'Want to automatically clear related pages when you update content? Learn more about the <a href="%s">Pantheon Advanced Page Cache</a>.', 'pantheon-cache' ), 'https://docs.pantheon.io/guides/wordpress-configurations/wordpress-cache-plugin' ) ); ?></p></div>
<?php endif; ?>
<?php
/**
* Permits the Pantheon Advanced Page Cache plugin to add
* supplemental text.
*/
do_action( 'pantheon_cache_settings_page_top' );
?>
<?php if ( apply_filters( 'pantheon_cache_allow_clear_all', true ) ) : ?>
<form action="admin-post.php" method="POST">
<input type="hidden" name="action" value="pantheon_cache_flush_site" />
<?php wp_nonce_field( 'pantheon-cache-clear-all', 'pantheon-cache-nonce' ); ?>
<h3><?php esc_html_e( 'Clear Site Cache', 'pantheon-cache' ); ?></h3>
<p><?php esc_html_e( 'Use with care. Clearing the entire site cache will negatively impact performance for a short period of time.', 'pantheon-cache' ); ?></p>
<?php submit_button( __( 'Clear Cache', 'pantheon-cache' ), 'secondary' ); ?>
</form>
<hr />
<?php endif ?>
<style>
.ttl-form th[scope="row"] {
display: none;
}
.ttl-form td {
padding-left: 0;
}
.ttl-form td p {
margin-bottom: 1em;
font-size: 13px;
}
</style>
<form action="options.php" method="POST" class="ttl-form">
<?php settings_fields( self::SLUG ); ?>
<?php do_settings_sections( self::SLUG ); ?>
<?php submit_button( __( 'Save Changes', 'pantheon-cache' ) ); ?>
</form>
<hr />
<?php
/**
* Permits the Pantheon Advanced Page Cache plugin to add
* supplemental text.
*/
do_action( 'pantheon_cache_settings_page_bottom' );
?>
</div>
<?php
}
/**
* Get the cache-control header value.
*
* This removes "max-age=0" which could hypothetically be used by
* Varnish on an immediate subsequent request.
*
* @return string
*/
private function get_cache_control_header_value() {
if ( ! is_admin() && ! is_user_logged_in() ) {
$ttl = absint( $this->options['default_ttl'] );
if ( $ttl < 60 && isset( $_ENV['PANTHEON_ENVIRONMENT'] ) && 'live' === $_ENV['PANTHEON_ENVIRONMENT'] ) {
$ttl = 60;
}
return sprintf( 'public, max-age=%d', $ttl );
} else {
return 'no-cache, no-store, must-revalidate';
}
}
/**
* Add the cache-control header.
*
* @return void
*/
public function cache_add_headers() {
header( sprintf( 'cache-control: %s', $this->get_cache_control_header_value() ) );
}
/**
* Send the cache control header for REST API requests
*
* @param WP_REST_Response $response Response.
* @return WP_REST_Response Response.
*/
public function filter_rest_post_dispatch_send_cache_control( $response ) {
$response->header( 'Cache-Control', $this->get_cache_control_header_value() );
return $response;
}
/**
* Clear the cache for the entire site.
*
* @return void|false
*/
public function flush_site() {
if ( ! function_exists( 'current_user_can' ) || false === current_user_can( 'manage_options' ) ) {
return false;
}
if ( ! empty( $_POST['pantheon-cache-nonce'] ) && wp_verify_nonce( $_POST['pantheon-cache-nonce'], 'pantheon-cache-clear-all' ) ) {
if ( function_exists( 'pantheon_clear_edge_all' ) ) {
pantheon_clear_edge_all();
}
wp_cache_flush();
wp_safe_redirect( admin_url( 'options-general.php?page=pantheon-cache&cache-cleared=true' ) );
exit();
}
}
/**
* Clear the cache for a post.
*
* @deprecated
*
* @param int $post_id A post ID to clean.
* @return void
*/
public function clean_post_cache( $post_id, $include_homepage = true ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable,Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
if ( method_exists( 'Pantheon_Advanced_Page_Cache\Purger', 'action_clean_post_cache' ) ) {
Pantheon_Advanced_Page_Cache\Purger::action_clean_post_cache( $post_id );
}
}
/**
* Clear the cache for a given term or terms and taxonomy.
*
* @deprecated
*
* @param int|array $term_ids Single or list of Term IDs.
* @param string $taxonomy Can be empty and will assume tt_ids, else will use for context.
* @return void
*/
public function clean_term_cache( $term_ids, $taxonomy ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed,VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
if ( method_exists( 'Pantheon_Advanced_Page_Cache\Purger', 'action_clean_term_cache' ) ) {
Pantheon_Advanced_Page_Cache\Purger::action_clean_term_cache( $term_ids );
}
}
/**
* Clear the cache for a given term or terms and taxonomy.
*
* @deprecated
*
* @param int|array $object_ids Single or list of term object ID(s).
* @param array|string $object_type The taxonomy object type.
* @return void
*/
public function clean_object_term_cache( $object_ids, $object_type ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
// Handled by Pantheon Integrated CDN.
}
/**
* Enqueue Fully-qualified urls to be cleared on shutdown.
*
* @param array|string $urls List of full urls to clear.
* @return void
*/
public function enqueue_urls( $urls ) {
$paths = [];
$urls = array_filter( (array) $urls, 'is_string' );
foreach ( $urls as $full_url ) {
// Parse down to the path+query, escape regex.
$parsed = parse_url( $full_url );
// Sometimes parse_url can return false, on malformed urls.
if ( false === $parsed ) {
continue;
}
// Build up the path, checking if the array key exists first.
if ( array_key_exists( 'path', $parsed ) ) {
$path = $parsed['path'];
if ( array_key_exists( 'query', $parsed ) ) {
$path = $path . $parsed['query'];
}
} else {
// If the path doesn't exist, set it to the null string.
$path = '';
}
if ( '' === $path ) {
continue;
}
$path = '^' . preg_quote( $path ) . '$'; // phpcs:ignore WordPress.PHP.PregQuoteDelimiter.Missing
$paths[] = $path;
}
$this->paths = array_merge( $this->paths, $paths );
}
/**
* Enqueue a regex to be cleared.
*
* You must understand regular expressions to use this, and be careful.
*
* @param string $regex path regex to clear.
* @return void
*/
public function enqueue_regex( $regex ) {
$this->paths[] = $regex;
}
public function cache_clean_urls() {
if ( empty( $this->paths ) ) {
return;
}
$this->paths = apply_filters( 'pantheon_clean_urls', array_unique( $this->paths ) );
// Call the big daddy here.
$this->paths = apply_filters( 'pantheon_final_clean_urls', $this->paths );
if ( function_exists( 'pantheon_clear_edge_paths' ) ) {
pantheon_clear_edge_paths( $this->paths );
}
}
}
/**
* Get a reference to the singleton.
*
* This can be used to reference public methods, e.g. `Pantheon_Cache()->clean_post_cache( 123 )`
*/
function Pantheon_Cache() {
return Pantheon_Cache::instance();
}
add_action( 'plugins_loaded', 'Pantheon_Cache' );
/**
* @see Pantheon_Cache::clean_post_cache
*
* @deprecated Please call Pantheon Integrated CDN instead.
*/
function pantheon_clean_post_cache( $post_id, $include_homepage = true ) {
Pantheon_Cache()->clean_post_cache( $post_id, $include_homepage );
}
/**
* @see Pantheon_Cache::clean_term_cache
*
* @deprecated Please call Pantheon Integrated CDN instead.
*/
function pantheon_clean_term_cache( $term_ids, $taxonomy ) {
Pantheon_Cache()->clean_term_cache( $term_ids, $taxonomy );
}
/**
* @see Pantheon_Cache::enqueue_urls
*
* @deprecated Please call Pantheon Integrated CDN instead.
*/
function pantheon_enqueue_urls( $urls ) {
Pantheon_Cache()->enqueue_urls( $urls );
}

View File

@@ -0,0 +1,29 @@
<?php
/**
* If a Pantheon site is in Git mode, hide the Plugin installation functionality and show a notice.
*/
if ( ! wp_is_writable( WP_PLUGIN_DIR ) ) {
if ( ! defined( 'DISALLOW_FILE_MODS' ) ) {
define( 'DISALLOW_FILE_MODS', true );
}
add_action( 'admin_notices', '_pantheon_plugin_install_notice' );
add_action( 'network_admin_notices', '_pantheon_plugin_install_notice' );
}
function _pantheon_plugin_install_notice() {
$screen = get_current_screen();
// Only show this notice on the plugins page.
if ( 'plugins' === $screen->id || 'plugins-network' === $screen->id ) { ?>
<div class="update-nag notice notice-warning is-dismissible" style="margin: 5px 6em 15px 0;">
<p style="font-size: 14px; margin: 0;">
<?php
// Translators: %s is a URL to the user's Pantheon Dashboard.
echo wp_kses_post( sprintf( __( 'If you wish to update or add plugins using the WordPress UI, switch your site to SFTP mode from <a href="%s">your Pantheon dashboard</a>.', 'pantheon-systems' ), 'https://dashboard.pantheon.io/sites/' . $_ENV['PANTHEON_SITE'] ) );
?>
</p>
</div>
<?php
}
}

View File

@@ -0,0 +1,181 @@
<?php
/**
* Pantheon MU Plugin Updates
*
* Handles modifying the default WordPress update behavior on Pantheon.
*/
// If on Pantheon...
if ( isset( $_ENV['PANTHEON_ENVIRONMENT'] ) ) {
// Disable WordPress auto updates.
if ( ! defined( 'WP_AUTO_UPDATE_CORE' ) ) {
define( 'WP_AUTO_UPDATE_CORE', false );
}
remove_action( 'wp_maybe_auto_update', 'wp_maybe_auto_update' );
// Remove the default WordPress core update nag.
add_action( 'admin_menu', '_pantheon_hide_update_nag' );
}
/**
* Remove the default WordPress core update nag message.
*
* @return void
*/
function _pantheon_hide_update_nag() {
remove_action( 'admin_notices', 'update_nag', 3 );
remove_action( 'network_admin_notices', 'update_nag', 3 );
}
/**
* Helper function that returns the current WordPress version.
*
* @return string
*/
function _pantheon_get_current_wordpress_version(): string {
include ABSPATH . WPINC . '/version.php';
return $wp_version; // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable
}
/**
* Get the latest WordPress version.
*
* @return string|null
*/
function _pantheon_get_latest_wordpress_version(): ?string {
$core_updates = get_core_updates();
if ( ! is_array( $core_updates ) || empty( $core_updates ) || ! property_exists( $core_updates[0], 'current' ) ) {
return null;
}
return $core_updates[0]->current;
}
/**
* Check if WordPress core is at the latest version.
*
* @return bool
*/
function _pantheon_is_wordpress_core_latest(): bool {
$latest_wp_version = _pantheon_get_latest_wordpress_version();
$wp_version = _pantheon_get_current_wordpress_version();
if ( null === $latest_wp_version ) {
return true;
}
// Return true if our version is the latest.
return version_compare( str_replace( '-src', '', $latest_wp_version ), str_replace( '-src', '', $wp_version ), '<=' ); // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable
}
/**
* Check if WordPress core is a pre-release version.
*
* @return bool
*/
function _pantheon_is_wordpress_core_prerelease(): bool {
$wp_version = _pantheon_get_current_wordpress_version();
// Return true if our version is a prerelease. Pre-releases are identified by a dash in the version number.
return false !== strpos( $wp_version, '-' ); // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable
}
/**
* Replace WordPress core update nag EVERYWHERE with our own notice.
* Use git upstream instead
*
* @return void
*/
function _pantheon_upstream_update_notice() {
$wp_version = _pantheon_get_current_wordpress_version();
$screen = get_current_screen();
// Translators: %s is a URL to the user's Pantheon Dashboard.
$notice_message = sprintf( __( 'Check for updates on <a href="%s">your Pantheon dashboard</a>.', 'pantheon-systems' ), 'https://dashboard.pantheon.io/sites/' . $_ENV['PANTHEON_SITE'] );
// Translators: %s is a URL to Pantheon's upstream updates documentation.
$upstream_help_message = sprintf( __( 'For details on applying updates, see the <a href="%s">Applying Upstream Updates</a> documentation.', 'pantheon-systems' ), 'https://docs.pantheon.io/core-updates' );
$update_help = __( 'If you need help, contact an administrator for your Pantheon organization.', 'pantheon-systems' );
$div_class = esc_attr( 'update-nag notice notice-warning' );
$div_style = esc_attr( 'display: table;' );
$paragraph_style = esc_attr( 'font-size: 14px; font-weight: bold; margin: 0 0 0.5em 0;' );
if ( ! _pantheon_is_wordpress_core_latest() ) {
// If WP core is out of date, alter the message and show the nag everywhere.
// Translators: %s is a URL to the user's Pantheon Dashboard.
$notice_message = sprintf( __( 'A new WordPress update is available! Please update from <a href="%s">your Pantheon dashboard</a>.', 'pantheon-systems' ), 'https://dashboard.pantheon.io/sites/' . $_ENV['PANTHEON_SITE'] );
}
// If WP core is a pre-release, alter the message.
if ( _pantheon_is_wordpress_core_prerelease() ) {
$version = '<span style="font-weight: normal;">(' . $wp_version . ')</span>';
$paragraph_style = esc_attr( 'font-size: 14px;' );
// Translators: %s is the current WordPress version.
$notice_message = sprintf( __( '<strong>You are using a development version of WordPress.</strong> %s', 'pantheon-systems' ), $version );
// If we're on the Updates page, add a note about the Beta Tester plugin.
if ( 'update-core' === $screen->id || 'update-core-network' === $screen->id ) {
$notice_message .= '<br /><span style="font-weight: normal;">';
$notice_message .= __( 'You are responsible for keeping WordPress up-to-date. Pantheon updates to WordPress will not appear in the dashboard as long as you\'re using a pre-release version. If you are using the Beta Tester plugin, you must have your site in SFTP mode to get the latest updates to your Pantheon Dev environment.', 'pantheon-systems' );
}
}
ob_start();
?>
<div class="<?php echo esc_attr( $div_class ); ?>" style="<?php echo esc_attr( $div_style ); ?>">
<p style="<?php echo esc_attr( $paragraph_style ); ?>">
<?php echo wp_kses_post( $notice_message ); ?>
</p>
<?php if ( ! _pantheon_is_wordpress_core_prerelease() ) : ?>
<?php echo wp_kses_post( $upstream_help_message ); ?>
<br />
<?php echo wp_kses_post( $update_help ); ?>
<?php endif; ?>
</div>
<?php
$notice_html = ob_get_clean();
// If a WP core update is not detected, only show the nag on the updates page.
if ( ! _pantheon_is_wordpress_core_latest() || 'update-core' === $screen->id || 'update-core-network' === $screen->id ) {
// Escaping is handled above when we're buffering the output, so we can ignore it here.
echo $notice_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
}
/**
* Register Pantheon specific WordPress update admin notice.
*
* @return void
*/
function _pantheon_register_upstream_update_notice() {
// Only register notice if we are on Pantheon and this is not a WordPress Ajax request.
if ( isset( $_ENV['PANTHEON_ENVIRONMENT'] ) && ! wp_doing_ajax() ) {
add_action( 'admin_notices', '_pantheon_upstream_update_notice' );
add_action( 'network_admin_notices', '_pantheon_upstream_update_notice' );
}
}
add_action( 'admin_init', '_pantheon_register_upstream_update_notice' );
/**
* Return zero updates and current time as last checked time.
*
* @return object
*/
function _pantheon_disable_wp_updates(): object {
$wp_version = _pantheon_get_current_wordpress_version();
return (object) [
'updates' => [],
'version_checked' => $wp_version, // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable
'last_checked' => time(),
];
}
// In the Test and Live environments, clear plugin/theme update notifications.
// Users must check a dev or multidev environment for updates.
if ( isset( $_ENV['PANTHEON_ENVIRONMENT'] ) && in_array( $_ENV['PANTHEON_ENVIRONMENT'], [ 'test', 'live' ], true ) && ( php_sapi_name() !== 'cli' ) ) {
// Disable Plugin Updates.
remove_action( 'load-update-core.php', 'wp_update_plugins' );
add_filter( 'pre_site_transient_update_plugins', '_pantheon_disable_wp_updates' );
// Disable Theme Updates.
remove_action( 'load-update-core.php', 'wp_update_themes' );
add_filter( 'pre_site_transient_update_themes', '_pantheon_disable_wp_updates' );
}

View File

@@ -0,0 +1,54 @@
<?php
/**
* Plugin Name: Pantheon
* Plugin URI: https://pantheon.io/
* Description: Building on Pantheon's and WordPress's strengths, together.
* Version: 1.2.1
* Author: Pantheon
* Author URI: https://pantheon.io/
*
* @package pantheon
*/
define( 'PANTHEON_MU_PLUGIN_VERSION', '1.2.1' );
if ( isset( $_ENV['PANTHEON_ENVIRONMENT'] ) ) {
require_once 'inc/pantheon-page-cache.php';
if ( ! defined( 'DISABLE_PANTHEON_UPDATE_NOTICES' ) || ! DISABLE_PANTHEON_UPDATE_NOTICES ) {
require_once 'inc/pantheon-updates.php';
}
if ( ! defined( 'RETURN_TO_PANTHEON_BUTTON' ) || RETURN_TO_PANTHEON_BUTTON ) {
require_once 'inc/pantheon-login-form-mods.php';
}
if ( 'dev' === $_ENV['PANTHEON_ENVIRONMENT'] && function_exists( 'wp_is_writable' ) ) {
require_once 'inc/pantheon-plugin-install-notice.php';
}
if ( defined( 'WP_CLI' ) && WP_CLI ) {
require_once 'inc/cli.php';
}
if ( ! defined( 'FS_METHOD' ) ) {
/**
* When this constant is not set, WordPress writes and then deletes a
* temporary file to determine if it has direct access to the filesystem,
* which we already know to be the case. This multiplies filesystem
* operations and can degrade performance of the filesystem as a whole in
* the case of large sites that do a lot of filesystem operations.
* Setting this constant to 'direct' tells WordPress to assume it has
* direct access and skip creating the extra temporary file.
*/
define( 'FS_METHOD', 'direct' );
}
// When developing a WordPress Multisite locally, ensure that this constant is set.
// This will set the Multisite variable in all Pantheon environments.
if ( getenv( 'FRAMEWORK' ) === 'wordpress_network' && ! defined( 'WP_ALLOW_MULTISITE' ) ) {
define( 'WP_ALLOW_MULTISITE', true );
}
if ( defined( 'WP_ALLOW_MULTISITE' ) && WP_ALLOW_MULTISITE ) {
if ( defined( 'MULTISITE' ) && MULTISITE ) {
require_once 'inc/pantheon-network-setup.php';
} else {
require_once 'inc/pantheon-multisite-finalize.php';
}
}
} // Ensuring that this is on Pantheon.

View File

@@ -80,9 +80,15 @@
var data = [];
$( this ).closest( 'form' ).find( '[data-config-field]' ).each( function() {
var val = $( this ).val();
if ( $( this ).is( '[type=checkbox]' ) ) {
val = $( this ).is( ':checked' ) ? 1 : 0;
}
data.push( {
'name': $( this ).attr( 'name' ).replace( /^wpcf7-/, '' ).replace( /-/g, '_' ),
'value': $( this ).val()
'value': val
} );
} );

View File

@@ -79,7 +79,7 @@ function wpcf7_enqueue_block_editor_assets() {
'contact-form-7-block-editor',
sprintf(
'window.wpcf7 = {contactForms:%s};',
json_encode( $contact_forms )
wp_json_encode( $contact_forms )
),
'before'
);

View File

@@ -275,6 +275,17 @@ function wpcf7_sanitize_unit_tag( $tag ) {
function wpcf7_antiscript_file_name( $filename ) {
$filename = wp_basename( $filename );
// Apply part of protection logic from sanitize_file_name().
$filename = str_replace(
array(
'?', '[', ']', '/', '\\', '=', '<', '>', ':', ';', ',', "'", '"',
'&', '$', '#', '*', '(', ')', '|', '~', '`', '!', '{', '}',
'%', '+', '', '«', '»', '”', '“', chr( 0 )
),
'',
$filename
);
$filename = preg_replace( '/[\r\n\t -]+/', '-', $filename );
$filename = preg_replace( '/[\pC\pZ]+/iu', '', $filename );

View File

@@ -25,7 +25,7 @@ class WPCF7_SWV_FileRule extends WPCF7_SWV_Rule {
$acceptable_filetypes = array();
foreach ( (array) $this->get_property( 'accept' ) as $accept ) {
if ( false === strpos( $accept, '/' ) ) {
if ( preg_match( '/^\.[a-z0-9]+$/i', $accept ) ) {
$acceptable_filetypes[] = strtolower( $accept );
} else {
foreach ( wpcf7_convert_mime_to_ext( $accept ) as $ext ) {

View File

@@ -247,7 +247,7 @@ class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
'Accept' => 'application/json',
'Content-Type' => 'application/json; charset=utf-8',
),
'body' => json_encode( $properties ),
'body' => wp_json_encode( $properties ),
);
$response = $this->remote_request( $endpoint, $request );

View File

@@ -336,7 +336,7 @@ trait WPCF7_Sendinblue_API {
'Content-Type' => 'application/json; charset=utf-8',
'API-Key' => $this->get_api_key(),
),
'body' => json_encode( $properties ),
'body' => wp_json_encode( $properties ),
);
$response = wp_remote_post( $endpoint, $request );
@@ -364,7 +364,7 @@ trait WPCF7_Sendinblue_API {
'Content-Type' => 'application/json; charset=utf-8',
'API-Key' => $this->get_api_key(),
),
'body' => json_encode( $properties ),
'body' => wp_json_encode( $properties ),
);
$response = wp_remote_post( $endpoint, $request );

View File

@@ -61,7 +61,7 @@ class WPCF7_Stripe_API {
$headers = array(
'Authorization' => sprintf( 'Bearer %s', $this->secret ),
'Stripe-Version' => self::api_version,
'X-Stripe-Client-User-Agent' => json_encode( $ua ),
'X-Stripe-Client-User-Agent' => wp_json_encode( $ua ),
'User-Agent' => sprintf(
'%1$s/%2$s (%3$s)',
self::app_name,

View File

@@ -5,7 +5,7 @@ Tags: contact, form, contact form, feedback, email, ajax, captcha, akismet, mult
Requires at least: 6.2
Requires PHP: 7.4
Tested up to: 6.4
Stable tag: 5.8.3
Stable tag: 5.8.5
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -78,6 +78,14 @@ Do you have questions or issues with Contact Form 7? Use these support channels
For more information, see [Releases](https://contactform7.com/category/releases/).
= 5.8.5 =
[https://contactform7.com/contact-form-7-585/](https://contactform7.com/contact-form-7-585/)
= 5.8.4 =
[https://contactform7.com/contact-form-7-584/](https://contactform7.com/contact-form-7-584/)
= 5.8.3 =
[https://contactform7.com/contact-form-7-583/](https://contactform7.com/contact-form-7-583/)

View File

@@ -7,12 +7,12 @@
* Author URI: https://ideasilo.wordpress.com/
* License: GPL v2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Version: 5.8.3
* Version: 5.8.5
* Requires at least: 6.2
* Requires PHP: 7.4
*/
define( 'WPCF7_VERSION', '5.8.3' );
define( 'WPCF7_VERSION', '5.8.5' );
define( 'WPCF7_REQUIRED_WP_VERSION', '6.2' );

View File

@@ -1 +1 @@
.imagify-account,.imagify-account-link{padding-right:15px}.imagify-meteo-icon{display:inline-block;height:38px;vertical-align:middle;margin-right:10px}.imagify-user-plan{color:#40b1d0}.imagify-meteo-title.imagify-meteo-title{color:#fff;font-size:17px}.imagify-space-left>p{color:#fff}#wp-admin-bar-imagify-profile [class^=imagify-bar-]{position:relative;height:1.5em;width:100%;background:#60758d;color:#fff;font-size:10px}#wp-admin-bar-imagify-profile .imagify-progress{height:1.5em;font-size:1em}.imagify-progress{-webkit-transition:width .3s;-o-transition:width .3s;transition:width .3s}.imagify-bar-positive .imagify-progress{background:#8cc152}.imagify-bar-positive .imagify-barnb{color:#8cc152}.imagify-bar-negative .imagify-progress{background:#73818c}.imagify-bar-negative .imagify-barnb{color:#73818c}.imagify-bar-neutral .imagify-progress{background:#f5a623}.imagify-space-left .imagify-bar-negative .imagify-progress{background:#d0021b}#wpadminbar #wp-admin-bar-imagify-profile *{line-height:1.5;white-space:initial}#wpadminbar #wp-admin-bar-imagify .ab-submenu{padding-bottom:0}#wpadminbar #wp-admin-bar-imagify-profile .ab-item{height:auto;padding:0 13px}#wpadminbar #wp-admin-bar-imagify-profile{min-width:200px;padding:15px 0 10px;margin-top:.7em;background:#222}#wp-admin-bar-imagify .dashicons{font-family:dashicons;font-size:18px;vertical-align:middle;margin:0 5px 0 0}#wp-admin-bar-imagify .button-text{display:inline-block;vertical-align:middle}#wp-admin-bar-imagify .imagify-abq-row{display:table;width:100%}#wp-admin-bar-imagify .imagify-abq-row+.imagify-abq-row{margin-top:.75em}#wp-admin-bar-imagify .imagify-abq-row>*{display:table-cell}#wp-admin-bar-imagify-profile .imagify-meteo-icon{padding-right:7px}#wp-admin-bar-imagify-profile .imagify-meteo-icon img{width:37px}#wp-admin-bar-imagify-profile .imagify-meteo-title{font-size:17px}#wp-admin-bar-imagify-profile .imagify-meteo-subs{color:#72889f}#wpadminbar #wp-admin-bar-imagify-profile strong{font-weight:700}#wpadminbar #wp-admin-bar-imagify-profile .imagify-user-plan,#wpadminbar #wp-admin-bar-imagify-profile a{padding:0;color:#40b1d0}#wpadminbar #wp-admin-bar-imagify-profile .imagify-account-link{display:table}#wpadminbar #wp-admin-bar-imagify-profile .imagify-account-link>*{display:table-cell}#wpadminbar #wp-admin-bar-imagify-profile .imagify-space-left{max-width:210px;min-width:210px;width:210px}#wpadminbar #wp-admin-bar-imagify-profile .imagify-space-left p{font-size:12px}#wp-admin-bar-imagify-profile .imagify-error,#wp-admin-bar-imagify-profile .imagify-warning{padding:10px;margin:0 -13px -13px}#wp-admin-bar-imagify-profile .imagify-error p+p,#wp-admin-bar-imagify-profile .imagify-warning p+p{margin-top:.5em}#wp-admin-bar-imagify-profile .imagify-error p+p+p,#wp-admin-bar-imagify-profile .imagify-warning p+p+p{margin-top:1em}#wpadminbar #wp-admin-bar-imagify-profile .imagify-btn-ghost{display:inline-block;height:auto;padding:7px 10px;border:1px solid #fff;text-align:center;background:0 0;color:#fff;border-radius:3px;-webkit-transition:all .275s;-o-transition:all .275s;transition:all .275s}#wpadminbar #wp-admin-bar-imagify-profile .imagify-btn-ghost:focus,#wpadminbar #wp-admin-bar-imagify-profile .imagify-btn-ghost:hover{background:#fff;color:#888}#wpadminbar .imagify-warning *{background:#f5a623;color:#fff;text-shadow:0 0 2px rgba(0,0,0,.2)}
.imagify-account,.imagify-account-link{padding-right:15px}.imagify-meteo-icon{display:inline-block;height:38px;vertical-align:middle;margin-right:10px}.imagify-user-plan{color:#40b1d0}.imagify-meteo-title.imagify-meteo-title{color:#fff;font-size:17px}.imagify-space-left>p{color:#fff}#wp-admin-bar-imagify-profile [class^=imagify-bar-]{position:relative;height:1.5em;width:100%;background:#60758d;color:#fff;font-size:10px}#wp-admin-bar-imagify-profile .imagify-progress{height:1.5em;font-size:1em}.imagify-progress{-webkit-transition:width .3s;-o-transition:width .3s;transition:width .3s}.imagify-bar-positive .imagify-progress{background:#8cc152}.imagify-bar-positive .imagify-barnb{color:#8cc152}.imagify-bar-negative .imagify-progress{background:#73818c}.imagify-bar-negative .imagify-barnb{color:#73818c}.imagify-bar-neutral .imagify-progress{background:#f5a623}.imagify-space-left .imagify-bar-negative .imagify-progress{background:#d0021b}#wpadminbar #wp-admin-bar-imagify-profile *{line-height:1.5;white-space:initial}#wpadminbar #wp-admin-bar-imagify .ab-submenu{padding-bottom:0}#wpadminbar #wp-admin-bar-imagify-profile .ab-item{height:auto;padding:0 13px}#wpadminbar #wp-admin-bar-imagify-profile{min-width:200px;padding:15px 0 10px;margin-top:.7em;background:#222}#wp-admin-bar-imagify .dashicons{font-family:dashicons;font-size:18px;vertical-align:middle;margin:0 5px 0 0}#wp-admin-bar-imagify .button-text{display:inline-block;vertical-align:middle}#wp-admin-bar-imagify .imagify-abq-row{display:table;width:100%}#wp-admin-bar-imagify .imagify-abq-row+.imagify-abq-row{margin-top:.75em}#wp-admin-bar-imagify .imagify-abq-row>*{display:table-cell}#wp-admin-bar-imagify-profile .imagify-meteo-icon{padding-right:7px}#wp-admin-bar-imagify-profile .imagify-meteo-icon img{width:37px}#wp-admin-bar-imagify-profile .imagify-meteo-title{font-size:17px}#wp-admin-bar-imagify-profile .imagify-meteo-subs{color:#72889f}#wpadminbar #wp-admin-bar-imagify-profile strong{font-weight:700}#wpadminbar #wp-admin-bar-imagify-profile .imagify-user-plan,#wpadminbar #wp-admin-bar-imagify-profile a{padding:0;color:#40b1d0}#wpadminbar #wp-admin-bar-imagify-profile .imagify-account-link{display:table}#wpadminbar #wp-admin-bar-imagify-profile .imagify-account-link>*{display:table-cell}#wpadminbar #wp-admin-bar-imagify-profile .imagify-space-left{max-width:210px;min-width:210px;width:210px}#wpadminbar #wp-admin-bar-imagify-profile .imagify-space-left p{font-size:12px}#wp-admin-bar-imagify-profile .imagify-error,#wp-admin-bar-imagify-profile .imagify-warning{padding:10px;margin:0 -13px -13px}#wp-admin-bar-imagify-profile .imagify-error p+p,#wp-admin-bar-imagify-profile .imagify-warning p+p{margin-top:.5em}#wp-admin-bar-imagify-profile .imagify-error p+p+p,#wp-admin-bar-imagify-profile .imagify-warning p+p+p{margin-top:1em}#wpadminbar #wp-admin-bar-imagify-profile .imagify-btn-ghost{display:inline-block;height:auto;padding:7px 10px;border:1px solid #fff;text-align:center;background:0 0;color:#fff;border-radius:3px;-webkit-transition:all .275s;-o-transition:all .275s;transition:all .275s}#wpadminbar #wp-admin-bar-imagify-profile .imagify-btn-ghost:focus,#wpadminbar #wp-admin-bar-imagify-profile .imagify-btn-ghost:hover{background:#fff;color:#888}#wpadminbar .imagify-warning *{background:#f5a623;color:#fff;text-shadow:0 0 2px rgba(0,0,0,.2)}#wp-admin-bar-imagify-profile .imagify-upsell-admin-bar{position:relative;background:#c51161;margin:10px -13px -10px -13px;padding:20px}#wp-admin-bar-imagify-profile .imagify-upsell-admin-bar p{color:#fff}#wp-admin-bar-imagify-profile a.imagify-upsell-admin-bar-button{display:block;height:auto!important;border:1px solid #fff;border-radius:5px;color:#fff!important;padding:5px 10px!important;text-align:center;text-decoration:none;margin-top:10px}#wpadminbar #wp-admin-bar-imagify-profile a.imagify-upsell-dismiss{display:inline!important;height:auto!important}#wpadminbar #wp-admin-bar-imagify-profile .imagify-upsell-dismiss::before{position:absolute;top:5px;right:10px;content:"\2715";color:#fff}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
!function(n){n(".imagify-notice-dismiss").on("click.imagify",function(i){var e=n(this),t=e.parents(".imagify-welcome, .imagify-notice, .imagify-rkt-notice"),e=e.attr("href");i.preventDefault(),t.fadeTo(100,0,function(){n(this).slideUp(100,function(){n(this).remove()})}),n.get(e.replace("admin-post.php","admin-ajax.php"))})}(jQuery,(document,window)),function(n,a){n("#imagify-signup").on("click.imagify",function(i){i.preventDefault(),swal({title:imagifyNotices.labels.signupTitle,html:imagifyNotices.labels.signupText,confirmButtonText:imagifyNotices.labels.signupConfirmButtonText,input:"email",padding:0,showLoaderOnConfirm:!0,customClass:"imagify-sweet-alert imagify-sweet-alert-signup",inputValidator:function(t){return new Promise(function(i,e){""!==n.trim(t)&&t?i():e(imagifyNotices.labels.signupErrorEmptyEmail)})},preConfirm:function(i){return new Promise(function(e,t){setTimeout(function(){n.get(ajaxurl+a.imagify.concat+"action=imagify_signup&email="+i+"&imagifysignupnonce="+n("#imagifysignupnonce").val()).done(function(i){i.success?e():t(i.data)})},2e3)})}}).then(function(){swal({title:imagifyNotices.labels.signupSuccessTitle,html:imagifyNotices.labels.signupSuccessText,type:"success",padding:0,customClass:"imagify-sweet-alert"})})}),n("#imagify-save-api-key").on("click.imagify",function(i){i.preventDefault(),swal({title:imagifyNotices.labels.saveApiKeyTitle,html:imagifyNotices.labels.saveApiKeyText,confirmButtonText:imagifyNotices.labels.saveApiKeyConfirmButtonText,input:"text",padding:0,showLoaderOnConfirm:!0,customClass:"imagify-sweet-alert imagify-sweet-alert-signup",inputValidator:function(t){return new Promise(function(i,e){""!==n.trim(t)&&t?i():e(imagifyNotices.labels.ApiKeyErrorEmpty)})},preConfirm:function(i){return new Promise(function(e,t){n.get(ajaxurl+a.imagify.concat+"action=imagify_check_api_key_validity&api_key="+i+"&imagifycheckapikeynonce="+n("#imagifycheckapikeynonce").val()).done(function(i){i.success?e():t(i.data)})})}}).then(function(){swal({title:imagifyNotices.labels.ApiKeyCheckSuccessTitle,html:imagifyNotices.labels.ApiKeyCheckSuccessText,type:"success",padding:0,customClass:"imagify-sweet-alert"})})})}(jQuery,(document,window));
!function(n){n(".imagify-notice-dismiss").on("click.imagify",function(i){var e=n(this),t=e.parents(".imagify-welcome, .imagify-notice, .imagify-rkt-notice, .imagify-upsell, .imagify-upsell-admin-bar"),e=e.attr("href");i.preventDefault(),t.fadeTo(100,0,function(){n(this).slideUp(100,function(){n(this).remove()})}),n.get(e.replace("admin-post.php","admin-ajax.php"))})}(jQuery,(document,window)),function(n,a){n("#imagify-signup").on("click.imagify",function(i){i.preventDefault(),swal({title:imagifyNotices.labels.signupTitle,html:imagifyNotices.labels.signupText,confirmButtonText:imagifyNotices.labels.signupConfirmButtonText,input:"email",padding:0,showLoaderOnConfirm:!0,customClass:"imagify-sweet-alert imagify-sweet-alert-signup",inputValidator:function(t){return new Promise(function(i,e){""!==n.trim(t)&&t?i():e(imagifyNotices.labels.signupErrorEmptyEmail)})},preConfirm:function(i){return new Promise(function(e,t){setTimeout(function(){n.get(ajaxurl+a.imagify.concat+"action=imagify_signup&email="+i+"&imagifysignupnonce="+n("#imagifysignupnonce").val()).done(function(i){i.success?e():t(i.data)})},2e3)})}}).then(function(){swal({title:imagifyNotices.labels.signupSuccessTitle,html:imagifyNotices.labels.signupSuccessText,type:"success",padding:0,customClass:"imagify-sweet-alert"})})}),n("#imagify-save-api-key").on("click.imagify",function(i){i.preventDefault(),swal({title:imagifyNotices.labels.saveApiKeyTitle,html:imagifyNotices.labels.saveApiKeyText,confirmButtonText:imagifyNotices.labels.saveApiKeyConfirmButtonText,input:"text",padding:0,showLoaderOnConfirm:!0,customClass:"imagify-sweet-alert imagify-sweet-alert-signup",inputValidator:function(t){return new Promise(function(i,e){""!==n.trim(t)&&t?i():e(imagifyNotices.labels.ApiKeyErrorEmpty)})},preConfirm:function(i){return new Promise(function(e,t){n.get(ajaxurl+a.imagify.concat+"action=imagify_check_api_key_validity&api_key="+i+"&imagifycheckapikeynonce="+n("#imagifycheckapikeynonce").val()).done(function(i){i.success?e():t(i.data)})})}}).then(function(){swal({title:imagifyNotices.labels.ApiKeyCheckSuccessTitle,html:imagifyNotices.labels.ApiKeyCheckSuccessText,type:"success",padding:0,customClass:"imagify-sweet-alert"})})})}(jQuery,(document,window));

View File

@@ -3,7 +3,7 @@
* Plugin Name: Imagify
* Plugin URI: https://wordpress.org/plugins/imagify/
* Description: Dramatically reduce image file sizes without losing quality, make your website load faster, boost your SEO and save money on your bandwidth using Imagify, the new most advanced image optimization tool.
* Version: 2.1.3
* Version: 2.1.3.1
* Requires at least: 5.3
* Requires PHP: 7.0
* Author: Imagify Optimize Images & Convert WebP
@@ -19,7 +19,7 @@
defined( 'ABSPATH' ) || die( 'Cheatin uh?' );
// Imagify defines.
define( 'IMAGIFY_VERSION', '2.1.3' );
define( 'IMAGIFY_VERSION', '2.1.3.1' );
define( 'IMAGIFY_SLUG', 'imagify' );
define( 'IMAGIFY_FILE', __FILE__ );
define( 'IMAGIFY_PATH', realpath( plugin_dir_path( IMAGIFY_FILE ) ) . '/' );

View File

@@ -1,8 +1,8 @@
=== Imagify Optimize Images & Convert WebP | Compress Images Easily ===
Contributors: wp_rocket, imagify
Tags: optimize images, convert webp, webp converter, image optimization, compress images, image compressor, resize images, reduce image size, performance, image optimizer, core web vitals, best image optimization plugin
Tested up to: 6.3
Stable tag: 2.1.3
Tested up to: 6.4
Stable tag: 2.1.3.1
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -258,6 +258,9 @@ You can report any security bugs found in the source code of the site-reviews pl
4. Other Media Page
== Changelog ==
= 2.1.3.1 =
- Bugfix: missing styling on some banners when using minified versions of the CSS files (#765)
= 2.1.3 =
- Enhancement: Update chart.js (#742)
- Enhancement: Improve messaging around WebP images when they are larger than the original (#751)

View File

@@ -1,9 +1,9 @@
<?php return array(
'root' => array(
'name' => 'wp-media/imagify-plugin',
'pretty_version' => 'v2.1.3',
'version' => '2.1.3.0',
'reference' => '58a54d5f7381cc9884874f51021a0c791965fc05',
'pretty_version' => 'v2.1.3.1',
'version' => '2.1.3.1',
'reference' => '82a34afe494abd2ba229285f871ab23239428a20',
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -29,9 +29,9 @@
'dev_requirement' => false,
),
'wp-media/imagify-plugin' => array(
'pretty_version' => 'v2.1.3',
'version' => '2.1.3.0',
'reference' => '58a54d5f7381cc9884874f51021a0c791965fc05',
'pretty_version' => 'v2.1.3.1',
'version' => '2.1.3.1',
'reference' => '82a34afe494abd2ba229285f871ab23239428a20',
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),

View File

@@ -1,10 +1,5 @@
<?php
/**
* Created by PhpStorm.
* User: fabrizio pera
* Date: 22/11/16
* Time: 10:48
*/
if ( ! defined( 'ABSPATH' ) ) {
die( '-1' );
}
@@ -24,13 +19,8 @@ if(!class_exists('IperCampaignController')){
const kCOOKIE_ID_FIVE9 = "SESSfive9";
const kCOOKIE_WEB_PROMOTION_TEXT = "SESSpromotion";
const kCOOKIE_PHONE = "SESScampaignphone";
const KCOOKIE_ControlPhone = "SESScontrolphone";
const KCOOKIE_CanaryPhone = "SESScanaryphone";
const kCOOKIE_EXPIRE = 15552000; // 6 months (3600 * 24 * 30 * 6)
const KCOOKIE_WEB_TOP_BAR = "SESStopoffer";
const KCOOKIE_Google_KW = "SESSgooglekw";
const KCOOKIE_AB_Test = "SESSabtest";
const KCOOKIE_ConfirmationPageText = "SESSconfirmationpagetext";
protected static $instance;
public $testVar;
@@ -106,7 +96,6 @@ if(!class_exists('IperCampaignController')){
return $phonenumber;
}
public static function getCampaignID(){
if(!empty($_COOKIE) && !empty($_COOKIE[self::kCOOKIE_ID])){
return $_COOKIE[self::kCOOKIE_ID];
@@ -126,48 +115,8 @@ if(!class_exists('IperCampaignController')){
}
return null;
}
public static function getGoogle_KW(){
if(!empty($_COOKIE) && !empty($_COOKIE[self::kCOOKIE_Google_KW])){
return $_COOKIE[self::KCOOKIE_Google_KW];
}
if(!empty($_SESSION[self::KCOOKIE_Google_KW])){
return $_SESSION[self::KCOOKIE_Google_KW];
}
return null;
}
public static function getAB_Test(){
if(!empty($_COOKIE) && !empty($_COOKIE[self::KCOOKIE_AB_Test])){
return $_COOKIE[self::KCOOKIE_AB_Test];
}
if(!empty($_SESSION[self::KCOOKIE_AB_Test])){
return $_SESSION[self::KCOOKIE_AB_Test];
}
return null;
}
public static function getCanaryPhone(){
if(!empty($_COOKIE) && !empty($_COOKIE[self::KCOOKIE_CanaryPhone])){
return $_COOKIE[self::KCOOKIE_CanaryPhone];
}
if(!empty($_SESSION[self::KCOOKIE_CanaryPhone])){
return $_SESSION[self::KCOOKIE_CanaryPhone];
}
return null;
}
public static function getControlPhone(){
if(!empty($_COOKIE) && !empty($_COOKIE[self::KCOOKIE_ControlPhone])){
return $_COOKIE[self::KCOOKIE_ControlPhone];
}
if(!empty($_SESSION[self::KCOOKIE_ControlPhone])){
return $_SESSION[self::KCOOKIE_ControlPhone];
}
return null;
}
public static function getWebPromotionText(){
public static function getWebPromotionText(){
if(!empty($_COOKIE) && !empty($_COOKIE[self::kCOOKIE_WEB_PROMOTION_TEXT])){
return $_COOKIE[self::kCOOKIE_WEB_PROMOTION_TEXT];
}
@@ -176,25 +125,7 @@ if(!class_exists('IperCampaignController')){
}
return null;
}
public static function getConfirmationPageText(){
if(!empty($_COOKIE) && !empty($_COOKIE[self::KCOOKIE_ConfirmationPageText])){
return $_COOKIE[self::KCOOKIE_ConfirmationPageText];
}
if(!empty($_SESSION[self::KCOOKIE_ConfirmationPageText])){
return $_SESSION[self::KCOOKIE_ConfirmationPageText];
}
return null;
}
public static function getCampaignSO(){
if(!empty($_COOKIE) && !empty($_COOKIE[self::KCOOKIE_WEB_TOP_BAR])){
return $_COOKIE[self::KCOOKIE_WEB_TOP_BAR];
}
if(!empty($_SESSION[self::KCOOKIE_WEB_TOP_BAR])){
return $_SESSION[self::KCOOKIE_WEB_TOP_BAR];
}
return null;
}
public function get_phone_number(){
$phoneNumber = get_option('cta_tel',true);
@@ -239,32 +170,20 @@ if(!class_exists('IperCampaignController')){
return false;
}
public function setCampaign($id="",$phone="",$id_five_9="",$WebPromotionText="",$WebTopBarSpecialOffer="",$Google_KW, $ABTest, $ConfirmationPageText="",$CanaryPhone="",$ControlPhone=""){
public function setCampaign($id="",$phone="",$id_five_9="",$WebPromotionText=""){
setcookie(self::kCOOKIE_ID, $id, 0,'/');
setcookie(self::kCOOKIE_PHONE, $phone, 0,'/');
setcookie(self::KCOOKIE_CanaryPhone, $CanaryPhone , 0,'/');
setcookie(self::KCOOKIE_ControlPhone, $ControlPhone , 0,'/');
setcookie(self::kCOOKIE_ID_FIVE9, $id_five_9, 0,'/');
setcookie(self::kCOOKIE_WEB_PROMOTION_TEXT, $WebPromotionText , 0,'/');
setcookie(self::KCOOKIE_WEB_TOP_BAR, $WebTopBarSpecialOffer , 0,'/');
setcookie(self::KCOOKIE_Google_KW, $Google_KW , 0,'/');
setcookie(self::KCOOKIE_AB_Test, $ABTest , 0,'/');
setcookie(self::KCOOKIE_ConfirmationPageText, $ConfirmationPageText , 0,'/');
if(!session_id()){
session_start();
}
$_SESSION[self::kCOOKIE_ID]=$id;
$_SESSION[self::kCOOKIE_PHONE]=$phone;
$_SESSION[self::KCOOKIE_CanaryPhone]=$CanaryPhone;
$_SESSION[self::KCOOKIE_ControlPhone]=$ControlPhone;
$_SESSION[self::kCOOKIE_ID_FIVE9]=$id_five_9;
$_SESSION[self::kCOOKIE_WEB_PROMOTION_TEXT]=$WebPromotionText;
$_SESSION[self::KCOOKIE_WEB_TOP_BAR]=$WebTopBarSpecialOffer;
$_SESSION[self::KCOOKIE_Google_KW]=$Google_KW;
$_SESSION[self::KCOOKIE_AB_Test]=$ABTest;
$_SESSION[self::KCOOKIE_ConfirmationPageText]=$ConfirmationPageText;
}
public function activate(){
@@ -300,19 +219,12 @@ if(!class_exists('IperCampaignController')){
$CampaignID = $single->CampaignID;
$StartDate = $single->StartDate;
$PhoneNumber = $single->PhoneNumber;
$CanaryPhone = $single->CanaryPhoneNumber;
$ControlPhone = $single->ControlPhoneNumber;
$LandingURL = $single->LandingURL;
$FriendlyURL = $single->FriendlyURL;
$EndDate = $single->EndDate;
$CampaignName = $single->CampaignName;
$Five9CallbackCampaign = $single->Five9CallbackCampaign;
$WebPromotionText = $single->WebPromotionText;//fill campaign field
$WebTopBarSpecialOffer = $single->WebTopBarSpecialOffer;
$Google_KW = $single->GoogleKW;
$ABTest = $single->ABTest;
$ConfirmationPageText = $single->ConfirmationPageText;
$postname = str_replace(get_bloginfo('wpurl'),"",$FriendlyURL);
@@ -343,19 +255,13 @@ if(!class_exists('IperCampaignController')){
IperCptCampaign::kMETA_CAMPAIGN_ID => $CampaignID,
IperCptCampaign::kMETA_CAMPAIGN_START_DATE => $StartDate,
IperCptCampaign::kMETA_CAMPAIGN_PHONE => $PhoneNumber,
IperCptCampaign::KMETA_CanaryPhone => $CanaryPhone,//pull text from sales force
IperCptCampaign::KMETA_ControlPhone => $ControlPhone,//pull text from sales force
IperCptCampaign::kMETA_CAMPAIGN_LANDING_URL => $LandingURL,
IperCptCampaign::kMETA_CAMPAIGN_SHORT_URL => $FriendlyURL,
IperCptCampaign::kMETA_CAMPAIGN_END_DATE => $EndDate,
IperCptCampaign::kMETA_CAMPAIGN_NAME => $CampaignName,
IperCptCampaign::kMETA_FIVE9 => $Five9CallbackCampaign,
IperCptCampaign::kMETA_WEB_PROMOTION_TEXT => $WebPromotionText,//pull text from sales force
IperCptCampaign::KMETA_WEB_TOP_BAR => $WebTopBarSpecialOffer,//pull text from sales force
IperCptCampaign::KMETA_Google_KW => $Google_KW,//pull text from sales force
IperCptCampaign::KMETA_AB_Test => $ABTest,//pull text from sales force
IperCptCampaign::KMETA_ConfirmationPageText => $ConfirmationPageText
)
IperCptCampaign::kMETA_WEB_PROMOTION_TEXT => $WebPromotionText,
)
);
wp_update_post($my_post);
@@ -375,17 +281,13 @@ if(!class_exists('IperCampaignController')){
IperCptCampaign::kMETA_CAMPAIGN_ID => $CampaignID,
IperCptCampaign::kMETA_CAMPAIGN_START_DATE => $StartDate,
IperCptCampaign::kMETA_CAMPAIGN_PHONE => $PhoneNumber,
IperCptCampaign::KMETA_CanaryPhone => $CanaryPhone,//pull text from sales force
IperCptCampaign::KMETA_ControlPhone => $ControlPhone,//pull text from sales force
IperCptCampaign::kMETA_CAMPAIGN_LANDING_URL => $LandingURL,
IperCptCampaign::kMETA_CAMPAIGN_SHORT_URL => $FriendlyURL,
IperCptCampaign::kMETA_CAMPAIGN_END_DATE => $EndDate,
IperCptCampaign::kMETA_CAMPAIGN_NAME => $CampaignName,
IperCptCampaign::kMETA_FIVE9 => $Five9CallbackCampaign,
IperCptCampaign::kMETA_WEB_PROMOTION_TEXT => $WebPromotionText,//pull text from sales force
IperCptCampaign::KMETA_AB_Test => $ABTest,//pull text from sales force
IperCptCampaign::KMETA_WEB_TOP_BAR => $WebTopBarSpecialOffer,//pull text from sales force
IperCptCampaign::KMETA_ConfirmationPageText => $ConfirmationPageText//pull text from sales force
)
);

View File

@@ -1,10 +1,4 @@
<?php
/**
* Created by PhpStorm.
* User: fabrizio pera
* Date: 22/11/16
* Time: 10:52
*/
if(!class_exists('IperCptCampaign')) {
@@ -17,48 +11,36 @@ if(!class_exists('IperCptCampaign')) {
const DESCRIPTION = "Post type for Campaign";
const QUERY_VAR = "campaign";
//meta key
const kMETA_CAMPAIGN_ID = "campaign_id";
const kMETA_CAMPAIGN_START_DATE = "campaign_start_date";
const kMETA_CAMPAIGN_END_DATE = "campaign_end_date";
const kMETA_CAMPAIGN_PHONE = "campaign_phone_number";
const KMETA_ControlPhone = "ControlPhoneNumber";
const KMETA_CanaryPhone = "CanaryPhoneNumber";
const kMETA_CAMPAIGN_SHORT_URL = "campaign_short_url";
const kMETA_CAMPAIGN_LANDING_URL = "campaign_landing_url";
const kMETA_CAMPAIGN_NAME = "campaign_name";
const kMETA_DELETE = "to_delete";
const kMETA_FIVE9 = "Five9CallbackCampaign";
const kMETA_WEB_PROMOTION_TEXT = "WebPromotionText";//Name text for campaign field
const KMETA_WEB_TOP_BAR = "WebTopBarSpecialOffer";
const KMETA_Google_KW = "GoogleKW";
const KMETA_AB_Test = "ABTest";
const KMETA_ConfirmationPageText = "ConfirmationPageText";
//meta array
private $_meta = array(
array('name'=>self::kMETA_CAMPAIGN_ID,'type'=>'input-text','title'=>'Campaign ID'),
array('name'=>self::kMETA_CAMPAIGN_NAME,'type'=>'input-text','title'=>'Campaign name'),
array('name'=>self::kMETA_CAMPAIGN_START_DATE,'type'=>'input-date','title'=>'Start date'),
array('name'=>self::kMETA_CAMPAIGN_END_DATE,'type'=>'input-date','title'=>'End date'),
array('name'=>self::kMETA_CAMPAIGN_PHONE,'type'=>'input-text','title'=>'Phone number'),
array('name'=>self::KMETA_ControlPhone,'type'=>'input-text','title'=>'Control Phone number'),
array('name'=>self::KMETA_CanaryPhone,'type'=>'input-text','title'=>'Canary 800 Number'),
array('name'=>self::kMETA_CAMPAIGN_SHORT_URL,'type'=>'input-text','title'=>'Friendly URL'),
array('name'=>self::kMETA_CAMPAIGN_LANDING_URL,'type'=>'input-text','title'=>'Landing URL'),
array('name'=>self::kMETA_FIVE9,'type'=>'input-text','title'=>'Five9 Callback Campaign'),
array('name'=>self::kMETA_WEB_PROMOTION_TEXT,'type'=>'input-text','title'=>'Web Promotion Text'),//label name for campaign field
array('name'=>self::KMETA_WEB_TOP_BAR,'type'=>'input-text','title'=>'Web Top Bar Special Offer'),
array('name'=>self::KMETA_Google_KW,'type'=>'input-text','title'=>'Google KW'),
array('name'=>self::KMETA_AB_Test,'type'=>'input-text','title'=>'A/B Test'),
array('name'=>self::KMETA_ConfirmationPageText,'type'=>'input-text','title'=>'Confirmation Page Text')
array('name'=>self::kMETA_WEB_PROMOTION_TEXT,'type'=>'input-text','title'=>'Web Promotion Text'),
);
public function __construct(){
add_action('init', array(&$this, 'init'));
add_action('admin_init', array(&$this, 'admin_init'));
//add_action('admin_print_scripts', array(&$this,'load_custom_wp_admin_script') );
add_filter('single_template',array(&$this,'single_template'));
}

View File

@@ -6,17 +6,11 @@ $campaignTitle = get_the_title();
$campaignID = get_post_meta(get_the_ID(),IperCptCampaign::kMETA_CAMPAIGN_ID,true);
$campaignPhone = get_post_meta(get_the_ID(),IperCptCampaign::kMETA_CAMPAIGN_PHONE,true);
$controlPhone = get_post_meta(get_the_ID(),IperCptCampaign::KMETA_ControlPhone,true);
$CanaryPhone = get_post_meta(get_the_ID(),IperCptCampaign::KMETA_CanaryPhone,true);
$campaignStart = get_post_meta(get_the_ID(),IperCptCampaign::kMETA_CAMPAIGN_START_DATE,true);
$campaignEnd = get_post_meta(get_the_ID(),IperCptCampaign::kMETA_CAMPAIGN_END_DATE,true);
$campaignLink = get_post_meta(get_the_ID(),IperCptCampaign::kMETA_CAMPAIGN_LANDING_URL,true);
$campaignFive9CallbackCampaign = get_post_meta(get_the_ID(),IperCptCampaign::kMETA_FIVE9,true);
$WebPromotionText = get_post_meta(get_the_ID(),IperCptCampaign::kMETA_WEB_PROMOTION_TEXT,true);
$WebTopBarSpecialOffer = get_post_meta(get_the_ID(),IperCptCampaign::KMETA_WEB_TOP_BAR,true);
$Google_KW = get_post_meta(get_the_ID(),IperCptCampaign::KMETA_Google_KW,true);
$ABTest = get_post_meta(get_the_ID(),IperCptCampaign::KMETA_AB_Test,true);
$ConfirmationPageText = get_post_meta(get_the_ID(),IperCptCampaign::KMETA_ConfirmationPageText,true);
$campaignStart.=" 00:00:00";
$campaignEnd.=" 23:59:59";
@@ -25,10 +19,8 @@ $campaignStart = strtotime($campaignStart);
$campaignEnd = strtotime($campaignEnd);
if($now>=$campaignStart && $now<=$campaignEnd){
//campaign active
$controller = IperCampaignController::instance();
$controller->setCampaign($campaignID,$campaignPhone,$campaignFive9CallbackCampaign,$WebPromotionText,$WebTopBarSpecialOffer,$Google_KW,$ABTest,$ConfirmationPageText,$CanaryPhone,$controlPhone);
$controller->setCampaign($campaignID,$campaignPhone,$campaignFive9CallbackCampaign,$WebPromotionText);
}else{
//campaign expired or not yet started
@@ -43,12 +35,6 @@ $myurl = get_option('siteurl');
$campaignurl = (empty($campaignLink)) ? get_home_url() : $campaignLink;
$utm_campaign = $_GET['dynamic_id'];
/* For testing
ob_flush();
ob_start();
var_dump($permalink);
file_put_contents("dumps.txt", ob_get_flush());
*/
switch ($utm_campaign) {
case "landline" :

View File

@@ -0,0 +1 @@
<?php return array('dependencies' => array('wp-components', 'wp-compose', 'wp-data', 'wp-edit-post', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-polyfill'), 'version' => 'b81b50e9375d8f85569a43863b885812');

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
{"translation-revision-date":"2023-04-23 03:33:05+0000","generator":"GlotPress\/4.0.0-alpha.3","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;","lang":"cs_CZ"},"Insights":["P\u0159ehledy"]}},"comment":{"reference":"index.js"}}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
{"translation-revision-date":"2023-04-23 03:33:04+0000","generator":"GlotPress\/4.0.0-alpha.3","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"de"},"Ignore post content in the indexing.":["Beitragsinhalt in der Indexierung ignorieren."],"Low-ranking search terms used to find this post:":["Niedrig rankende Suchbegriffe, um diesen Beitrag zu finden:"],"The most common search terms used to find this post:":["Die h\u00e4ufigsten Suchbegriffe, um diesen Beitrag zu finden:"],"Excluded posts for this post:":["Ausgeschlossene Beitr\u00e4ge f\u00fcr diesen Beitrag:"],"Related posts for this post:":["Verwandte Beitr\u00e4ge f\u00fcr diesen Beitrag:"],"Related posts":["Verwandte Beitr\u00e4ge"],"Exclusion":["Ausschluss"],"Pinning":["Anheften"],"Reason this post is not indexed:":["Grund, warum dieser Beitrag nicht indexiert ist:"],"MySQL columns:":["MySQL-Spalten:"],"Links to this post:":["Link zu diesem Beitrag:"],"Excerpt:":["Textauszug:"],"Custom fields:":["Individuelle Felder:"],"Comments:":["Kommentare:"],"Other taxonomies:":["Andere Taxonomien:"],"Tags:":["Schlagw\u00f6rter:"],"Categories:":["Kategorien:"],"Author:":["Autor:"],"Content:":["Inhalt:"],"Title:":["Titel:"],"use this":["dieses benutzen"],"not this":["nicht dieses"],"Insights":["Einsichten"],"A comma-separated list of post IDs to use as related posts for this post":["Eine kommagetrennte Liste von Beitrags-IDs, die als verwandte Beitr\u00e4ge f\u00fcr diesen Beitrag verwendet werden sollen"],"Don't show this as a related post for any post.":["Dies nicht als verwandten Beitrag f\u00fcr einen Beitrag anzeigen."],"Don't append the related posts to this page.":["Die verwandten Beitr\u00e4ge nicht an diese Seite anh\u00e4ngen."],"Exclude this post or page from the index.":["Diesen Beitrag oder diese Seite aus dem Index ausschlie\u00dfen."],"Pin this post for all searches it appears in.":["Diesen Beitrag f\u00fcr alle Suchanfragen anheften, in denen er erscheint."],"How Relevanssi sees this post":["Wie Relevanssi diesen Beitrag sieht"]}},"comment":{"reference":"index.js"}}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
{"translation-revision-date":"2023-04-23 03:33:05+0000","generator":"GlotPress\/4.0.0-alpha.3","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Ignore post content in the indexing.":["Ignora el contenido de la entrada en la indexaci\u00f3n."],"Low-ranking search terms used to find this post:":["T\u00e9rminos de b\u00fasqueda de bajo rango utilizados para encontrar esta entrada:"],"The most common search terms used to find this post:":["T\u00e9rminos de b\u00fasqueda m\u00e1s comunes utilizados para encontrar esta entrada:"],"Excluded posts for this post:":["Entradas excluidas para esta entrada:"],"Related posts for this post:":["Entradas relacionadas para esta entrada:"],"Related posts":["Entradas relacionadas"],"Exclusion":["Exclusi\u00f3n"],"Pinning":["Marcado"],"Reason this post is not indexed:":["Raz\u00f3n por la que esta entrada no est\u00e1 indexada:"],"MySQL columns:":["Columnas de MySQL"],"Links to this post:":["Enlaces a esta entrada:"],"Excerpt:":["Extracto:"],"Custom fields:":["Campos personalizados:"],"Comments:":["Comentarios:"],"Other taxonomies:":["Otras taxonom\u00edas:"],"Tags:":["Etiquetas:"],"Categories:":["Categor\u00edas:"],"Author:":["Autor:"],"Content:":["Contenido:"],"Title:":["T\u00edtulo:"],"use this":["usar este"],"not this":["no \u00e9ste"],"Insights":["Insights"],"A comma-separated list of post IDs to use as related posts for this post":["Lista separada por comas de ID de entradas para utilizarlas como entradas relacionadas de esta entrada"],"Don't show this as a related post for any post.":["No mostrar \u00e9ste como entrada relacionada de ninguna entradas."],"Don't append the related posts to this page.":["No a\u00f1adir entradas relacionadas a esta p\u00e1gina."],"Exclude this post or page from the index.":["Excluir esta entrada o p\u00e1gina del \u00edndex."],"Pin this post for all searches it appears in.":["Marca esta entrada para todas las b\u00fasquedas en las que aparezca."],"How Relevanssi sees this post":["C\u00f3mo ve Relevanssi esta entrada"]}},"comment":{"reference":"index.js"}}

View File

@@ -0,0 +1,120 @@
{
"translation-revision-date": "",
"generator": "WP-CLI\/2.6.0",
"source": "index.js",
"domain": "messages",
"locale_data": {
"messages": {
"": {
"domain": "messages",
"lang": "fi",
"plural-forms": "nplurals=2; plural=(n != 1);"
},
"not this": [
"ei t\u00e4t\u00e4"
],
"use this": [
"k\u00e4yt\u00e4 t\u00e4t\u00e4"
],
"How Relevanssi sees this post": [
"Kuinka Relevanssi n\u00e4kee artikkelin"
],
"Title:": [
"Otsikko:"
],
"Content:": [
"Sis\u00e4lt\u00f6:"
],
"Author:": [
"Tekij\u00e4:"
],
"Categories:": [
"Aiheet:"
],
"Tags:": [
"Avainsanat:"
],
"Other taxonomies:": [
"Muut taksonomiat:"
],
"Comments:": [
"Kommentit:"
],
"Custom fields:": [
"Avainkent\u00e4t:"
],
"Excerpt:": [
"Ote:"
],
"Links to this post:": [
"Sis\u00e4iset linkit:"
],
"MySQL columns:": [
"MySQL-sarakkeet:"
],
"Reason this post is not indexed:": [
"Miksi t\u00e4t\u00e4 artikkelia ei ole indeksoitu:"
],
"Pinning": [
"Artikkelin kiinnitt\u00e4minen"
],
"Pin this post for all searches it appears in.": [
"Kiinnit\u00e4 t\u00e4m\u00e4 artikkeli k\u00e4rkeen kaikissa hauissa, joissa se esiintyy."
],
"A comma-separated list of single word keywords or multi-word phrases.": [
"Pilkuilla erotettu lista yksitt\u00e4isi\u00e4 hakusanoja tai monisanaisia hakulauseita."
],
"If any of these keywords are present in the search query, this post will be moved on top of the search results.": [
"Jos joku n\u00e4ist\u00e4 hakusanoista esiintyy k\u00e4ytt\u00e4j\u00e4n haussa, t\u00e4m\u00e4 artikkeli kiinnitet\u00e4\u00e4n hakutulosten huipulle."
],
"You can add weights to pinned keywords like this: 'keyword (100)'. The post with the highest weight will be sorted first if there are multiple posts pinned to the same keyword.": [
"Voit lis\u00e4t\u00e4 kiinnitetyille avainsanoille painoja n\u00e4in: \u2019avainsana (100)\u2019. Jos samalla avainsanalla on kiinnitetty useampi artikkeli, tuloslistan ensimm\u00e4iseksi nostetaan se, jonka paino on suurin."
],
"Exclusion": [
"Artikkelien poissulkeminen"
],
"Exclude this post or page from the index.": [
"Poista t\u00e4m\u00e4 artikkeli indeksist\u00e4."
],
"Ignore post content in the indexing.": [
"\u00c4l\u00e4 huomioi artikkelin sis\u00e4lt\u00f6\u00e4 indeksoitaessa."
],
"If any of these keywords are present in the search query, this post will be removed from the search results.": [
"Jos joku n\u00e4ist\u00e4 hakusanoista esiintyy k\u00e4ytt\u00e4j\u00e4n haussa, t\u00e4m\u00e4 artikkeli poistetaan hakutuloksista."
],
"Related posts": [
"Aiheeseen liittyv\u00e4t artikkelit"
],
"Don't append the related posts to this page.": [
"\u00c4l\u00e4 lis\u00e4\u00e4 samankaltaisia artikkeleita t\u00e4lle sivulle."
],
"Don't show this as a related post for any post.": [
"\u00c4l\u00e4 n\u00e4yt\u00e4 t\u00e4t\u00e4 samankaltaisena artikkelina mill\u00e4\u00e4n sivulla."
],
"A comma-separated list of keywords to use for the Related Posts feature.": [
"Pilkulla erotettu lista avainsanoja samankaltaisten artikkelien etsimiseen."
],
"Anything entered here will used when searching for related posts. Using phrases with quotes is allowed, but will restrict the related posts to posts including that phrase.": [
"T\u00e4h\u00e4n merkittyj\u00e4 hakusanoja k\u00e4ytet\u00e4\u00e4n samankaltaisten artikkelien etsimiseen. Voit k\u00e4ytt\u00e4\u00e4 fraasihakua lainausmerkeill\u00e4, mutta se rajoittaa samankaltaiset artikkelit niihin, joissa fraasi esiintyy."
],
"A comma-separated list of post IDs to use as related posts for this post": [
"Pilkuilla erotettu lista t\u00e4m\u00e4n artikkelin liittyvin\u00e4 artikkeleina k\u00e4ytett\u00e4vien artikkelien ID-numeroista"
],
"Related posts for this post:": [
"Samankaltaiset artikkelit:"
],
"Excluded posts for this post:": [
"\u00c4l\u00e4 k\u00e4yt\u00e4 samankaltaisina artikkeleina t\u00e4lle artikkelille:"
],
"Insights": [
"Huomioita"
],
"The most common search terms used to find this post:": [
"Yleisimm\u00e4t hakusanat, joilla t\u00e4m\u00e4 artikkeli l\u00f6ydet\u00e4\u00e4n:"
],
"Low-ranking search terms used to find this post:": [
"Hakusanoja, joilla t\u00e4m\u00e4 artikkeli on l\u00f6ydetty matalilta sijoilta:"
]
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
{"translation-revision-date":"2023-04-23 03:33:04+0000","generator":"GlotPress\/4.0.0-alpha.3","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n > 1;","lang":"fr"},"Ignore post content in the indexing.":["Ignorer le contenu de la publication dans l\u2019indexation."],"use this":["utiliser ceci"],"not this":["pas cela"],"Insights":["Insights"],"A comma-separated list of post IDs to use as related posts for this post":["Une liste d\u2019ID de publications s\u00e9par\u00e9s par des virgules \u00e0 utiliser comme publications similaires pour cette publication"],"Don't show this as a related post for any post.":["N\u2019affichez ceci comme une publication similaire pour aucune publication."],"Don't append the related posts to this page.":["N\u2019ajoutez pas les publications similaires \u00e0 cette page."],"Exclude this post or page from the index.":["Exclure cette publication ou cette page de l\u2019index."],"Pin this post for all searches it appears in.":["\u00c9pinglez cette publication pour toutes les recherches dans lesquelles elle appara\u00eet."],"How Relevanssi sees this post":["Comment Relevanssi voit cette publication"]}},"comment":{"reference":"index.js"}}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
{"translation-revision-date":"2023-04-23 03:33:04+0000","generator":"GlotPress\/4.0.0-alpha.3","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"it"},"Insights":["Approfondimenti (Insights)"]}},"comment":{"reference":"index.js"}}

View File

@@ -0,0 +1,321 @@
msgid ""
msgstr ""
"Project-Id-Version: Relevanssi\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-08-14 14:06+0200\n"
"PO-Revision-Date: \n"
"Last-Translator: Alessandro Fiorotto <alex@fiorotto.com>\n"
"Language-Team: Fiorotto <alex@fiorotto.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Language: Italian\n"
"X-Poedit-Country: ITALY\n"
"X-Poedit-SourceCharset: utf-8\n"
#: relevanssi.php:703
msgid "There is no excerpt because this is a protected post."
msgstr "Non c'è alcun estratto perché il post è protetto."
#: relevanssi.php:994
msgid "Indexing complete!"
msgstr "Indicizzazione completata!"
#: relevanssi.php:1183
msgid "Relevanssi Search Options"
msgstr "Opzioni per Relevanssi Search"
#: relevanssi.php:1294
#, php-format
msgid "<div id='message' class='update fade'><p>Term '%s' added to stopwords!</p></div>"
msgstr "<div id='message' class='update fade'><p>Termine '%s' aggiunto alle parole inutili ai fini della ricerca!</p></div>"
#: relevanssi.php:1297
#, php-format
msgid "<div id='message' class='update fade'><p>Couldn't add term '%s' to stopwords!</p></div>"
msgstr "<div id='message' class='update fade'><p>Non posso aggiungere il termine '%s' alle parole inutili ai fini della ricerca!</p></div>"
#: relevanssi.php:1306
msgid "25 most common words in the index"
msgstr "Le 25 parole più comuni nell'indice"
#: relevanssi.php:1308
msgid "These words are excellent stopword material. A word that appears in most of the posts in the database is quite pointless when searching. This is also an easy way to create a completely new stopword list, if one isn't available in your language. Click the icon after the word to add the word to the stopword list. The word will also be removed from the index, so rebuilding the index is not necessary."
msgstr "Queste parole possono dimostrarsi inutili ai fini della ricerca. Una parola che compare nella maggior parte dei posti nel database è piuttosto inutile ai fini di una buona ricerca. Questo è anche un modo semplice per creare un nuovo elenco di parole non significative, se non è disponibile nella tua lingua. Fare clic sull'icona dopo la parola per aggiungere la parola alla lista delle parole non significative. La parola sarà rimossa dall'indice e non sarà necessario ricostruire l'indice se si effettua una modifica."
#: relevanssi.php:1331
msgid "Add to stopwords"
msgstr "Aggiungi alle parole inutili ai fini della ricerca"
#: relevanssi.php:1344
msgid "25 most popular queries"
msgstr "25 ricerche più effettuate"
#: relevanssi.php:1356
msgid "Recent queries that got 0 hits"
msgstr "Recenti ricerche che non hanno dato risultati"
#: relevanssi.php:1491
msgid "Title boost:"
msgstr "Potenziamento dal titolo:"
#: relevanssi.php:1492
#, php-format
msgid "Default: %d. 0 means titles are ignored, 1 means no boost, more than 1 gives extra value."
msgstr "Predefinito %d. 0 significa che i titoli sono ignorati, 1 significa non aumentare, mentre più di 1 da un valore in più."
#: relevanssi.php:1493
msgid "Tag boost:"
msgstr "Potenziamento da TAG"
#: relevanssi.php:1494
#, php-format
msgid "Default: %d. 0 means tags are ignored, 1 means no boost, more than 1 gives extra value."
msgstr "Predefinito %d. 0 significa che i tag sono ignorati, 1 significa non aumentare, mentre più di 1 da un valore in più."
#: relevanssi.php:1495
msgid "Comment boost:"
msgstr "Potenziamento dai commenti:"
#: relevanssi.php:1496
#, php-format
msgid "Default: %d. 0 means comments are ignored, 1 means no boost, more than 1 gives extra value."
msgstr "Predefinito %d. 0 significa che i commenti sono ignorati, 1 significa non aumentare, mentre più di 1 da un valore in più."
#: relevanssi.php:1497
msgid "Use search for admin:"
msgstr "Usa ricerca per admin:"
#: relevanssi.php:1498
msgid "If checked, Relevanssi will be used for searches in the admin interface"
msgstr "Se selezionato, Relevanssi sarà usato anche per le ricerche nell'interfaccia di amministrazione"
#: relevanssi.php:1499
msgid "Restrict search to these categories and tags:"
msgstr "Circoscrivi la ricerca a queste categorie e tag:"
#: relevanssi.php:1500
msgid "Enter a comma-separated list of category and tag IDs to restrict search to those categories or tags. You can also use <code>&lt;input type='hidden' name='cat' value='list of cats and tags' /&gt;</code> in your search form. The input field will overrun this setting."
msgstr "Inserire un elenco separato da virgola, con gli id degli articoli e/o delle pagine a cui sarà circoscritto l'ambito di ricerca. Si può anche usare il codice <code>&lt;input type='hidden' name='cat' value='list of cats and tags' /&gt;</code> nel modulo di ricerca e quello che si inserirà nel modulo sovrascriverà quanto impostato qui."
#: relevanssi.php:1501
msgid "Exclude these categories and tags from search:"
msgstr "Escludi queste categorie e tag dalla ricerca:"
#: relevanssi.php:1502
msgid "Enter a comma-separated list of category and tag IDs that are excluded from search results. This only works here, you can't use the input field option (WordPress doesn't pass custom parameters there)."
msgstr "Inserire un elenco separato da virgola, con gli id delle categorie e dei tag esclusi dai risultati della ricerca. Non è possibile sovrascrivere o cambiare questa impostazione inserendo dell'apposito codice nel modulo di ricerca."
#: relevanssi.php:1505
msgid "Exclude these posts/pages from search:"
msgstr "Escludi questi articoli/pagine dalla ricerca:"
#: relevanssi.php:1506
msgid "Enter a comma-separated list of post/page IDs that are excluded from search results. This only works here, you can't use the input field option (WordPress doesn't pass custom parameters there)."
msgstr "Inserire un elenco separato da virgola, con gli id degli articoli e/o delle pagine esclusi dai risultati della ricerca. Non è possibile sovrascrivere o cambiare questa impostazione inserendo dell'apposito codice nel modulo di ricerca."
#: relevanssi.php:1507
msgid "Index and search your posts' tags:"
msgstr "Indicizza e cerca i tag degli articoli:"
#: relevanssi.php:1508
msgid "If checked, Relevanssi will also index and search the tags of your posts. Remember to rebuild the index if you change this option!"
msgstr "Se selezionato, Relevanssi indicizzerà anche i tag degli articoli. Ricordati di ricostruire l'indice se cambi questa opzione!"
#: relevanssi.php:1509
msgid "Index and search these comments:"
msgstr "Indicizza e ricerca questi commenti:"
#: relevanssi.php:1510
msgid "Relevanssi will index and search ALL (all comments including track- &amp; pingbacks and custom comment types), NONE (no comments) or NORMAL (manually posted comments on your blog).<br />Remember to rebuild the index if you change this option!"
msgstr "Relevanssi consente di indicizzare e di effettuare le ricerche su TUTTO (compresi tutti i commenti, track & pingbacks e i commenti personalizzati), NESSUNO (commenti esclusi) o NORMALE (solo i commenti inseriti manualmente nel tuo blog). <br /> Ricordati di ricostruire l'indice, se modifichi questa opzione!"
#: relevanssi.php:1511
msgid "all"
msgstr "tutto"
#: relevanssi.php:1512
msgid "normal"
msgstr "normale"
#: relevanssi.php:1513
msgid "none"
msgstr "nessuno"
#: relevanssi.php:1516
msgid "Create custom search result snippets:"
msgstr "Crea un frammento di ricerca personalizzato:"
#: relevanssi.php:1517
msgid "If checked, Relevanssi will create excerpts that contain the search term hits. To make them work, make sure your search result template uses the_excerpt() to display post excerpts."
msgstr "Se selezionato, Relevanssi creerà un estratto che conterrà la parola cercata. Affinché funzioni, assicurarsi che il template utilizzi la funzione the_excerpt() per visualizzare il risultato della ricerca."
#: relevanssi.php:1518
msgid "Length of the snippet:"
msgstr "Lunghezza del frammento:"
#: relevanssi.php:1519
msgid "This must be an integer."
msgstr "Deve essere un numero intero."
#: relevanssi.php:1520
msgid "words"
msgstr "parole"
#: relevanssi.php:1521
msgid "characters"
msgstr "caratteri"
#: relevanssi.php:1522
msgid "Keep a log of user queries:"
msgstr "Conserva un log delle ricerche:"
#: relevanssi.php:1523
msgid "If checked, Relevanssi will log user queries."
msgstr "Se selezionato, Relevanssi terrà traccia delle ricerche effettuate."
#: relevanssi.php:1524
msgid "Highlight query terms in search results:"
msgstr "Evidenzia i termini di ricerca nei risultati:"
#: relevanssi.php:1525
msgid "Highlighting isn't available unless you use custom snippets"
msgstr "L'evidenziazione non è disponibile se non si utilizzano degli snippet personalizzati"
#: relevanssi.php:1526
msgid "Highlight query terms in result titles too:"
msgstr "Evidenzia i termini di ricerca anche nei titoli dei risultati:"
#: relevanssi.php:1529
msgid "Save"
msgstr "Salva"
#: relevanssi.php:1530
msgid "Building the index and indexing options"
msgstr "Costruisci l'indice e salva le opzioni di indicizzazione"
#: relevanssi.php:1531
msgid "After installing the plugin, you need to build the index. This generally needs to be done once, you don't have to re-index unless something goes wrong. Indexing is a heavy task and might take more time than your servers allow. If the indexing cannot be finished - for example you get a blank screen or something like that after indexing - you can continue indexing from where you left by clicking 'Continue indexing'. Clicking 'Build the index' will delete the old index, so you can't use that."
msgstr "Dopo aver installato il plugin, è necessario costruire l'indice. Questo genere deve essere fatto una volta solo e non si deve reindicizzare fino a che qualcosa non funziona bene. L'indicizzazione è un compito pesante e potrebbe richiedere più tempo di quanto i server consentono. Se l'indicizzazione non viene completata e si ottine ad esempio una pagina bianca o qualcosa del genere, è possibile continuare l'indicizzazione dal punto in cui è stata interrotta semplicemente premendo il tasto 'Continua indicizzazione'. Cliccando invece su 'costruisci l'indice' si reinizierà da zero la creazione dell'indicie."
#: relevanssi.php:1532
msgid "So, if you build the index and don't get the 'Indexing complete' in the end, keep on clicking the 'Continue indexing' button until you do. On my blogs, I was able to index ~400 pages on one go, but had to continue indexing twice to index ~950 pages."
msgstr "Se si crea l'indice e alla fine non si ottiene il risultato di 'indicizzazione completa', cliccare nuovamente sul pulsante 'Continua indicizzazione' fino a quando non si otterrà tale risultato. Il mo blog ad esempio è stato in grado di indicizzare circa 400 pagine in una volta sola, ma ha dovuto continuare l'indicizzazione due volte per completare l'indice di circa 950 pagine."
#: relevanssi.php:1533
msgid "Save indexing options and build the index"
msgstr "Salva le opzioni di indicizzazione e costruisci l'indice"
#: relevanssi.php:1534
msgid "Continue indexing"
msgstr "Continua indicizzazione"
#: relevanssi.php:1535
msgid "No highlighting"
msgstr "No evidenziazione"
#: relevanssi.php:1536
msgid "Text color"
msgstr "Colore del testo"
#: relevanssi.php:1537
msgid "Background color"
msgstr "Colore di sfondo"
#: relevanssi.php:1538
msgid "CSS Style"
msgstr "Stile CSS"
#: relevanssi.php:1539
msgid "CSS Class"
msgstr "Classe CSS"
#: relevanssi.php:1541
msgid "Text color for highlights:"
msgstr "Colore del testo delle evidenziazioni:"
#: relevanssi.php:1542
msgid "Background color for highlights:"
msgstr "Colore di sfondo delle evidenziazioni:"
#: relevanssi.php:1543
msgid "CSS style for highlights:"
msgstr "Stile CSS per le evidenziazioni:"
#: relevanssi.php:1544
msgid "CSS class for highlights:"
msgstr "Classe CSS per le evidenziazioni:"
#: relevanssi.php:1546
#: relevanssi.php:1547
msgid "Use HTML color codes (#rgb or #rrggbb)"
msgstr "Usare il codice colore HTML (#rgb o #rrggbb)"
#: relevanssi.php:1548
msgid "You can use any CSS styling here, style will be inserted with a &lt;span&gt;"
msgstr "È possibile usare qualsiasi stile CSS, lo stile sarà inserito con &lt;span&gt;"
#: relevanssi.php:1549
msgid "Name a class here, search results will be wrapped in a &lt;span&gt; with the class"
msgstr "Nome della classe qui. I risultati di ricerca saranno compresi in &lt;span&gt; con la classe"
#: relevanssi.php:1551
msgid "What to include in the index"
msgstr "Cosa includere nell'indice"
#: relevanssi.php:1552
msgid "Everything"
msgstr "Ogni cosa"
#: relevanssi.php:1553
msgid "Just posts"
msgstr "Solo articoli"
#: relevanssi.php:1554
msgid "Just pages"
msgstr "Solo pagine"
#: relevanssi.php:1556
msgid "Custom fields to index:"
msgstr "Campi personalizzati da indicizzare:"
#: relevanssi.php:1557
msgid "A comma-separated list of custom field names to include in the index."
msgstr "Una lista separata da virgola dei nomi personalizzati da includere nell'indice."
#: relevanssi.php:1559
msgid "Show breakdown of search hits in excerpts:"
msgstr "Viusalizza un separatore nei risultati di ricerca:"
#: relevanssi.php:1560
msgid "Check this to show more information on where the search hits were made. Requires custom snippets to work."
msgstr "Seleziona qui per mostrare più informazioni o per definire dove sarà effettuata la ricerca. Per attivarlo richiede uno snippet personalizzato."
#: relevanssi.php:1561
msgid "The breakdown format:"
msgstr "Formato dell'interruzione:"
#: relevanssi.php:1562
msgid "Use %body%, %title%, %tags%, %comments% and %score% to display the number of hits and the document weight."
msgstr "Usa %body%, %title%, %tags%, %comments% e %score% per visualizzare il numero di ricorrenze e il peso del documento."
#: relevanssi.php:1564
msgid "When to use fuzzy matching?"
msgstr "Quando usare la ricerca per parola simile?"
#: relevanssi.php:1565
msgid "When straight search gets no hits"
msgstr "Quando la ricerca regolare non produce risultati"
#: relevanssi.php:1566
msgid "Always"
msgstr "Sempre"
#: relevanssi.php:1567
msgid "Don't use fuzzy search"
msgstr "Non usare la ricerca per similitudini"
#: relevanssi.php:1568
msgid "Straight search matches just the term. Fuzzy search matches everything that begins or ends with the search term."
msgstr "La ricerca regolare cerca semplicemente un termine. La ricerca per similitudine trova anche tutti i termini che iniziano o finiscono come il termine di ricerca."

View File

@@ -0,0 +1 @@
{"translation-revision-date":"2023-01-25 12:26:59+0000","generator":"GlotPress\/4.0.0-alpha.3","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=1; plural=0;","lang":"ja_JP"},"Insights":["Insights"]}},"comment":{"reference":"index.js"}}

View File

@@ -0,0 +1 @@
{"translation-revision-date":"2023-04-23 03:33:04+0000","generator":"GlotPress\/4.0.0-alpha.3","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"nl"},"Insights":["Inzichten"]}},"comment":{"reference":"index.js"}}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
{"translation-revision-date":"2023-02-21 15:40:15+0000","generator":"GlotPress\/4.0.0-alpha.3","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=(n > 1);","lang":"pt_BR"},"Insights":["Insights"]}},"comment":{"reference":"index.js"}}

View File

@@ -0,0 +1,578 @@
msgid ""
msgstr ""
"Project-Id-Version: Relevanssi\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"Last-Translator: Pedro Padron <ppadron@w3p.com.br>\n"
"Language-Team: W3P Projetos Web <contato@w3p.com.br>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Language: Portuguese\n"
"X-Poedit-Country: BRAZIL\n"
"X-Poedit-Basepath: /\n"
"X-Poedit-SearchPath-0: /home/ppadron/Projects/wordpress-vanilla/wp-content/plugins/relevanssi\n"
#: relevanssi.php:1032
msgid "There is no excerpt because this is a protected post."
msgstr "Não há resumo porque esse é um post protegido."
#: relevanssi.php:1746
msgid "Relevanssi Search Options"
msgstr "Opções de Busca do Relevanssi"
#: relevanssi.php:1915
msgid "25 most common words in the index"
msgstr "25 palavras mais comuns no &iacute;ndice"
#: relevanssi.php:1917
msgid "These words are excellent stopword material. A word that appears in most of the posts in the database is quite pointless when searching. This is also an easy way to create a completely new stopword list, if one isn't available in your language. Click the icon after the word to add the word to the stopword list. The word will also be removed from the index, so rebuilding the index is not necessary."
msgstr "Estas palavras são excelentes para formar uma lista de stopwords. Uma palavra que aparece na maioria dos posts é um tanto quanto inútil em uma busca. Esta também é uma maneira fácil de criar uma nova lista de stopwords, caso uma não esteja disponível em seu idioma. Clique no ícone após a palavra para adicioná-la à lista de stopwords. A palavra também será removida do índice, então não é necessário reconstruí-lo."
#: relevanssi.php:1940
msgid "Add to stopwords"
msgstr "Adicionar à lista de stopwords"
#: relevanssi.php:1953
msgid "25 most popular queries"
msgstr "25 buscas mais populares"
#: relevanssi.php:1965
msgid "Recent queries that got 0 hits"
msgstr "Buscas recentes que não retornaram resultados"
#: relevanssi.php:2126
msgid "Title boost:"
msgstr "Prioridade do Título:"
#: relevanssi.php:2135
msgid "Use search for admin:"
msgstr "Usar a busca para o admin:"
#: relevanssi.php:2138
msgid "Restrict search to these categories and tags:"
msgstr "Restringir a busca para essas categorias e tags:"
#: relevanssi.php:2182
msgid "Create custom search result snippets:"
msgstr "Criar resumos de resultado de busca personalizados:"
#: relevanssi.php:2186
msgid "Length of the snippet:"
msgstr "Tamanho do resumo:"
#: relevanssi.php:2190
msgid "Keep a log of user queries:"
msgstr "Manter um histórico de buscas dos usuários:"
#: relevanssi.php:2191
msgid "If checked, Relevanssi will log user queries."
msgstr "Se ativada, Relevanssi irá armazenar as buscas feitas pelos usuários."
#: relevanssi.php:2195
msgid "Highlight query terms in search results:"
msgstr "Usar efeito marca-texto nos termos da busca nos resultados:"
#: relevanssi.php:2196
msgid "Highlighting isn't available unless you use custom snippets"
msgstr "Esta opção só está disponível se você utilizar resumos de resultados de busca personalizados"
#: relevanssi.php:2214
msgid "Continue indexing"
msgstr "Continuar Indexação"
#: relevanssi.php:2215
msgid "No highlighting"
msgstr "Sem efeito marca-texto"
#: relevanssi.php:2216
msgid "Text color"
msgstr "Cor do texto"
#: relevanssi.php:2217
msgid "Background color"
msgstr "Cor de fundo"
#: relevanssi.php:2218
msgid "CSS Style"
msgstr "CSS Style"
#: relevanssi.php:2219
msgid "CSS Class"
msgstr "Classe CSS"
#: relevanssi.php:2221
msgid "Text color for highlights:"
msgstr "Cor de texto para efeito marca-texto:"
#: relevanssi.php:2222
msgid "Background color for highlights:"
msgstr "Cor de fundo para efeito marca-texto:"
#: relevanssi.php:2223
msgid "CSS style for highlights:"
msgstr "Estilo CSS para efeito marca-texto:"
#: relevanssi.php:2224
msgid "CSS class for highlights:"
msgstr "Classe CSS para efeito marca-texto:"
#: relevanssi.php:2226
#: relevanssi.php:2227
msgid "Use HTML color codes (#rgb or #rrggbb)"
msgstr "Use cores em hexadecimal (#rgb ou #rrggbb)"
# @ default
#: relevanssi.php:94
#, php-format
msgid "Relevanssi needs attention: Remember to build the index (you can do it at <a href=\"%1$s\">the settings page</a>), otherwise searching won't work."
msgstr "Relevanssi precisa de atenção: Lembre-se de construir o índice (você pode fazê-lo na <a href=\"%1$s\">página de opções</a>), caso contrário a busca não irá funcionar."
#: relevanssi.php:1430
msgid "Indexing complete!"
msgstr "Indexação concluída!"
#: relevanssi.php:1903
#, php-format
msgid "<div id='message' class='update fade'><p>Term '%s' added to stopwords!</p></div>"
msgstr "<div id='message' class='update fade'><p>Termo '%s' adicionado à lista de stopwords!</p></div>"
#: relevanssi.php:1906
#, php-format
msgid "<div id='message' class='update fade'><p>Couldn't add term '%s' to stopwords!</p></div>"
msgstr "<div id='message' class='update fade'><p>Não foi possível adicionar '%s' à lista de stopwords!</p></div>"
#: relevanssi.php:2129
msgid "Tag boost:"
msgstr "Prioridade da Tag:"
#: relevanssi.php:2132
msgid "Comment boost:"
msgstr "Prioridade dos Comentários:"
#: relevanssi.php:2143
msgid "Exclude these categories and tags from search:"
msgstr "Excluir da busca essas categorias e tags:"
# @ relevanssi
#: relevanssi.php:2147
msgid "Exclusions and restrictions"
msgstr "Restrições"
#: relevanssi.php:2150
msgid "Exclude these posts/pages from search:"
msgstr "Excluir esses posts/páginas da busca:"
#: relevanssi.php:2154
msgid "Index and search your posts' tags:"
msgstr "Indexar e buscar as tags dos posts:"
#: relevanssi.php:2157
msgid "Index and search these comments:"
msgstr "Indexar e buscar nestes Comentários:"
#: relevanssi.php:2162
msgid "all"
msgstr "todos"
#: relevanssi.php:2163
msgid "normal"
msgstr "normal"
#: relevanssi.php:2164
msgid "none"
msgstr "nenhum"
#: relevanssi.php:2181
msgid "Custom excerpts/snippets"
msgstr "Resumos de resultado de busca personalizados"
#: relevanssi.php:2187
msgid "This must be an integer."
msgstr "O valor deve ser um número inteiro."
#: relevanssi.php:2188
msgid "words"
msgstr "palavras"
#: relevanssi.php:2189
msgid "characters"
msgstr "caracteres"
#: relevanssi.php:2192
msgid "Search hit highlighting"
msgstr "Efeito marca-texto"
# @ relevanssi
#: relevanssi.php:2193
msgid "First, choose the type of highlighting used:"
msgstr "Primeiramente, escolha o tipo de efeito marca-texto a ser utilizado:"
# @ relevanssi
#: relevanssi.php:2194
msgid "Then adjust the settings for your chosen type:"
msgstr "Ajuste as opções para o tipo escolhido:"
#: relevanssi.php:2198
msgid "Highlight query terms in result titles too:"
msgstr "Usar efeito marca-texto também nos títulos dos resultados:"
# @ relevanssi
#: relevanssi.php:2201
msgid "Save the options"
msgstr "Gravar as opções"
#: relevanssi.php:2202
msgid "Building the index and indexing options"
msgstr "Construindo o índice e opções de indexação"
#: relevanssi.php:2213
msgid "Save indexing options and build the index"
msgstr "Gravar opções de indexação e construir o índice"
#: relevanssi.php:2233
msgid "What to include in the index"
msgstr "O que incluir no índice"
#: relevanssi.php:2234
msgid "Everything"
msgstr "Tudo"
#: relevanssi.php:2235
msgid "Just posts"
msgstr "Apenas posts"
#: relevanssi.php:2236
msgid "Just pages"
msgstr "Apenas páginas"
#: relevanssi.php:2251
msgid "Custom fields to index:"
msgstr "Campos personalizados a serem indexados:"
#: relevanssi.php:2259
msgid "Show breakdown of search hits in excerpts:"
msgstr "Exibir mais informações de hits no resumo:"
#: relevanssi.php:2262
msgid "The breakdown format:"
msgstr "Formato das informações:"
#: relevanssi.php:2267
msgid "When to use fuzzy matching?"
msgstr "Quando utilizar busca fuzzy"
#: relevanssi.php:2268
msgid "When straight search gets no hits"
msgstr "Quando a busca direta não encontra resultados"
#: relevanssi.php:2269
msgid "Always"
msgstr "Sempre"
#: relevanssi.php:2270
msgid "Don't use fuzzy search"
msgstr "Não utilizar busca fuzzy"
# @ relevanssi
#: relevanssi.php:311
msgid "Data wiped clean, you can now delete the plugin."
msgstr "Dados removidos! Você pode remover o plugin agora."
# @ relevanssi
#: relevanssi.php:2280
msgid "Uninstall"
msgstr "Desinstalar"
# @ relevanssi
#: relevanssi.php:2284
msgid "Remove plugin data"
msgstr "Remover todos os dados do plugin"
# @ relevanssi
#: relevanssi.php:2274
msgid "Expand shortcodes in post content:"
msgstr "Converter os shortcodes "
#: relevanssi.php:2167
msgid "Index and search your posts' categories:"
msgstr "Indexar e buscar as categorias dos posts:"
#: relevanssi.php:2243
msgid "Custom post types to index"
msgstr "Tipos de Posts (custom post types) a serem indexados"
#: relevanssi.php:2255
msgid "Custom taxonomies to index:"
msgstr "Taxonomias personalizadas a serem indexadas:"
#: relevanssi.php:2127
#, php-format
msgid ""
"Default: %d. 0 means titles are ignored, 1 means no boost, more\n"
"\t\tthan 1 gives extra value."
msgstr "Padrão: %d. 0 significa que os títulos são ignorados, 1 significa nenhuma prioridade, mais de 1 aumenta a prioridade."
#: relevanssi.php:2130
#, php-format
msgid ""
"Default: %d. 0 means tags are ignored, 1 means no boost, more\n"
"\t\tthan 1 gives extra value."
msgstr "Padrão: %d. 0 significa que as tags são ignoradas, 1 significa nenhuma prioridade, mais de 1 aumenta a prioridade."
#: relevanssi.php:2133
#, php-format
msgid ""
"Default: %d. 0 means comments are ignored, 1 means no boost,\n"
"\t\tmore than 1 gives extra value."
msgstr "Padrão: %d. 0 significa que os comentários são ignorados, 1 significa nenhuma prioridade, mais de 1 aumenta a prioridade."
#: relevanssi.php:2136
msgid ""
"If checked, Relevanssi will be used for searches in the admin\n"
"\t\tinterface"
msgstr "Se a opção estiver marcada, Relevanssi será usado nas buscas no painel do admin"
#: relevanssi.php:2139
msgid ""
"Enter a comma-separated list of category and tag IDs to restrict search to\n"
"\t\tthose categories or tags. You can also use <code>&lt;input type='hidden' name='cat'\n"
"\t\tvalue='list of cats and tags' /&gt;</code> in your search form. The input field will\n"
"\t\toverrun this setting."
msgstr "Insira uma lista separada por vírgulas de categorias e IDs de tags para restringir a busca apenas nelas. Você também pode usar <code>&lt;input type='hidden' name='cat' value='lista de categorias e tags' /&gt;</code> em seu formulário. O campo no formulário tem prioridade sobre esta opção no painel."
#: relevanssi.php:2144
msgid ""
"Enter a comma-separated list of category and tag IDs that are excluded from\n"
"\t\tsearch results. This only works here, you can't use the input field option (WordPress\n"
"\t\tdoesn't pass custom parameters there)."
msgstr "Insira uma lista separada por vírgulas de categorias e IDs de tags que serão excluídos dos resultados da busca. Essa opção só pode ser definida aqui, você não pode usar um campo adicional no formulário (WordPress não passa parâmetros personalizados lá)."
#: relevanssi.php:2151
msgid ""
"Enter a comma-separated list of post/page IDs that are excluded from search\n"
"\t\tresults. This only works here, you can't use the input field option (WordPress doesn't pass\n"
"\t\tcustom parameters there)."
msgstr "Insira uma lista separada por vírgulas de IDs de posts/páginas que serão excluídos dos resultados da busca. Essa opção só pode ser definida aqui, você não pode usar um campo adicional no formulário (WordPress não passa parâmetros personalizados lá)."
#: relevanssi.php:2155
msgid ""
"If checked, Relevanssi will also index and search the tags of your posts.\n"
"\t\tRemember to rebuild the index if you change this option!"
msgstr "Se esta opção estiver marcada, Relevanssi irá indexar e realizar buscas nas tags de seus posts. Lembre-se de reconstruir o índice se você mudar esta opção!"
#: relevanssi.php:2158
msgid ""
"Relevanssi will index and search ALL (all comments including track-\n"
"\t\t&amp; pingbacks and custom comment types), NONE (no comments) or NORMAL (manually posted\n"
"\t\tcomments on your blog).<br />Remember to rebuild the index if you change this option!"
msgstr "Relevanssi irá indexar e buscar em TODOS (comentários, trackbacks, pingbacks e tipos personalizados de comentários), NENHUM (nenhum comentário) ou NORMAL (comentários postados manualmente no blog).<br/> Lembre-se de reconstruir o índice se você mudar esta opção!"
#: relevanssi.php:2168
msgid ""
"If checked, Relevanssi will also index and search the categories of your\n"
"\t\tposts. Category titles will pass through 'single_cat_title' filter. Remember to rebuild the\n"
"\t\tindex if you change this option!"
msgstr "Se esta opção estiver marcada, Relevanssi irá indexar e realizar buscas nas categorias de seus posts. Lembre-se de reconstruir o índice se você mudar esta opção!"
#: relevanssi.php:2183
msgid ""
"If checked, Relevanssi will create excerpts that contain the search term\n"
"\t\thits. To make them work, make sure your search result template uses the_excerpt() to\n"
"\t\tdisplay post excerpts."
msgstr "Se esta opção estiver marcada, Relevanssi irá criar resumos que contém o(s) termo(s) buscado(s). Para que isso funcione, certifique-se de que seu template de resultado de busca utiliza <code>the_excerpt()</code> para exibir resumos de posts."
#: relevanssi.php:2203
msgid ""
"After installing the plugin, you need to build the index. This generally needs\n"
"\t\tto be done once, you don't have to re-index unless something goes wrong. Indexing is a heavy\n"
"\t\ttask and might take more time than your servers allow. If the indexing cannot be finished -\n"
"\t\tfor example you get a blank screen or something like that after indexing - you can continue\n"
"\t\tindexing from where you left by clicking 'Continue indexing'. Clicking 'Build the index'\n"
"\t\twill delete the old index, so you can't use that."
msgstr "Após a instalação do plugin, é preciso construir o índice. Isso normalmente precisa ser feito apenas uma vez. Não é necessário reconstruir o índice a não ser que algo de errado aconteça. A indexação é uma tarefa pesada e pode levar mais tempo do que seus servidores permitam. Se a indexação não puder ser concluída - por exemplo, você encontrar uma tela branca ou algo parecido após a indexação - você pode continuar o processo a partir de onde parou ao clicar em \"Continuar Indexação\". Ao clicar em \"Construir o Índice\" o índice atual será removido, portanto não clique nele para continuar uma indexação interrompida."
#: relevanssi.php:2209
msgid ""
"So, if you build the index and don't get the 'Indexing complete' in the end,\n"
"\t\tkeep on clicking the 'Continue indexing' button until you do. On my blogs, I was able to\n"
"\t\tindex ~400 pages on one go, but had to continue indexing twice to index ~950 pages."
msgstr "Portanto, se você construir o índice e não receber a mensagem \"Indexação Concluída\" no final, continue clicando em \"Continuar Indexação\" até que isso aconteça. Em meus blogs consegui indexar cerca de 400 páginas de uma só vez, mas precisei continuar o processo mais duas vezes para chegar a cerca de 950 páginas."
#: relevanssi.php:2228
msgid ""
"You can use any CSS styling here, style will be inserted with a\n"
"\t\t&lt;span&gt;"
msgstr "Você pode usar qualquer estilo CSS aqui, ele será inserido com a tag <code>&lt;span&gt;</code>"
#: relevanssi.php:2230
msgid ""
"Name a class here, search results will be wrapped in a &lt;span&gt;\n"
"\t\twith the class"
msgstr "Insira aqui o nome da classe e os resultados da busca serão encapsulados por uma tag <code>&lt;span&gt;</code> com esta classe"
# @ relevanssi
#: relevanssi.php:2237
msgid "All public post types"
msgstr "Todos os tipos de post públicos"
# @ relevanssi
#: relevanssi.php:2238
msgid ""
"This determines which post types are included in the index. Choosing\n"
"\t\t'everything' will include posts, pages and all custom post types. 'All public post types'\n"
"\t\tincludes all registered post types that don't have the 'exclude_from_search' set to true.\n"
"\t\tThis includes post, page, attachment, and possible custom types. 'All public types'\n"
"\t\trequires at least WP 2.9, otherwise it's the same as 'everything'."
msgstr "Isso determina quais tipos de posts serão indexados. Ao escolher \"Tudo\" serão incluídos todos os posts, páginas e posts personalizados. \"Todos os tipos de post públicos\" inclui todos os tipos de posts públicos que não possuam o atributo \"exclude_from_search\" definido como verdadeiro, o que inclui posts, páginas, anexos e possivelmente posts personalizados. A opção \"Todos os tipos de post públicos\" requer Wordpress 2.9 ou superior, caso contrário será o mesmo que \"Tudo\"."
# @ relevanssi
#: relevanssi.php:2244
msgid ""
"If you don't want to index all custom post types, list here the custom\n"
"\t\tpost types you want to see indexed. List comma-separated post type names (as used in the\n"
"\t\tdatabase). You can also use a hidden field in the search form to restrict the search to a\n"
"\t\tcertain post type: <code>&lt;input type='hidden' name='post_type' value='comma-separated\n"
"\t\tlist of post types' /&gt;</code>. If you choose 'All public post types' or 'Everything'\n"
"\t\tabove, this option has no effect."
msgstr "Se você não quiser indexar todos os tipos de post personalizados, liste aqui quais são os tipos que você quer indexar. Insira os nomes dos tipos de posts em uma lista separada por vírgula. Você pode também usar um campo hidden no formário de busca para restringir a busca em um determinado tipo de post: <code>&lt;input type='hidden' name='post_type' value='lista de tipos de posts' /&gt;</code>. Se na opção anterior você escolheu \"Todos os tipos de posts públicos\" ou \"Tudo\", essa opção não terá efeito."
#: relevanssi.php:2252
msgid ""
"A comma-separated list of custom field names to include in the\n"
"\t\tindex."
msgstr "Uma lista separada por vírgula de nomes de campos personalizados a serem incluídos no índice."
#: relevanssi.php:2256
msgid ""
"A comma-separated list of custom taxonomies to include in the\n"
"\t\tindex."
msgstr "Uma lista separada por vírgula de nomes de taxonomias personalizadas a serem incluídos no índice."
#: relevanssi.php:2260
msgid ""
"Check this to show more information on where the search hits were\n"
"\t\tmade. Requires custom snippets to work."
msgstr "Marque esta opção para exibir mais informações sobre onde os termos buscados foram encontrados. Para essa opção funcionar, é preciso habilitar os resumos personalizados."
#: relevanssi.php:2271
msgid ""
"Straight search matches just the term. Fuzzy search matches everything\n"
"\t\tthat begins or ends with the search term."
msgstr "Busca direta encontra apenas o termo buscado. Busca fuzzy irá encontrar tudo que começa ou termina com o termo buscado."
# @ relevanssi
#: relevanssi.php:2275
msgid ""
"If checked, Relevanssi will expand shortcodes in post content\n"
"\t\tbefore indexing. Otherwise shortcodes will be stripped. If you use shortcodes to\n"
"\t\tinclude dynamic content, Relevanssi will not keep the index updated, the index will\n"
"\t\treflect the status of the shortcode content at the moment of indexing."
msgstr "Se esta opção estiver marcada, Relevanssi irá converter os shortcodes no conteúdo do post antes de indexar. Caso contrário, os shortcodes serão removidos. Se você utiliza shortcodes para incluir conteúdo dinâmico, Relevanssi não manterá o índice atualizado. Ou seja, será utilizado o conteúdo gerado pelo shortcode no momento da indexação."
# @ relevanssi
#: relevanssi.php:2281
msgid ""
"If you want to uninstall the plugin, start by clicking the button\n"
"\t\tbelow to wipe clean the options and tables created by the plugin, then remove it from\n"
"\t\tthe plugins list."
msgstr "Se quiser desinstalar o plugin, comece clicando no botão abaixo para remover todas as opções e todas as tabelas criadas pelo plugin, e então remova-o da lista de plugins."
#: relevanssi.php:2172
msgid "Index and search your posts' authors:"
msgstr "Indexar e buscar os autores dos posts:"
#: relevanssi.php:2173
msgid ""
"If checked, Relevanssi will also index and search the authors of your\n"
"\t\tposts. Author display name will be indexed. Remember to rebuild the index if you change\n"
"\t\tthis option!"
msgstr "Se esta opção estiver marcada, Relevanssi irá indexar e realizar buscas nos autores de seus posts. Lembre-se de reconstruir o índice se você mudar esta opção!"
# @ relevanssi
#: relevanssi.php:2286
msgid "State of the Index"
msgstr "Estatísticas do Índice"
# @ relevanssi
#: relevanssi.php:2287
msgid "Highest post ID indexed"
msgstr "Último ID indexado"
#: relevanssi.php:2288
msgid "Documents in the index"
msgstr "Registros no índice"
# @ relevanssi
#: relevanssi.php:2289
msgid "Basic options"
msgstr "Opções Básicas"
# @ relevanssi
#: relevanssi.php:2291
msgid "Default operator for the search?"
msgstr "Operador padrão para a busca?"
# @ relevanssi
#: relevanssi.php:2292
msgid "AND - require all terms"
msgstr "E - necessita de todos os termos"
# @ relevanssi
#: relevanssi.php:2293
msgid "OR - any term present is enough"
msgstr "OU - qualquer termo presente é o bastante"
# @ relevanssi
#: relevanssi.php:2294
msgid "If you choose AND and the search finds no matches, it will automatically do an OR search."
msgstr "Se escolher E e a busca não encontrar resultados, uma nova busca do tipo OU será feita automaticamente."
# @ relevanssi
#: relevanssi.php:2296
msgid "Don't log queries from these users:"
msgstr "Não armazenar registros de buscas destes usuários:"
#: relevanssi.php:2297
msgid "Comma-separated list of user ids that will not be logged."
msgstr "Uma lista separada por vírgula de usuários que não terão suas buscas registradas."
# @ relevanssi
#: relevanssi.php:2299
msgid "Synonyms"
msgstr "Sinônimos"
# @ relevanssi
#: relevanssi.php:2300
msgid "Add synonyms here in 'key = value' format. When searching with the OR operator, any search of 'key' will be expanded to include 'value' as well. Using phrases is possible. The key-value pairs work in one direction only, but you can of course repeat the same pair reversed."
msgstr "Adicione sinônimos no formato \"chave = valor\". Quando for feita uma busca do tipo OU, qualquer busca por <strong>\"chave\"</strong> será expandida para incluir <strong>\"valor\"</strong> também. É possível utilizar frases. Os pares chave-valor funcionam apenas em uma direção, mas claro que você pode repetir o mesmo par em ordem inversa."
#: relevanssi.php:2177
msgid "Index and search post excerpts:"
msgstr "Indexar e buscar os resumos dos posts:"
#: relevanssi.php:2178
msgid ""
"If checked, Relevanssi will also index and search the excerpts of your\n"
"\t\tposts.Remember to rebuild the index if you change this option!"
msgstr "Se esta opção estiver marcada, Relevanssi irá indexar e realizar buscas nos resumos de seus posts. Lembre-se de reconstruir o índice se você mudar esta opção!"
# @ relevanssi
#: relevanssi.php:2263
#, php-format
msgid ""
"Use %body%, %title%, %tags% and %comments% to display the number of\n"
"\t\thits (in different parts of the post), %total% for total hits, %score% to display the document weight and %terms% to\n"
"\t\tshow how many hits each search term got. No double quotes (\") allowed!"
msgstr "Utilize %body%, %title%, %tags% e %comments% para exibir o número de hits, %total% para o total de hits, %score% para exibir a relevância e %terms% para exibir quantas vezes cada termo buscado foi encontrado. Aspas duplas (\") não são permitidas aqui!"
#~ msgid "Save"
#~ msgstr "Gravar"
#~ msgid ""
#~ "Use %body%, %title%, %tags%, %comments% and %score% to display the number "
#~ "of hits and the document weight."
#~ msgstr ""
#~ "Use %body%, %title%, %tags%, %comments% e %score% para exibir o número de "
#~ "hits e o peso do resultado."

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,148 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"Last-Translator: Mikko Saari <mikko@mikkosaari.fi>\n"
"Language-Team: \n"
"Language: fi\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.3\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src/index.js:151
msgid "not this"
msgstr "ei tätä"
#: src/index.js:174
msgid "use this"
msgstr "käytä tätä"
#: src/index.js:199
msgid "How Relevanssi sees this post"
msgstr "Kuinka Relevanssi näkee artikkelin"
#: src/index.js:203
msgid "Title:"
msgstr "Otsikko:"
#: src/index.js:210
msgid "Content:"
msgstr "Sisältö:"
#: src/index.js:217
msgid "Author:"
msgstr "Tekijä:"
#: src/index.js:224
msgid "Categories:"
msgstr "Aiheet:"
#: src/index.js:231
msgid "Tags:"
msgstr "Avainsanat:"
#: src/index.js:238
msgid "Other taxonomies:"
msgstr "Muut taksonomiat:"
#: src/index.js:245
msgid "Comments:"
msgstr "Kommentit:"
#: src/index.js:252
msgid "Custom fields:"
msgstr "Avainkentät:"
#: src/index.js:259
msgid "Excerpt:"
msgstr "Ote:"
#: src/index.js:266
msgid "Links to this post:"
msgstr "Sisäiset linkit:"
#: src/index.js:273
msgid "MySQL columns:"
msgstr "MySQL-sarakkeet:"
#: src/index.js:281
msgid "Reason this post is not indexed:"
msgstr "Miksi tätä artikkelia ei ole indeksoitu:"
#: src/index.js:290
msgid "Pinning"
msgstr "Artikkelin kiinnittäminen"
#: src/index.js:294
msgid "Pin this post for all searches it appears in."
msgstr "Kiinnitä tämä artikkeli kärkeen kaikissa hauissa, joissa se esiintyy."
#: src/index.js:304
msgid ""
"A comma-separated list of single word keywords or multi-word phrases. If any "
"of these keywords are present in the search query, this post will be moved "
"on top of the search results."
msgstr ""
"Pilkuilla erotettu lista yksittäisiä hakusanoja tai monisanaisia "
"hakulauseita. Jos joku näistä hakusanoista esiintyy käyttäjän haussa, tämä "
"artikkeli kiinnitetään hakutulosten huipulle."
#: src/index.js:314
msgid "Exclusion"
msgstr "Artikkelien poissulkeminen"
#: src/index.js:319
msgid "Exclude this post or page from the index."
msgstr "Poista tämä artikkeli indeksistä."
#: src/index.js:329
msgid ""
"A comma-separated list of single word keywords or multi-word phrases. If any "
"of these keywords are present in the search query, this post will be removed "
"from the search results."
msgstr ""
"Pilkuilla erotettu lista yksittäisiä hakusanoja tai monisanaisia "
"hakulauseita. Jos joku näistä hakusanoista esiintyy käyttäjän haussa, tämä "
"artikkeli poistetaan hakutuloksista."
#: src/index.js:341
msgid "Related posts"
msgstr "Aiheeseen liittyvät artikkelit"
#: src/index.js:346
msgid "Don't append the related posts to this page."
msgstr "Älä lisää samankaltaisia artikkeleita tälle sivulle."
#: src/index.js:356
msgid "Don't show this as a related post for any post."
msgstr "Älä näytä tätä samankaltaisena artikkelina millään sivulla."
#: src/index.js:366
msgid ""
"A comma-separated list of keywords to use for the Related Posts feature. "
"Anything entered here will used when searching for related posts. Using "
"phrases with quotes is allowed, but will restrict the related posts to posts "
"including that phrase."
msgstr ""
"Pilkulla erotettu lista avainsanoja samankaltaisten artikkelien etsimiseen. "
"Tähän merkittyjä hakusanoja käytetään samankaltaisten artikkelien "
"etsimiseen. Voit käyttää fraasihakua lainausmerkeillä, mutta se rajoittaa "
"samankaltaiset artikkelit niihin, joissa fraasi esiintyy."
#: src/index.js:376
msgid ""
"A comma-separated list of post IDs to use as related posts for this post"
msgstr ""
"Pilkuilla erotettu lista tämän artikkelin liittyvinä artikkeleina "
"käytettävien artikkelien ID-numeroista"
#: src/index.js:383
msgid "Related posts for this post:"
msgstr "Samankaltaiset artikkelit:"
#: src/index.js:386
msgid "Excluded posts for this post:"
msgstr "Älä käytä samankaltaisina artikkeleina tälle artikkelille:"

View File

@@ -0,0 +1,154 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"X-Generator: babel-plugin-makepot\n"
#: src/index.js:152
msgid "not this"
msgstr ""
#: src/index.js:175
msgid "use this"
msgstr ""
#: src/index.js:224
msgid "How Relevanssi sees this post"
msgstr ""
#: src/index.js:228
msgid "Title:"
msgstr ""
#: src/index.js:235
msgid "Content:"
msgstr ""
#: src/index.js:242
msgid "Author:"
msgstr ""
#: src/index.js:249
msgid "Categories:"
msgstr ""
#: src/index.js:256
msgid "Tags:"
msgstr ""
#: src/index.js:263
msgid "Other taxonomies:"
msgstr ""
#: src/index.js:270
msgid "Comments:"
msgstr ""
#: src/index.js:277
msgid "Custom fields:"
msgstr ""
#: src/index.js:284
msgid "Excerpt:"
msgstr ""
#: src/index.js:291
msgid "Links to this post:"
msgstr ""
#: src/index.js:298
msgid "MySQL columns:"
msgstr ""
#: src/index.js:306
msgid "Reason this post is not indexed:"
msgstr ""
#: src/index.js:315
msgid "Pinning"
msgstr ""
#: src/index.js:319
msgid "Pin this post for all searches it appears in."
msgstr ""
#: src/index.js:338
msgid ""
"If any of these keywords are present in the search query, this post will be "
"moved on top of the search results."
msgstr ""
#: src/index.js:343
msgid ""
"You can add weights to pinned keywords like this: 'keyword (100)'. The post "
"with the highest weight will be sorted first if there are multiple posts "
"pinned to the same keyword."
msgstr ""
#: src/index.js:349
msgid "Exclusion"
msgstr ""
#: src/index.js:354
msgid "Exclude this post or page from the index."
msgstr ""
#: src/index.js:364
msgid "Ignore post content in the indexing."
msgstr ""
#: src/index.js:374
msgid "A comma-separated list of single word keywords or multi-word phrases."
msgstr ""
#: src/index.js:383
msgid ""
"If any of these keywords are present in the search query, this post will be "
"removed from the search results."
msgstr ""
#: src/index.js:391
msgid "Related posts"
msgstr ""
#: src/index.js:396
msgid "Don't append the related posts to this page."
msgstr ""
#: src/index.js:406
msgid "Don't show this as a related post for any post."
msgstr ""
#: src/index.js:416
msgid "A comma-separated list of keywords to use for the Related Posts feature."
msgstr ""
#: src/index.js:425
msgid ""
"Anything entered here will used when searching for related posts. Using "
"phrases with quotes is allowed, but will restrict the related posts to "
"posts including that phrase."
msgstr ""
#: src/index.js:431
msgid "A comma-separated list of post IDs to use as related posts for this post"
msgstr ""
#: src/index.js:438
msgid "Related posts for this post:"
msgstr ""
#: src/index.js:441
msgid "Excluded posts for this post:"
msgstr ""
#: src/index.js:446
msgid "Insights"
msgstr ""
#: src/index.js:448
msgid "The most common search terms used to find this post:"
msgstr ""
#: src/index.js:455
msgid "Low-ranking search terms used to find this post:"
msgstr ""

View File

@@ -0,0 +1 @@
{"translation-revision-date":"2023-04-23 03:33:04+0000","generator":"GlotPress\/4.0.0-alpha.3","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"sv_SE"},"Insights":["Inblickar"]}},"comment":{"reference":"index.js"}}

View File

@@ -0,0 +1,470 @@
<?php
/**
* /lib/admin-ajax.php
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_action( 'wp_ajax_relevanssi_truncate_index', 'relevanssi_truncate_index_ajax_wrapper' );
add_action( 'wp_ajax_relevanssi_index_posts', 'relevanssi_index_posts_ajax_wrapper' );
add_action( 'wp_ajax_relevanssi_count_posts', 'relevanssi_count_posts_ajax_wrapper' );
add_action( 'wp_ajax_relevanssi_count_missing_posts', 'relevanssi_count_missing_posts_ajax_wrapper' );
add_action( 'wp_ajax_relevanssi_list_categories', 'relevanssi_list_categories' );
add_action( 'wp_ajax_relevanssi_admin_search', 'relevanssi_admin_search' );
add_action( 'wp_ajax_relevanssi_update_counts', 'relevanssi_update_counts' );
add_action( 'wp_ajax_nopriv_relevanssi_update_counts', 'relevanssi_update_counts' );
add_action( 'wp_ajax_relevanssi_list_custom_fields', 'relevanssi_list_custom_fields' );
/**
* Checks if current user can access Relevanssi options.
*
* If the current user doesn't have sufficient access to Relevanssi options,
* the function will die. If the user has access, nothing happens.
*
* @return void
*/
function relevanssi_current_user_can_access_options() {
/**
* Filters the capability required to access Relevanssi options.
*
* @param string The capability required. Default 'manage_options'.
*/
if ( ! current_user_can( apply_filters( 'relevanssi_options_capability', 'manage_options' ) ) ) {
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'relevanssi' ) );
}
}
/**
* Truncates the Relevanssi index.
*
* Wipes the index clean using relevanssi_truncate_index().
*/
function relevanssi_truncate_index_ajax_wrapper() {
check_ajax_referer( 'relevanssi_indexing_nonce', 'security' );
relevanssi_current_user_can_access_options();
$response = relevanssi_truncate_index();
echo wp_json_encode( $response );
wp_die();
}
/**
* Indexes posts in AJAX context.
*
* AJAX wrapper for indexing posts. Parses the arguments, uses the
* relevanssi_build_index() to do the hard work, then creates the AJAX response.
*/
function relevanssi_index_posts_ajax_wrapper() {
check_ajax_referer( 'relevanssi_indexing_nonce', 'security' );
relevanssi_current_user_can_access_options();
$completed = absint( $_POST['completed'] );
$total = absint( $_POST['total'] );
$offset = absint( $_POST['offset'] );
$limit = absint( $_POST['limit'] );
$extend = strval( $_POST['extend'] );
if ( 'true' === $extend ) {
$extend = true;
}
if ( $limit < 1 ) {
$limit = 1;
}
$response = array();
$is_ajax = true;
$verbose = false;
if ( $extend ) {
$offset = true;
}
$indexing_response = relevanssi_build_index( $offset, $verbose, $limit, $is_ajax );
if ( $indexing_response['indexing_complete'] ) {
$response['completed'] = 'done';
$response['percentage'] = 100;
$completed += $indexing_response['indexed'];
$response['total_posts'] = $completed;
$processed = $total;
} else {
$completed += $indexing_response['indexed'];
$response['completed'] = $completed;
if ( true === $offset ) {
$processed = $completed;
} else {
$offset = $offset + $limit;
$processed = $offset;
}
if ( $total > 0 ) {
$response['percentage'] = $processed / $total * 100;
} else {
$response['percentage'] = 0;
}
}
$response['feedback'] = sprintf(
// translators: Number of posts indexed on this go, total number of posts indexed so far, number of posts processed on this go, total number of posts to process.
_n(
'Indexed %1$d post (total %2$d), processed %3$d / %4$d.',
'Indexed %1$d posts (total %2$d), processed %3$d / %4$d.',
$indexing_response['indexed'],
'relevanssi'
),
$indexing_response['indexed'],
$completed,
$processed,
$total
) . "\n";
$response['offset'] = $offset;
echo wp_json_encode( $response );
wp_die();
}
/**
* Counts the posts to index.
*
* AJAX wrapper for relevanssi_count_total_posts().
*/
function relevanssi_count_posts_ajax_wrapper() {
relevanssi_current_user_can_access_options();
$count = relevanssi_count_total_posts();
echo wp_json_encode( $count );
wp_die();
}
/**
* Counts the posts missing from the index.
*
* AJAX wrapper for relevanssi_count_missing_posts().
*/
function relevanssi_count_missing_posts_ajax_wrapper() {
relevanssi_current_user_can_access_options();
$count = relevanssi_count_missing_posts();
echo wp_json_encode( $count );
wp_die();
}
/**
* Lists categories.
*
* AJAX wrapper for get_categories().
*/
function relevanssi_list_categories() {
relevanssi_current_user_can_access_options();
$categories = get_categories(
array(
'taxonomy' => 'category',
'hide_empty' => false,
)
);
echo wp_json_encode( $categories );
wp_die();
}
/**
* Performs an admin search.
*
* Performs an admin dashboard search.
*
* @since 2.2.0
*/
function relevanssi_admin_search() {
check_ajax_referer( 'relevanssi_admin_search_nonce', 'security' );
/**
* Filters the capability required to access Relevanssi admin search page.
*
* @param string The capability required. Default 'edit_posts'.
*/
if ( ! current_user_can( apply_filters( 'relevanssi_admin_search_capability', 'edit_posts' ) ) ) {
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'relevanssi' ) );
}
$args = array();
if ( isset( $_POST['args'] ) ) {
parse_str( $_POST['args'], $args );
}
if ( isset( $_POST['posts_per_page'] ) ) {
$posts_per_page = intval( $_POST['posts_per_page'] );
if ( $posts_per_page > 0 ) {
$args['posts_per_page'] = $posts_per_page;
}
}
if ( isset( $_POST['post_types'] ) ) {
$post_type = $_POST['post_types'];
$args['post_types'] = $post_type;
}
if ( isset( $_POST['offset'] ) ) {
$offset = intval( $_POST['offset'] );
if ( $offset > 0 ) {
$args['offset'] = $offset;
}
}
if ( isset( $_POST['s'] ) ) {
$args['s'] = $_POST['s'];
}
$query = new WP_Query();
$query->parse_query( $args );
$query->set( 'relevanssi_admin_search', true );
$query = apply_filters( 'relevanssi_modify_wp_query', $query );
relevanssi_do_query( $query );
$results = relevanssi_admin_search_debugging_info( $query );
// Take the posts array and create a string out of it.
$offset = 0;
if ( isset( $query->query_vars['offset'] ) ) {
$offset = $query->query_vars['offset'];
}
$results .= relevanssi_admin_search_format_posts( $query->posts, $query->found_posts, $offset, $args['s'] );
echo wp_json_encode( $results );
wp_die();
}
/**
* Formats the posts for admin search.
*
* Results are presented as an ordered list of posts. The format is very basic, and
* can be modified with the 'relevanssi_admin_search_element' filter hook.
*
* @param array $posts The posts array.
* @param int $total The number of posts found in total.
* @param int $offset Offset value.
* @param string $query The search query.
*
* @return string The formatted posts.
*
* @since 2.2.0
*/
function relevanssi_admin_search_format_posts( $posts, $total, $offset, $query ) {
$result = '<h3>' . __( 'Results', 'relevanssi' ) . '</h3>';
$start = $offset + 1;
$end = $offset + count( $posts );
// Translators: %1$d is the total number of posts found, %2$d is the current search result count, %3$d is the offset.
$result .= '<p>' . sprintf( __( 'Found a total of %1$d posts, showing posts %2$d%3$s.', 'relevanssi' ), $total, $start, '<span id="offset">' . $end . '</span>' ) . '</p>';
if ( $offset > 0 ) {
$result .= sprintf( '<button type="button" id="prev_page">%s</button>', __( 'Previous page', 'relevanssi' ) );
}
if ( count( $posts ) + $offset < $total ) {
$result .= sprintf( '<button type="button" id="next_page">%s</button>', __( 'Next page', 'relevanssi' ) );
}
$result .= '<ol start="' . $start . '">';
$score_label = __( 'Score:', 'relevanssi' );
foreach ( $posts as $post ) {
$blog_name = '';
if ( isset( $post->blog_id ) && function_exists( 'switch_to_blog' ) ) {
switch_to_blog( $post->blog_id );
$blog_name = get_bloginfo( 'name' ) . ': ';
}
$permalink = get_permalink( $post->ID );
$edit_url = get_edit_post_link( $post->ID );
$post_type = $post->post_type;
if ( isset( $post->relevanssi_link ) ) {
$permalink = $post->relevanssi_link;
}
if ( 'user' === $post->post_type ) {
$edit_url = get_edit_user_link( $post->ID );
}
if ( empty( $edit_url ) ) {
if ( isset( $post->term_id ) ) {
$edit_url = get_edit_term_link( $post->term_id, $post->post_type );
}
}
$title = sprintf( '<a href="%1$s">%2$s %3$s</a>', $permalink, $post->post_title, $post_type );
$edit_link = '';
if ( current_user_can( 'edit_post', $post->ID ) ) {
$edit_link = sprintf( '(<a href="%1$s">%2$s %3$s</a>)', $edit_url, __( 'Edit', 'relevanssi' ), $post_type );
}
$pinning_buttons = '';
$pinned = '';
if ( function_exists( 'relevanssi_admin_search_pinning' ) ) {
// Relevanssi Premium adds pinning features to the admin search.
list( $pinning_buttons, $pinned ) = relevanssi_admin_search_pinning( $post, $query );
}
$post_element = <<<EOH
<li>$blog_name <strong>$title</strong> $edit_link $pinning_buttons <br />
$post->post_excerpt<br />
$score_label $post->relevance_score $pinned</li>
EOH;
/**
* Filters the admin search results element.
*
* The post element is a <li> element. Feel free to edit the element any
* way you want to.
*
* @param string $post_element The post element.
* @param object $post The post object.
*/
$result .= apply_filters( 'relevanssi_admin_search_element', $post_element, $post );
if ( isset( $post->blog_id ) && function_exists( 'restore_current_blog' ) ) {
restore_current_blog();
}
}
$result .= '</ol>';
return $result;
}
/**
* Shows debugging information about the search.
*
* Formats the WP_Query parameters, looks at some filter hooks and presents the
* information in an easy-to-read format.
*
* @param WP_Query $query The WP_Query object.
*
* @return string The formatted debugging information.
*
* @since 2.2.0
*/
function relevanssi_admin_search_debugging_info( $query ) {
$result = '<div id="debugging">';
$result .= '<h3>' . __( 'Query variables', 'relevanssi' ) . '</h3>';
$result .= '<ul style="list-style: disc; margin-left: 1.5em">';
foreach ( $query->query_vars as $key => $value ) {
if ( 'tax_query' === $key ) {
$result .= '<li>tax_query:<ul style="list-style: disc; margin-left: 1.5em">';
$result .= implode(
'',
array_map(
function ( $row ) {
$result = '';
if ( is_array( $row ) ) {
foreach ( $row as $row_key => $row_value ) {
$result .= "<li>$row_key: $row_value</li>";
}
}
return $result;
},
$value
)
);
$result .= '</ul></li>';
} else {
if ( is_array( $value ) ) {
$value = relevanssi_flatten_array( $value );
}
if ( empty( $value ) ) {
continue;
}
$result .= "<li>$key: $value</li>";
}
}
if ( ! empty( $query->tax_query ) ) {
$result .= '<li>tax_query:<ul style="list-style: disc; margin-left: 1.5em">';
foreach ( $query->tax_query as $tax_query ) {
if ( ! is_array( $tax_query ) ) {
continue;
}
foreach ( $tax_query as $key => $value ) {
if ( is_array( $value ) ) {
$value = relevanssi_flatten_array( $value );
}
$result .= "<li>$key: $value</li>";
}
}
$result .= '</ul></li>';
}
$result .= '</ul>';
global $wp_filter;
$filters = array(
'relevanssi_search_ok',
'relevanssi_modify_wp_query',
'relevanssi_search_filters',
'relevanssi_where',
'relevanssi_join',
'relevanssi_fuzzy_query',
'relevanssi_exact_match_bonus',
'relevanssi_query_filter',
'relevanssi_match',
'relevanssi_post_ok',
'relevanssi_search_again',
'relevanssi_results',
'relevanssi_orderby',
'relevanssi_order',
'relevanssi_default_tax_query_relation',
'relevanssi_hits_filter',
);
$result .= '<h3>' . __( 'Filters', 'relevanssi' ) . '</h3>';
$result .= '<button type="button" id="show_filters">' . __( 'show', 'relevanssi' ) . '</button>';
$result .= '<button type="button" id="hide_filters" style="display: none">' . __( 'hide', 'relevanssi' ) . '</button>';
$result .= '<div id="relevanssi_filter_list">';
foreach ( $filters as $filter ) {
if ( isset( $wp_filter[ $filter ] ) ) {
$result .= '<h4>' . $filter . '</h4>';
$result .= '<ul style="list-style: disc; margin-left: 1.5em">';
foreach ( $wp_filter[ $filter ] as $priority => $functions ) {
foreach ( $functions as $function ) {
if ( $function['function'] instanceof Closure ) {
$function['function'] = 'Anonymous function';
}
$result .= "<li>$priority: " . $function['function'] . '</li>';
}
}
$result .= '</ul>';
}
}
$result .= '</div>';
$result .= '</div>';
return $result;
}
/**
* Updates count options.
*
* Updates 'relevanssi_doc_count', 'relevanssi_terms_count' (and in Premium
* 'relevanssi_user_count' and 'relevanssi_taxterm_count'). These are slightly
* expensive queries, so they are updated when necessary as a non-blocking AJAX
* action and stored in options for quick retrieval.
*
* @global object $wpdb The WordPress database interface.
* @global array $relevanssi_variables The Relevanssi global variable, used for table names.
*/
function relevanssi_update_counts() {
global $wpdb, $relevanssi_variables;
relevanssi_update_doc_count();
$terms_count = $wpdb->get_var( 'SELECT COUNT(*) FROM ' . $relevanssi_variables['relevanssi_table'] ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
update_option( 'relevanssi_terms_count', is_null( $terms_count ) ? 0 : $terms_count, false );
if ( RELEVANSSI_PREMIUM ) {
$user_count = $wpdb->get_var( 'SELECT COUNT(DISTINCT item) FROM ' . $relevanssi_variables['relevanssi_table'] . " WHERE type = 'user'" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
$taxterm_count = $wpdb->get_var( 'SELECT COUNT(DISTINCT item) FROM ' . $relevanssi_variables['relevanssi_table'] . " WHERE (type != 'post' AND type != 'attachment' AND type != 'user')" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
update_option( 'relevanssi_user_count', is_null( $user_count ) ? 0 : $user_count, false );
update_option( 'relevanssi_taxterm_count', is_null( $taxterm_count ) ? 0 : $taxterm_count, false );
}
}
/**
* Returns a comma-separated list of indexed custom field names.
*
* @uses relevanssi_list_all_indexed_custom_fields()
*/
function relevanssi_list_custom_fields() {
$response = relevanssi_list_all_indexed_custom_fields();
echo wp_json_encode( $response );
wp_die();
}

View File

@@ -0,0 +1,540 @@
/* Confirmation for copying options between blogs */
jQuery(document).ready(function ($) {
$("#copy_config").on("submit", function () {
var c = confirm(relevanssi.confirm)
return c //you can just return c because it will be true or false
})
$("#removeallstopwords").on("click", function () {
var c = confirm(relevanssi.confirm_stopwords)
return c
})
$("#delete_query").on("click", function () {
var c = confirm(relevanssi.confirm_delete_query)
return c
})
$("#list_custom_fields").on("click", function () {
var results = $("#relevanssi_custom_field_list")
var data = {
action: "relevanssi_list_custom_fields",
}
jQuery.post(ajaxurl, data, function (response) {
console.log(response)
results.html('<p>' + JSON.parse(response) + '</p>')
})
})
})
jQuery(document).ready(function ($) {
$(".color-field").wpColorPicker()
var txtcol_control = $("#tr_relevanssi_txt_col")
var bgcol_control = $("#tr_relevanssi_bg_col")
var class_control = $("#tr_relevanssi_class")
var css_control = $("#tr_relevanssi_css")
$("#relevanssi_highlight").on("change", function () {
txtcol_control.addClass("screen-reader-text")
bgcol_control.addClass("screen-reader-text")
class_control.addClass("screen-reader-text")
css_control.addClass("screen-reader-text")
if (this.value == "col") txtcol_control.toggleClass("screen-reader-text")
if (this.value == "bgcol") bgcol_control.toggleClass("screen-reader-text")
if (this.value == "class") class_control.toggleClass("screen-reader-text")
if (this.value == "css") css_control.toggleClass("screen-reader-text")
})
$("#relevanssi_hilite_title").on("click", function () {
$("#title_description").toggleClass("screen-reader-text", !this.checked)
})
var or_fallback = $("#orfallback")
$("#relevanssi_implicit_operator").on("change", function () {
or_fallback.toggleClass("screen-reader-text")
})
var index_subscribers = $("#index_subscribers")
var user_extra_fields = $("#user_extra_fields")
$("#relevanssi_index_users").on("click", function () {
$("#user_profile_notice").toggleClass("screen-reader-text", !this.checked)
index_subscribers.toggleClass("screen-reader-text", !this.checked)
user_extra_fields.toggleClass("screen-reader-text", !this.checked)
})
var taxonomies = $("#taxonomies")
$("#relevanssi_index_taxonomies").on("click", function () {
taxonomies.toggleClass("screen-reader-text", !this.checked)
})
var post_type_archives = $("#posttypearchives")
$("#relevanssi_index_post_type_archives").on("click", function () {
post_type_archives.toggleClass("screen-reader-text", !this.checked)
})
var fields_content = $("#index_field_input")
var fields_select = $("#relevanssi_index_fields_select")
fields_select.on("change", function () {
if (this.value == "some") fields_content.show()
if (this.value != "some") fields_content.hide()
})
var index_images = $("#row_index_image_files")
var index_attachments = $("#relevanssi_index_type_attachment")
index_attachments.on("click", function () {
if (this.checked) index_images.show()
if (!this.checked) index_images.hide()
})
$("#show_advanced_indexing").on("click", function (e) {
$("#advanced_indexing").toggleClass("screen-reader-text")
$("#hide_advanced_indexing").show()
$("#show_advanced_indexing").hide()
})
$("#hide_advanced_indexing").on("click", function (e) {
$("#advanced_indexing").toggleClass("screen-reader-text")
$("#show_advanced_indexing").show()
$("#hide_advanced_indexing").hide()
})
$("#indexing_tab :input").on("change", function (e) {
$("#build_index").attr("disabled", "disabled")
var relevanssi_note = $("#relevanssi-note")
relevanssi_note.show()
relevanssi_note.html('<p class="description important">' + relevanssi.options_changed + '</p>')
})
$("#relevanssi_default_orderby").on("change", function (e) {
if (this.value == "post_date") {
$("#relevanssi_throttle").prop("checked", false)
}
$("#throttle_disabled").toggleClass("screen-reader-text")
$("#throttle_enabled").toggleClass("screen-reader-text")
})
$("#relevanssi_show_pdf_errors").on("click", function (e) {
var error_box = $("#relevanssi_pdf_errors")
error_box.toggle()
var data = {
action: "relevanssi_get_pdf_errors",
}
jQuery.post(ajaxurl, data, function (response) {
error_box.val(JSON.parse(response))
})
})
$("#relevanssi_excerpts").on("click", function () {
$("#relevanssi_breakdown").toggleClass("relevanssi_disabled", !this.checked)
$("#relevanssi_highlighting").toggleClass(
"relevanssi_disabled",
!this.checked
)
$("#tr_excerpt_custom_fields").toggleClass(
"relevanssi_disabled",
!this.checked
)
$("#tr_excerpt_allowable_tags").toggleClass(
"relevanssi_disabled",
!this.checked
)
$("#tr_excerpt_length").toggleClass("relevanssi_disabled", !this.checked)
$("#tr_max_excerpts").toggleClass("relevanssi_disabled", !this.checked)
$("#relevanssi_excerpt_length").attr("disabled", !this.checked)
$("#relevanssi_excerpt_type").attr("disabled", !this.checked)
$("#relevanssi_max_excerpts").attr("disabled", !this.checked)
$("#relevanssi_excerpt_allowable_tags").attr("disabled", !this.checked)
$("#relevanssi_excerpt_custom_fields").attr("disabled", !this.checked)
$("#relevanssi_highlight").attr("disabled", !this.checked)
$("#relevanssi_txt_col").attr("disabled", !this.checked)
$("#relevanssi_bg_col").attr("disabled", !this.checked)
$("#relevanssi_css").attr("disabled", !this.checked)
$("#relevanssi_class").attr("disabled", !this.checked)
$("#relevanssi_hilite_title").attr("disabled", !this.checked)
$("#relevanssi_highlight_docs").attr("disabled", !this.checked)
$("#relevanssi_highlight_comments").attr("disabled", !this.checked)
$("#relevanssi_show_matches").attr("disabled", !this.checked)
$("#relevanssi_show_matches_text").attr("disabled", !this.checked)
$("#relevanssi_expand_highlights").attr("disabled", !this.checked)
})
$("#relevanssi_excerpt_custom_fields").on("change", function () {
$("#relevanssi_excerpt_specific_fields").attr("disabled", !this.checked)
})
$("#relevanssi_searchblogs_all").on("click", function () {
$("#relevanssi_searchblogs").attr("disabled", this.checked)
})
var min_word_length = $("#relevanssi_min_word_length")
min_word_length.on("change", function(e) {
if ( min_word_length.val() < 1 ) {
min_word_length.val(1)
}
if ( min_word_length.val() > 9 ) {
min_word_length.val(9)
}
})
})
var time = 0
var intervalID = 0
function relevanssiUpdateClock() {
time++
var time_formatted = rlv_format_time(Math.round(time))
document.getElementById("relevanssi_elapsed").innerHTML = time_formatted
}
jQuery(document).ready(function ($) {
$("#continue_indexing").on("click", function () {
$("#relevanssi-progress").show()
$("#results").show()
$("#relevanssi-timer").show()
$("#stateoftheindex").html(relevanssi.reload_state)
$("#indexing_button_instructions").hide()
var results = document.getElementById("results")
results.value = ""
intervalID = window.setInterval(relevanssiUpdateClock, 1000)
var data = {
action: "relevanssi_count_missing_posts",
}
console.log("Counting posts.")
results.value += relevanssi.counting_posts + " "
jQuery.post(ajaxurl, data, function (response) {
count_response = JSON.parse(response)
console.log("Counted " + count_response + " posts.")
results.value += count_response + " " + relevanssi.posts_found + "\n"
if (count_response > 0) {
var args = {
completed: 0,
total: count_response,
offset: 0,
total_seconds: 0,
limit: relevanssi_params.indexing_limit,
adjust: relevanssi_params.indexing_adjust,
extend: true,
security: nonce.indexing_nonce,
}
process_indexing_step(args)
} else {
clearInterval(intervalID)
}
})
})
})
function process_indexing_step(args) {
// console.log(args.completed + " / " + args.total);
var t0 = performance.now()
jQuery.ajax({
type: "POST",
url: ajaxurl,
data: {
action: "relevanssi_index_posts",
completed: args.completed,
total: args.total,
offset: args.offset,
limit: args.limit,
adjust: args.adjust,
extend: args.extend,
security: args.security,
},
dataType: "json",
success: function (response) {
console.log(response)
if (response.completed == "done") {
//console.log("response " + parseInt(response.total_posts));
var results_textarea = document.getElementById("results")
results_textarea.value += response.feedback
document.getElementById("relevanssi_estimated").innerHTML =
relevanssi.notimeremaining
var hidden_posts = args.total - parseInt(response.total_posts)
results_textarea.value +=
relevanssi.indexing_complete +
" " +
hidden_posts +
" " +
relevanssi.excluded_posts
results_textarea.scrollTop = results_textarea.scrollHeight
jQuery(".rpi-progress div").animate(
{
width: response.percentage + "%",
},
50,
function () {
// Animation complete.
}
)
clearInterval(intervalID)
} else {
var t1 = performance.now()
var time_seconds = (t1 - t0) / 1000
time_seconds = Math.round(time_seconds * 100) / 100
args.total_seconds += time_seconds
var estimated_time = rlv_format_approximate_time(
Math.round(
(args.total_seconds / response.percentage) * 100 -
args.total_seconds
)
)
document.getElementById(
"relevanssi_estimated"
).innerHTML = estimated_time
if (args.adjust) {
if (time_seconds < 2) {
args.limit = args.limit * 2
// current limit can be indexed in less than two seconds; double the limit
} else if (time_seconds < 5) {
args.limit += 5
// current limit can be indexed in less than five seconds; up the limit
} else if (time_seconds > 20) {
args.limit = Math.round(args.limit / 2)
if (args.limit < 1) args.limit = 1
// current limit takes more than twenty seconds; halve the limit
} else if (time_seconds > 10) {
args.limit -= 5
if (args.limit < 1) args.limit = 1
// current limit takes more than ten seconds; reduce the limit
}
}
var results_textarea = document.getElementById("results")
results_textarea.value += response.feedback
results_textarea.scrollTop = results_textarea.scrollHeight
var percentage_rounded = Math.round(response.percentage)
jQuery(".rpi-progress div").animate(
{
width: percentage_rounded + "%",
},
50,
function () {
// Animation complete.
}
)
//console.log("Next step.");
var new_args = {
completed: parseInt(response.completed),
total: args.total,
offset: response.offset,
total_seconds: args.total_seconds,
limit: args.limit,
adjust: args.adjust,
extend: args.extend,
security: args.security,
}
process_indexing_step(new_args)
}
},
})
}
function rlv_format_time(total_seconds) {
var hours = Math.floor(total_seconds / 3600)
var minutes = Math.floor((total_seconds - hours * 3600) / 60)
var seconds = total_seconds - hours * 3600 - minutes * 60
if (minutes < 10) minutes = "0" + minutes
if (seconds < 10) seconds = "0" + seconds
return hours + ":" + minutes + ":" + seconds
}
function rlv_format_approximate_time(total_seconds) {
var hours = Math.floor(total_seconds / 3600)
var minutes = Math.floor(total_seconds / 60)
var seconds = total_seconds - hours * 3600 - minutes * 60
var time = ""
if (minutes > 99) {
hour_word = relevanssi.hours
if (hours == 1) hour_word = relevanssi.hour
time = relevanssi.about + " " + hours + " " + hour_word
}
if (minutes > 79 && minutes < 100) time = relevanssi.ninety_min
if (minutes > 49 && minutes < 80) time = relevanssi.sixty_min
if (minutes < 50) {
if (seconds > 30) minutes += 1
minute_word = relevanssi.minutes
if (minutes == 1) minute_word = relevanssi.minute
time = relevanssi.about + " " + minutes + " " + minute_word
}
if (minutes < 1) time = relevanssi.underminute
return time
}
jQuery(document).ready(function ($) {
$("#search").on("click", function (e) {
var results = document.getElementById("results")
results.innerHTML = "Searching..."
e.preventDefault()
jQuery.ajax({
type: "POST",
url: ajaxurl,
data: {
action: "relevanssi_admin_search",
args: document.getElementById("args").value,
posts_per_page: document.getElementById("posts_per_page").value,
post_types: document.getElementById("post_types").value,
s: document.getElementById("s").value,
security: nonce.searching_nonce,
},
dataType: "json",
success: function (response) {
results.innerHTML = response
},
})
})
// Show the filters on the "Admin search" page.
$(document).on("click", "#show_filters", function (e) {
$("#relevanssi_filter_list").toggle()
$("#show_filters").toggle()
$("#hide_filters").toggle()
})
// Hide the filters on the "Admin search" page.
$(document).on("click", "#hide_filters", function (e) {
$("#relevanssi_filter_list").toggle()
$("#show_filters").toggle()
$("#hide_filters").toggle()
})
$(document).on("click", "#next_page", function (e) {
e.preventDefault()
var results = document.getElementById("results")
var offset = parseInt(document.getElementById("offset").innerHTML)
var posts = parseInt(document.getElementById("posts_per_page").value)
results.innerHTML = "Searching..."
jQuery.ajax({
type: "POST",
url: ajaxurl,
data: {
action: "relevanssi_admin_search",
args: document.getElementById("args").value,
posts_per_page: posts,
s: document.getElementById("s").value,
offset: offset,
security: nonce.searching_nonce,
},
dataType: "json",
success: function (response) {
results.innerHTML = response
},
})
})
$(document).on("click", "#prev_page", function (e) {
e.preventDefault()
var results = document.getElementById("results")
var offset = parseInt(document.getElementById("offset").innerHTML)
var posts = parseInt(document.getElementById("posts_per_page").value)
offset = offset - posts - posts
if (offset < 0) offset = 0
results.innerHTML = "Searching..."
jQuery.ajax({
type: "POST",
url: ajaxurl,
data: {
action: "relevanssi_admin_search",
args: document.getElementById("args").value,
posts_per_page: document.getElementById("posts_per_page").value,
s: document.getElementById("s").value,
offset: offset,
security: nonce.searching_nonce,
},
dataType: "json",
success: function (response) {
results.innerHTML = response
},
})
})
$(document).on("click", ".pin", function (e) {
e.preventDefault()
var keyword = e.target.dataset.keyword
var post_id = e.target.dataset.postid
jQuery.ajax({
type: "POST",
url: ajaxurl,
data: {
action: "relevanssi_pin_post",
keyword,
post_id,
security: nonce.searching_nonce,
},
dataType: "json",
success: function (response) {
var results = document.getElementById("results")
results.innerHTML = "Searching..."
e.preventDefault()
jQuery.ajax({
type: "POST",
url: ajaxurl,
data: {
action: "relevanssi_admin_search",
args: document.getElementById("args").value,
posts_per_page: document.getElementById("posts_per_page").value,
s: document.getElementById("s").value,
security: nonce.searching_nonce,
},
dataType: "json",
success: function (response) {
results.innerHTML = response
},
})
},
})
})
$(document).on("click", ".unpin", function (e) {
e.preventDefault()
var keyword = e.target.dataset.keyword
var post_id = e.target.dataset.postid
jQuery.ajax({
type: "POST",
url: ajaxurl,
data: {
action: "relevanssi_unpin_post",
keyword,
post_id,
security: nonce.searching_nonce,
},
dataType: "json",
success: function (response) {
var results = document.getElementById("results")
results.innerHTML = "Searching..."
e.preventDefault()
jQuery.ajax({
type: "POST",
url: ajaxurl,
data: {
action: "relevanssi_admin_search",
args: document.getElementById("args").value,
posts_per_page: document.getElementById("posts_per_page").value,
s: document.getElementById("s").value,
security: nonce.searching_nonce,
},
dataType: "json",
success: function (response) {
results.innerHTML = response
},
})
},
})
})
})

View File

@@ -0,0 +1,53 @@
jQuery(document).ready(function ($) {
$("#build_index").click(function () {
$("#relevanssi-progress").show()
$("#results").show()
$("#relevanssi-timer").show()
$("#relevanssi-indexing-instructions").show()
$("#stateoftheindex").html(relevanssi.reload_state)
$("#indexing_button_instructions").hide()
var results = document.getElementById("results")
results.value = ""
var data = {
action: "relevanssi_truncate_index",
security: nonce.indexing_nonce,
}
intervalID = window.setInterval(relevanssiUpdateClock, 1000)
console.log("Truncating index.")
results.value += relevanssi.truncating_index + " "
jQuery.post(ajaxurl, data, function (response) {
truncate_response = JSON.parse(response)
console.log("Truncate index: " + truncate_response)
if (truncate_response == true) {
results.value += relevanssi.done + "\n"
}
var data = {
action: "relevanssi_count_posts",
}
console.log("Counting posts.")
results.value += relevanssi.counting_posts + " "
jQuery.post(ajaxurl, data, function (response) {
count_response = JSON.parse(response)
console.log("Counted " + count_response + " posts.")
var post_total = parseInt(count_response)
results.value += count_response + " " + relevanssi.posts_found + "\n"
var args = {
completed: 0,
total: post_total,
offset: 0,
total_seconds: 0,
limit: relevanssi_params.indexing_limit,
adjust: relevanssi_params.indexing_adjust,
extend: false,
security: nonce.indexing_nonce,
}
process_indexing_step(args)
})
})
})
})

View File

@@ -0,0 +1,118 @@
p.important {
color: #992000;
}
table.form-table table.widefat th {
padding-left: 8px;
}
#relevanssi_min_word_length {
width: 3em;
}
#relevanssi_trim_logs, #relevanssi_trim_click_logs {
width: 4em;
}
#index_field_input {
margin-top: 1em;
}
#indexing_tab #results {
display: none;
width: 100%;
}
#relevanssi-progress {
display: none;
margin-bottom: 2em;
width: 100%;
height: 20px;
background-color: white;
}
.rpi-indicator {
width: 0;
height: 20px;
background-color: #afe240;
}
.relevanssi-weights-table {
min-width: 400px;
}
.relevanssi-weights-table td {
padding: 0;
}
.relevanssi-weights-table td.col-2, .relevanssi-weights-table th.col-2 {
width: 25%;
}
.rpi-progress {
display: none;
margin: 0.5em 0 2em 0;
width: 100%;
height: 20px;
background-color: white;
}
.rpi-progress div {
width: 0;
height: 20px;
background-color: #afe240;
}
#relevanssi_results {
display: none;
width: 100%;
}
#relevanssi_show_pdf_errors {
text-decoration: underline;
cursor: pointer;
color: #0073aa;
}
#relevanssi_pdf_errors {
display: none;
}
.visually_hidden {
margin: -1px;
padding: 0;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(0 0 0 0);
clip: rect(0,0,0,0);
position: absolute;
}
.relevanssi_disabled, .relevanssi_disabled td, .relevanssi_disabled th, .relevanssi_disabled p {
color: #999;
}
#relevanssi-timer {
display: none;
}
#category_inclusion_checklist ul.children, #category_exclusion_checklist ul.children {
margin-left: 1.5em;
}
#relevanssi_filter_list {
display: none;
}
#redirect_table td {
vertical-align: top;
}
#relevanssi_sees_container, #relevanssi_db_view_container {
width: 80%;
background: white;
padding: 5px 20px;
border: thin solid black;
overflow: scroll;
}

View File

@@ -0,0 +1,74 @@
<?php
/**
* /lib/class-relevanssi-taxonomy-walker.php
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
/**
* A taxonomy walker used in Relevanssi interface.
*
* This is needed for wp_terms_checklist() in the Relevanssi admin interface to
* control the way the taxonomies are listed.
*/
class Relevanssi_Taxonomy_Walker extends Walker_Category_Checklist {
/**
* Name of the input element.
*
* @var string $name Name of the input element.
*/
public $name;
/**
* Creates a single element of the list.
*
* @see Walker::start_el()
*
* @param string $output Used to append additional content (passed by reference).
* @param object $category Category data object.
* @param int $depth Optional. Depth of category in reference to parents. Default 0.
* @param array $args Optional. An array of arguments. See wp_list_categories(). Default empty array.
* @param int $id Optional. ID of the current category. Default 0.
*/
public function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
if ( empty( $args['taxonomy'] ) ) {
$taxonomy = 'category';
} else {
$taxonomy = $args['taxonomy'];
}
$name = $this->name;
if ( ! isset( $args['popular_cats'] ) ) {
$args['popular_cats'] = array();
}
if ( ! isset( $args['selected_cats'] ) ) {
$args['selected_cats'] = array();
}
$class = '';
$inner_class = '';
if ( ! empty( $args['list_only'] ) ) {
$aria_checked = 'false';
$inner_class = 'category';
$output .= "\n" . '<li' . $class . '>' .
'<div class="' . $inner_class . '" data-term-id=' . $category->term_id .
' tabindex="0" role="checkbox" aria-checked="' . $aria_checked . '">' .
/** This filter is documented in wp-includes/category-template.php */
esc_html( apply_filters( 'the_category', $category->name, '', '' ) ) . '</div>';
} else {
$output .= "\n<li id='{$taxonomy}-{$category->term_id}'$class>" .
'<label class="selectit"><input value="' . $category->term_id . '" type="checkbox" name="' . $name . '[]" id="in-' . $taxonomy . '-' . $category->term_id . '"' .
checked( in_array( intval( $category->term_id ), $args['selected_cats'], true ), true, false ) .
disabled( empty( $args['disabled'] ), false, false ) . ' /> ' .
/** This filter is documented in wp-includes/category-template.php */
esc_html( apply_filters( 'the_category', $category->name, '', '' ) ) . '</label>';
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,284 @@
<?php
/**
* /lib/compatibility/acf.php
*
* Advanced Custom Fields compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_action( 'acf/render_field_settings', 'relevanssi_acf_exclude_setting' );
add_filter( 'relevanssi_search_ok', 'relevanssi_acf_relationship_fields' );
add_filter( 'relevanssi_index_custom_fields', 'relevanssi_acf_exclude_fields', 10, 2 );
/**
* Disables Relevanssi in the ACF Relationship field post search.
*
* We don't want to use Relevanssi on the ACF Relationship field post searches, so
* this function disables it (on the 'relevanssi_search_ok' hook).
*
* @param boolean $search_ok Block the search or not.
*
* @return boolean False, if this is an ACF Relationship field search, pass the
* parameter unchanged otherwise.
*/
function relevanssi_acf_relationship_fields( $search_ok ) {
// phpcs:disable WordPress.Security.NonceVerification
if ( isset( $_REQUEST['action'] )
&& is_string( $_REQUEST['action'] )
&& 'acf' === substr( $_REQUEST['action'], 0, 3 ) ) {
$search_ok = false;
}
return $search_ok;
}
/**
* Indexes the human-readable value of "choice" options list from ACF.
*
* @author Droz Raphaël
*
* @param array $insert_data The insert data array.
* @param int $post_id The post ID.
* @param string $field_name Name of the field.
* @param string $field_value The field value.
*
* @return int Number of tokens indexed.
*/
function relevanssi_index_acf( &$insert_data, $post_id, $field_name, $field_value ) {
if ( ! is_admin() ) {
include_once ABSPATH . 'wp-admin/includes/plugin.php'; // Otherwise is_plugin_active() will cause a fatal error.
}
if ( ! function_exists( 'is_plugin_active' ) ) {
return 0;
}
if ( ! is_plugin_active( 'advanced-custom-fields/acf.php' ) && ! is_plugin_active( 'advanced-custom-fields-pro/acf.php' ) ) {
return 0;
}
if ( ! function_exists( 'get_field_object' ) ) {
return 0; // ACF is active, but not loaded.
}
$field_object = get_field_object( $field_name, $post_id );
if ( ! isset( $field_object['choices'] ) ) {
return 0; // Not a "select" field.
}
if ( is_array( $field_value ) ) {
return 0; // Not handled (currently).
}
if ( ! isset( $field_object['choices'][ $field_value ] ) ) {
return 0; // Value does not exist.
}
$n = 0;
/**
* Filters the field value before it is used to save the insert data.
*
* The value is used as an array key, so it needs to be an integer or a
* string. If your custom field values are arrays or objects, use this
* filter hook to convert them into strings.
*
* @param mixed $field_content The ACF field value.
* @param string $field_name The ACF field name.
* @param int $post_id The post ID.
*
* @return string|int The field value.
*/
$value = apply_filters(
'relevanssi_acf_field_value',
$field_object['choices'][ $field_value ],
$field_name,
$post_id
);
if ( $value && ( is_integer( $value ) || is_string( $value ) ) ) {
$min_word_length = get_option( 'relevanssi_min_word_length', 3 );
/** This filter is documented in lib/indexing.php */
$value_tokens = apply_filters( 'relevanssi_indexing_tokens', relevanssi_tokenize( $value, true, $min_word_length, 'indexing' ), 'custom_field' );
foreach ( $value_tokens as $token => $count ) {
++$n;
if ( ! isset( $insert_data[ $token ]['customfield'] ) ) {
$insert_data[ $token ]['customfield'] = 0;
}
$insert_data[ $token ]['customfield'] += $count;
// Premium indexes more detail about custom fields.
if ( function_exists( 'relevanssi_customfield_detail' ) ) {
$insert_data = relevanssi_customfield_detail( $insert_data, $token, $count, $field_name );
}
}
}
return $n;
}
/**
* Adds a Relevanssi exclude setting to ACF fields.
*
* @param array $field The field object array.
*/
function relevanssi_acf_exclude_setting( $field ) {
if ( ! function_exists( 'acf_render_field_setting' ) ) {
return;
}
if ( 'clone' === $field['type'] ) {
return;
}
acf_render_field_setting(
$field,
array(
'label' => __( 'Exclude from Relevanssi index', 'relevanssi' ),
'instructions' => __( 'If this setting is enabled, Relevanssi will not index the value of this field for posts.', 'relevanssi' ),
'name' => 'relevanssi_exclude',
'type' => 'true_false',
'ui' => 1,
),
true
);
}
/**
* Excludes ACF fields based on the exclude setting.
*
* Hooks on to relevanssi_index_custom_fields.
*
* @param array $fields The list of custom fields to index.
* @param int $post_id The post ID.
*
* @return array Filtered list of custom fields.
*/
function relevanssi_acf_exclude_fields( $fields, $post_id ) {
$included_fields = array();
$excluded_fields = array();
/**
* Filters the types of ACF fields to exclude from indexing.
*
* By default, blocks 'repeater', 'flexible_content' and 'group' are
* excluded from Relevanssi indexing. You can add other field types here.
*
* @param array $excluded_field_types The field types to exclude.
*/
$blocked_field_types = apply_filters(
'relevanssi_blocked_field_types',
array( 'repeater', 'flexible_content', 'group' )
);
global $post;
foreach ( $fields as $field ) {
$global_post = $post; // ACF fields can change the global $post.
$field_object = get_field_object( $field );
$post = $global_post; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
if ( ! $field_object || ! is_array( $field_object ) ) {
$field_id = relevanssi_acf_get_field_id( $field, $post_id );
if ( ! $field_id ) {
// No field ID -> not an ACF field. Include.
$included_fields[] = $field;
} else {
/*
* This field has a field ID, but get_field_object() does not
* return a field object. This may be a clone field, in which
* case we can try to get the field object from the field ID.
* Clone fields have keys like field_xxx_field_yyy, where the
* field_yyy is the part we need.
*/
$field_id = preg_replace( '/.*_(field_.*)/', '$1', $field_id );
$field_object = get_field_object( $field_id );
}
}
if ( $field_object ) {
/**
* Filters the ACF field object.
*
* If the filter returns a false value, Relevanssi will not index
* the field.
*
* @param array $field_object The field object.
* @param int $post_id The post ID.
*
* @return array The filtered field object.
*/
$field_object = apply_filters(
'relevanssi_acf_field_object',
$field_object,
$post_id
);
if ( ! $field_object ) {
continue;
}
if ( isset( $field_object['relevanssi_exclude'] ) && 1 === $field_object['relevanssi_exclude'] ) {
continue;
}
if ( relevanssi_acf_is_parent_excluded( $field_object ) ) {
continue;
}
if ( isset( $field_object['type'] ) && in_array( $field_object['type'], $blocked_field_types, true ) ) {
continue;
}
$included_fields[] = $field;
}
}
return $included_fields;
}
/**
* Checks if the field has an excluded parent field.
*
* If the field has a "parent" value set, this function gets the parent field
* post based on the post ID in the "parent" value. This is done recursively
* until we reach the top or find an excluded parent.
*
* @param array $field_object The field object.
*
* @return bool Returns true if the post has an excluded parent.
*/
function relevanssi_acf_is_parent_excluded( $field_object ) {
if ( isset( $field_object['parent'] ) ) {
$parent = $field_object['parent'];
if ( $parent ) {
$parent_field_post = get_post( $parent );
if ( $parent_field_post ) {
$parent_object = get_field_object( $parent_field_post->post_name );
if ( $parent_object ) {
if ( isset( $parent_object['relevanssi_exclude'] ) && 1 === $parent_object['relevanssi_exclude'] ) {
return true;
}
return relevanssi_acf_is_parent_excluded( $parent_object );
}
}
}
}
return false;
}
/**
* Gets the field ID from the field name.
*
* The field ID is stored in the postmeta table with the field name prefixed
* with an underscore as the key.
*
* @param string $field_name The field name.
* @param int $post_id The post ID.
*
* @return string The field ID.
*/
function relevanssi_acf_get_field_id( $field_name, $post_id ) {
global $wpdb;
$field_id = $wpdb->get_var(
$wpdb->prepare(
"SELECT meta_value FROM $wpdb->postmeta
WHERE post_id = %d
AND meta_key = %s",
$post_id,
'_' . $field_name
)
);
return $field_id;
}

View File

@@ -0,0 +1,108 @@
<?php
/**
* /lib/compatibility/aioseo.php
*
* All-in-One SEO noindex filtering function.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_do_not_index', 'relevanssi_aioseo_noindex', 10, 2 );
add_filter( 'relevanssi_indexing_restriction', 'relevanssi_aioseo_exclude' );
add_action( 'relevanssi_indexing_tab_advanced', 'relevanssi_aioseo_form', 20 );
add_action( 'relevanssi_indexing_options', 'relevanssi_aioseo_options' );
/**
* Blocks indexing of posts marked "noindex" in the All-in-One SEO settings.
*
* Attaches to the 'relevanssi_do_not_index' filter hook.
*
* @param boolean $do_not_index True, if the post shouldn't be indexed.
* @param integer $post_id The post ID number.
*
* @return string|boolean If the post shouldn't be indexed, this returns
* 'aioseo_seo'. The value may also be a boolean.
*/
function relevanssi_aioseo_noindex( bool $do_not_index, int $post_id ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $do_not_index;
}
$noindex_posts = relevanssi_aioseo_get_noindex_posts();
if ( in_array( $post_id, $noindex_posts, true ) ) {
$do_not_index = 'All-in-One SEO';
}
return $do_not_index;
}
/**
* Excludes the "noindex" posts from Relevanssi indexing.
*
* Adds a MySQL query restriction that blocks posts that have the aioseo SEO
* "noindex" setting set to "1" from indexing.
*
* @param array $restriction An array with two values: 'mysql' for the MySQL
* query restriction to modify, 'reason' for the reason of restriction.
*/
function relevanssi_aioseo_exclude( array $restriction ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $restriction;
}
global $wpdb;
$restriction['mysql'] .= " AND post.ID NOT IN (SELECT post_id FROM
{$wpdb->prefix}aioseo_posts WHERE robots_noindex = '1' ) ";
$restriction['reason'] .= ' All-in-One SEO';
return $restriction;
}
/**
* Fetches the post IDs where robots_noindex is set to 1 in the aioseo_posts
* table.
*
* @return array An array of post IDs.
*/
function relevanssi_aioseo_get_noindex_posts() {
global $wpdb, $relevanssi_aioseo_noindex_cache;
if ( ! empty( $relevanssi_aioseo_noindex_cache ) ) {
return $relevanssi_aioseo_noindex_cache;
}
$relevanssi_aioseo_noindex_cache = $wpdb->get_col( "SELECT post_id FROM {$wpdb->prefix}aioseo_posts WHERE 'robots_noindex' = '1'" );
return $relevanssi_aioseo_noindex_cache;
}
/**
* Prints out the form fields for disabling the feature.
*/
function relevanssi_aioseo_form() {
$seo_noindex = get_option( 'relevanssi_seo_noindex' );
$seo_noindex = relevanssi_check( $seo_noindex );
?>
<tr>
<th scope="row">
<label for='relevanssi_seo_noindex'><?php esc_html_e( 'Use All-in-One SEO noindex', 'relevanssi' ); ?></label>
</th>
<td>
<label for='relevanssi_seo_noindex'>
<input type='checkbox' name='relevanssi_seo_noindex' id='relevanssi_seo_noindex' <?php echo esc_attr( $seo_noindex ); ?> />
<?php esc_html_e( 'Use All-in-One SEO noindex.', 'relevanssi' ); ?>
</label>
<p class="description"><?php esc_html_e( 'If checked, Relevanssi will not index posts marked as "No index" in All-in-One SEO settings.', 'relevanssi' ); ?></p>
</td>
</tr>
<?php
}
/**
* Saves the SEO No index option.
*
* @param array $request An array of option values from the request.
*/
function relevanssi_aioseo_options( array $request ) {
relevanssi_update_off_or_on( $request, 'relevanssi_seo_noindex', true );
}

View File

@@ -0,0 +1,19 @@
<?php
/**
* /lib/compatibility/avada.php
*
* Avada theme compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter(
'fusion_live_search_query_args',
function ( $args ) {
$args['relevanssi'] = true;
return $args;
}
);

View File

@@ -0,0 +1,97 @@
<?php
/**
* /lib/compatibility/bricks.php
*
* Bricks theme compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'bricks/posts/query_vars', 'relevanssi_bricks_enable', 10 );
add_filter( 'relevanssi_custom_field_value', 'relevanssi_bricks_values', 10, 2 );
add_filter( 'relevanssi_index_custom_fields', 'relevanssi_add_bricks' );
add_filter( 'option_relevanssi_index_fields', 'relevanssi_bricks_fix_none_setting' );
add_action( 'save_post', 'relevanssi_insert_edit', 99, 1 );
/**
* Enables Relevanssi in the query when the 's' query var is set.
*
* @param array $query_vars The query variables.
*
* @return array The query variables with the Relevanssi toggle enabled.
*/
function relevanssi_bricks_enable( $query_vars ) {
if ( isset( $query_vars['s'] ) ) {
$query_vars['relevanssi'] = true;
}
return $query_vars;
}
/**
* Adds the `_bricks_page_content_2` to the list of indexed custom fields.
*
* @param array|boolean $fields An array of custom fields to index, or false.
*
* @return array An array of custom fields, including `_bricks_page_content_2`.
*/
function relevanssi_add_bricks( $fields ) {
if ( ! is_array( $fields ) ) {
$fields = array();
}
if ( ! in_array( '_bricks_page_content_2', $fields, true ) ) {
$fields[] = '_bricks_page_content_2';
}
return $fields;
}
/**
* Includes only text from _bricks_page_content_2 custom field.
*
* This function goes through the multilevel array of _bricks_page_content_2
* and only picks up the "text" elements inside it, discarding everything else.
*
* @param array $value An array of custom field values.
* @param string $field The name of the custom field.
*
* @return array An array containing a string with all the values concatenated
* together.
*/
function relevanssi_bricks_values( $value, $field ) {
if ( '_bricks_page_content_2' !== $field ) {
return $value;
}
$content = '';
array_walk_recursive(
$value,
function ( $text, $key ) use ( &$content ) {
if ( 'text' === $key ) {
$content .= ' ' . $text;
}
}
);
return array( $content );
}
/**
* Makes sure the Bricks builder shortcode is included in the index, even when
* the custom field setting is set to 'none'.
*
* @param string $value The custom field indexing setting value. The parameter
* is ignored, Relevanssi disables this filter and then checks the option to
* see what the value is.
*
* @return string If value is undefined, it's set to '_bricks_page_content_2'.
*/
function relevanssi_bricks_fix_none_setting( $value ) {
if ( ! $value ) {
$value = '_bricks_page_content_2';
}
return $value;
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* /lib/compatibility/elementor.php
*
* Elementor page builder compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_search_ok', 'relevanssi_block_elementor_library', 10, 2 );
/**
* Blocks Relevanssi from interfering with the Elementor Library searches.
*
* @param bool $ok Should Relevanssi be allowed to process the query.
* @param WP_Query $query The WP_Query object.
*
* @return bool Returns false, if this is an Elementor library search.
*/
function relevanssi_block_elementor_library( bool $ok, WP_Query $query ): bool {
if ( 'elementor_library' === $query->query_vars['post_type'] ) {
$ok = false;
}
return $ok;
}

View File

@@ -0,0 +1,27 @@
<?php
/**
* /lib/compatibility/fibosearch.php
*
* Fibo Search compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'dgwt/wcas/search_query/args', 'relevanssi_enable_relevanssi_in_fibo' );
/**
* Adds the 'relevanssi' parameter to the Fibo Search.
*
* Uses the dgwt/wcas/search_query_args filter hook to modify the search query.
*
* @param array $args The search arguments.
*
* @return array
*/
function relevanssi_enable_relevanssi_in_fibo( $args ) {
$args['relevanssi'] = true;
return $args;
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* /lib/compatibility/groups.php
*
* Groups compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_ok', 'relevanssi_groups_compatibility', 10, 2 );
/**
* Checks whether the user is allowed to see the post.
*
* Only applies to published posts.
*
* @param boolean $post_ok Can the post be shown to the user.
* @param int $post_id The post ID.
*
* @return boolean $post_ok True if the user is allowed to see the post,
* otherwise false.
*/
function relevanssi_groups_compatibility( $post_ok, $post_id ) {
$status = relevanssi_get_post_status( $post_id );
if ( 'publish' === $status ) {
// Only apply to published posts, don't apply to drafts.
$current_user = wp_get_current_user();
$post_ok = Groups_Post_Access::user_can_read_post( $post_id, $current_user->ID );
}
return $post_ok;
}

View File

@@ -0,0 +1,173 @@
<?php
/**
* /lib/compatibility/gutenberg.php
*
* Gutenberg compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_content', 'relevanssi_gutenberg_block_rendering', 10, 2 );
/**
* Registers rest_after_insert_{post_type} actions for all indexed post types.
*
* Runs on `admin_init` action hook and registers the function
* `relevanssi_save_gutenberg_postdata` for all indexed post types.
*
* @see relevanssi_save_gutenberg_postdata
*/
function relevanssi_register_gutenberg_actions() {
if ( ! RELEVANSSI_PREMIUM ) {
return;
}
$index_post_types = get_option( 'relevanssi_index_post_types', array() );
array_walk(
$index_post_types,
function ( $post_type ) {
if ( 'bogus' !== $post_type ) {
add_action(
'rest_after_insert_' . $post_type,
'relevanssi_save_gutenberg_postdata'
);
}
}
);
}
/**
* Renders Gutenberg blocks.
*
* Renders all sorts of Gutenberg blocks, including reusable blocks and ACF
* blocks. Also enables basic Gutenberg deindexing: you can add an extra CSS
* class 'relevanssi_noindex' to a block to stop it from being indexed by
* Relevanssi. This function is essentially the same as core do_blocks().
*
* @see do_blocks()
*
* @param string $content The post content.
* @param object $post_object The post object.
*
* @return string The post content with the rendered content added.
*/
function relevanssi_gutenberg_block_rendering( $content, $post_object ) {
/**
* Filters whether the blocks are rendered or not.
*
* If this filter returns false, the blocks in this post are not rendered,
* and the post content is returned as such.
*
* @param boolean If true, render the blocks. Default true.
* @param object The post object.
*/
if ( ! apply_filters( 'relevanssi_render_blocks', true, $post_object ) ) {
return $content;
}
$blocks = parse_blocks( $content );
$output = '';
foreach ( $blocks as $block ) {
/**
* Filters the Gutenberg block before it is rendered.
*
* If the block is non-empty after the filter and it's className
* parameter is not 'relevanssi_noindex', it will be passed on to the
* render_block() function for rendering.
*
* @see render_block
*
* @param array $block The Gutenberg block element.
*/
$block = apply_filters( 'relevanssi_block_to_render', $block );
if ( ! $block ) {
continue;
}
if (
isset( $block['attrs']['className'] )
&& false !== strstr( $block['attrs']['className'], 'relevanssi_noindex' )
) {
continue;
}
$block = relevanssi_process_inner_blocks( $block );
/**
* Filters the Gutenberg block after it is rendered.
*
* The value is the output from render_block( $block ). Feel free to
* modify it as you wish.
*
* @see render_block
*
* @param string The rendered block content.
* @param array $block The Gutenberg block being rendered.
*
* @return string The filtered block content.
*/
$output .= apply_filters( 'relevanssi_rendered_block', render_block( $block ), $block );
}
// If there are blocks in this content, we shouldn't run wpautop() on it later.
$priority = has_filter( 'the_content', 'wpautop' );
if ( false !== $priority && doing_filter( 'the_content' ) && has_blocks( $content ) ) {
remove_filter( 'the_content', 'wpautop', $priority );
add_filter( 'the_content', '_restore_wpautop_hook', $priority + 1 );
}
return $output;
}
/**
* Runs recursively through inner blocks to filter them.
*
* Runs relevanssi_block_to_render and the relevanssi_noindex CSS class check
* on all inner blocks. If inner blocks are filtered out, they will be removed
* with empty blocks of the type "core/fake". Removing the inner blocks causes
* problems; that's why they are replaced. The blocks are rendered here;
* everything will be rendered once at the top level.
*
* @param array $block A Gutenberg block.
*
* @return array The filtered block.
*/
function relevanssi_process_inner_blocks( $block ) {
$innerblocks_to_keep = array();
$empty_block = array(
'blockName' => 'core/fake',
'attrs' => array(),
'innerHTML' => '',
'innerBlocks' => array(),
);
foreach ( $block['innerBlocks'] as $inner_block ) {
/* Filter documented in /lib/compatibility/gutenberg.php. */
$inner_block = apply_filters( 'relevanssi_block_to_render', $inner_block );
if ( ! $inner_block ) {
$innerblocks_to_keep[] = $empty_block;
continue;
}
if (
isset( $inner_block['attrs']['className'] )
&& false !== strstr( $inner_block['attrs']['className'], 'relevanssi_noindex' )
) {
$innerblocks_to_keep[] = $empty_block;
continue;
}
$inner_block = relevanssi_process_inner_blocks( $inner_block );
$innerblocks_to_keep[] = $inner_block;
}
$block['innerBlocks'] = $innerblocks_to_keep;
return $block;
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* /lib/compatibility/jetsmartfilters.php
*
* JetSmartFilters compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_action( 'pre_get_posts', 'relevanssi_jetsmartfilters', 9999 );
/**
* Makes JetSmartFilters use posts from Relevanssi.
*
* @param WP_Query $wp_query The wp_query object.
*/
function relevanssi_jetsmartfilters( $wp_query ) {
if (
! isset( $wp_query->query['jet_smart_filters'] )
|| empty( $wp_query->query['s'] )
) {
return;
}
$args = array(
's' => $wp_query->query['s'],
'fields' => 'ids',
'posts_per_page' => -1,
'relevanssi' => true,
);
$relevanssi_query = new WP_Query( $args );
$results = ! empty( $relevanssi_query->posts )
? $relevanssi_query->posts
: array( 0 );
$wp_query->set( 'post__in', $results );
$wp_query->set( 'post_type', 'any' );
$wp_query->set( 'post_status', 'any' );
$wp_query->set( 'orderby', 'post__in' );
$wp_query->set( 'order', 'DESC' );
$wp_query->set( 's', false );
}

View File

@@ -0,0 +1,31 @@
<?php
/**
* /lib/compatibility/memberpress.php
*
* Memberpress compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_ok', 'relevanssi_memberpress_compatibility', 10, 2 );
/**
* Checks whether the user is allowed to see the post.
*
* @param boolean $post_ok Can the post be shown to the user.
* @param int $post_id The post ID.
*
* @return boolean $post_ok True if the user is allowed to see the post,
* otherwise false.
*/
function relevanssi_memberpress_compatibility( $post_ok, $post_id ) {
$post = get_post( $post_id );
if ( MeprRule::is_locked( $post ) ) {
$post_ok = false;
}
return $post_ok;
}

View File

@@ -0,0 +1,37 @@
<?php
/**
* /lib/compatibility/members.php
*
* Members compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_ok', 'relevanssi_members_compatibility', 10, 2 );
/**
* Checks whether the user is allowed to see the post.
*
* Only applies to private posts and only if the "content permissions" feature
* is enabled.
*
* @param boolean $post_ok Can the post be shown to the user.
* @param int $post_id The post ID.
*
* @return boolean $post_ok True if the user is allowed to see the post,
* otherwise false.
*/
function relevanssi_members_compatibility( $post_ok, $post_id ) {
$status = relevanssi_get_post_status( $post_id );
if ( 'private' === $status ) {
if ( members_content_permissions_enabled() ) {
$post_ok = members_can_current_user_view_post( $post_id );
}
}
return $post_ok;
}

View File

@@ -0,0 +1,94 @@
<?php
/**
* /lib/compatibility/ninjatables.php
*
* Ninja Tables compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_content', 'relevanssi_index_ninja_tables' );
/**
* Indexes Ninja Tables table contents.
*
* Uses regular expression matching to find all the Ninja Tables shortcodes in
* the post content and then uses relevanssi_index_ninja_table() to convert the
* tables into strings.
*
* @uses $wpdb WordPress database abstraction.
* @see relevanssi_index_ninja_table()
*
* @param string $content The post content.
*
* @return string Post content with the Ninja Tables data.
*/
function relevanssi_index_ninja_tables( $content ) {
$m = preg_match_all(
'/.*\[ninja_tables.*?id=["\'](\d+)["\'].*?\]/im',
$content,
$matches,
PREG_PATTERN_ORDER
);
if ( ! $m ) {
return $content;
}
foreach ( $matches[1] as $table_id ) {
$content .= ' ' . relevanssi_index_ninja_table( $table_id );
}
return $content;
}
/**
* Creates a string containing a Ninja Table table contents.
*
* The string contains the caption and the values from each row. The table
* title and description are also included, if they are set visible on the
* frontend.
*
* @uses $wpdb WordPress database abstraction.
*
* @param int $table_id The table ID.
*
* @return string The table content as a string.
*/
function relevanssi_index_ninja_table( $table_id ) {
global $wpdb;
$table_post = get_post( $table_id );
$table_settings = get_post_meta( $table_id, '_ninja_table_settings', true );
$table_contents = '';
if ( isset( $table_settings['show_description'] ) && '1' === $table_settings['show_description'] ) {
$table_contents .= ' ' . $table_post->post_content;
}
if ( isset( $table_settings['show_title'] ) && '1' === $table_settings['show_title'] ) {
$table_contents .= ' ' . $table_post->post_title;
}
$table_contents .= ' ' . get_post_meta( $table_id, '_ninja_table_caption', true );
$rows = $wpdb->get_results(
$wpdb->prepare(
"SELECT value FROM {$wpdb->prefix}ninja_table_items WHERE table_id=%d",
$table_id
)
);
foreach ( $rows as $row ) {
$array_values = array_map(
function ( $value ) {
if ( is_object( $value ) ) {
return '';
}
return strval( $value );
},
array_values( get_object_vars( json_decode( $row->value ) ) )
);
$table_contents .= ' ' . implode( ' ', $array_values );
}
return $table_contents;
}

View File

@@ -0,0 +1,259 @@
<?php
/**
* /lib/compatibility/oxygen.php
*
* Oxygen Builder compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_custom_field_value', 'relevanssi_oxygen_compatibility', 10, 3 );
add_filter( 'relevanssi_index_custom_fields', 'relevanssi_add_oxygen' );
add_filter( 'option_relevanssi_index_fields', 'relevanssi_oxygen_fix_none_setting' );
add_filter( 'relevanssi_oxygen_section_content', 'relevanssi_oxygen_code_block' );
add_filter( 'relevanssi_oxygen_section_content', 'relevanssi_oxygen_rich_text' );
add_action( 'save_post', 'relevanssi_insert_edit', 99, 1 );
/**
* Cleans up the Oxygen Builder custom field for Relevanssi consumption.
*
* Splits up the big custom field content from ct_builder_shortcodes into
* sections ([ct_section] tags). Each section can be processed with filters
* defined with `relevanssi_oxygen_section_filters`, for example to remove
* sections based on their "nicename" or "ct_category" values. After that the
* section is passed through the `relevanssi_oxygen_section_content` filter.
* Finally all shortcode tags are removed, leaving just the content.
*
* @param array $value An array of custom field values.
* @param string $field The name of the custom field. This function only looks
* at `ct_builder_shortcodes` fields.
* @param int $post_id The post ID.
*
* @return array|null An array of custom field values, null if no value exists.
*/
function relevanssi_oxygen_compatibility( $value, $field, $post_id ) {
if ( 'ct_builder_json' === $field ) {
$json = array();
foreach ( $value as $row ) {
$json[] = json_decode( $row );
}
$content = '';
if ( isset( $json[0]->children ) ) {
foreach ( $json[0]->children as $child ) {
$content .= relevanssi_process_oxygen_child( $child );
}
}
$value[0] = $content;
return $value;
}
if ( 'ct_builder_shortcodes_revisions_dates' === $field ) {
return '';
}
if ( 'ct_builder_shortcodes_revisions' === $field ) {
return '';
}
if ( 'ct_builder_shortcodes' === $field ) {
if ( version_compare( CT_VERSION, '4.0', '>=' ) ) {
return null;
}
if ( empty( $value ) ) {
return null;
}
$content_tags = explode( '[ct_section', $value[0] );
$page_content = '';
foreach ( $content_tags as $content ) {
if ( empty( $content ) ) {
continue;
}
if ( '[' !== substr( $content, 0, 1 ) ) {
$content = '[ct_section' . $content;
}
/**
* Allows defining filters to remove Oxygen Builder sections.
*
* The filters are arrays, with the array key defining the key and
* the value defining the value. If the filter array is
* array( 'nicename' => 'Hero BG' ), Relevanssi will look for
* sections that have "nicename":"Hero BG" in their settings and
* will remove those.
*
* @param array An array of filtering rules, defaults empty.
*
* @return array
*/
$filters = apply_filters(
'relevanssi_oxygen_section_filters',
array()
);
array_walk(
$filters,
function ( $filter ) use ( &$content ) {
foreach ( $filter as $key => $value ) {
if ( stristr( $content, '"' . $key . '":"' . $value . '"' ) !== false ) {
$content = '';
}
}
}
);
$content = preg_replace(
array(
'/\[oxygen.*?\]/',
'/\[\/?ct_.*?\]/',
'/\[\/?oxy_.*?\]/',
),
' ',
/**
* Filters the Oxygen Builder section content before the
* Oxygen Builder shortcode tags are removed.
*
* @param string $content The single section content.
* @param int $post_id The post ID.
*
* @return string
*/
apply_filters(
'relevanssi_oxygen_section_content',
$content,
$post_id
)
);
$page_content .= $content;
}
$page_content = relevanssi_do_shortcode( $page_content );
$value[0] = $page_content;
}
return $value;
}
/**
* Recursively processes the Oxygen JSON data.
*
* This function extracts all the ct_content data from the JSON. All elements
* are run through the relevanssi_oxygen_element filter hook. You can use that
* filter hook to modify or to eliminate elements from the JSON.
*
* @param array $child The child element array.
*
* @return string The content from the child and the grandchildren.
*/
function relevanssi_process_oxygen_child( $child ): string {
/**
* Filters the Oxygen JSON child element.
*
* If the filter returns an empty value, the child element and all its
* children will be ignored.
*
* @param array $child The JSON child element.
*/
$child = apply_filters( 'relevanssi_oxygen_element', $child );
if ( empty( $child ) ) {
return '';
}
$child_content = ' ';
if ( isset( $child->options->ct_content ) ) {
$child_content .= $child->options->ct_content;
}
if ( isset( $child->options->original->{'code-php'} ) ) {
// For code and HTML blocks, strip all tags.
$child_content .= wp_strip_all_tags( $child->options->original->{'code-php'} );
}
if ( isset( $child->children ) ) {
foreach ( $child->children as $grandchild ) {
$child_content .= relevanssi_process_oxygen_child( $grandchild );
}
}
return $child_content;
}
/**
* Adds the Oxygen custom field to the list of indexed custom fields.
*
* @param array|boolean $fields An array of custom fields to index, or false.
*
* @return array An array of custom fields, including `ct_builder_json` or
* `ct_builder_shortcodes`.
*/
function relevanssi_add_oxygen( $fields ) {
$oxygen_field = version_compare( CT_VERSION, '4.0', '>=' )
? 'ct_builder_json'
: 'ct_builder_shortcodes';
if ( ! is_array( $fields ) ) {
$fields = array();
}
if ( ! in_array( $oxygen_field, $fields, true ) ) {
$fields[] = $oxygen_field;
}
return $fields;
}
/**
* Makes sure the Oxygen builder shortcode is included in the index, even when
* the custom field setting is set to 'none'.
*
* @param string $value The custom field indexing setting value. The parameter
* is ignored, Relevanssi disables this filter and then checks the option to
* see what the value is.
*
* @return string If value is undefined, it's set to 'ct_builder_json' or
* 'ct_builder_shortcodes'.
*/
function relevanssi_oxygen_fix_none_setting( $value ) {
if ( ! $value ) {
$value = version_compare( CT_VERSION, '4.0', '>=' )
? 'ct_builder_json'
: 'ct_builder_shortcodes';
}
return $value;
}
/**
* Indexes the Base64 encoded PHP & HTML code block contents.
*
* @param string $content The section content from the
* relevanssi_oxygen_section_content filter hook.
*
* @return string $content The content with the decoded code block content
* added to the end.
*/
function relevanssi_oxygen_code_block( $content ) {
if ( preg_match_all( '/\[ct_code_block.*?ct_code_block\]/', $content, $matches ) ) {
foreach ( $matches[0] as $match ) {
if ( preg_match_all( '/"code-php":"(.*?)"/', $match, $block_matches ) ) {
foreach ( $block_matches[1] as $encoded_text ) {
$content .= ' ' . base64_decode( $encoded_text ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions
}
}
}
}
return $content;
}
/**
* Removes the Oxygen rich text shortcode.
*
* @param string $content The content of the Oxygen section.
*
* @return string The content with the oxy_rich_text shortcodes removed.
*/
function relevanssi_oxygen_rich_text( $content ) {
$content = preg_replace( '/\[\/?oxy_rich_text.*?\]/im', '', $content );
return $content;
}

View File

@@ -0,0 +1,38 @@
<?php
/**
* /lib/compatibility/paidmembershippro.php
*
* Paid Membership Pro compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_ok', 'relevanssi_paidmembershippro_compatibility', 10, 2 );
/**
* Checks whether the user is allowed to see the post.
*
* @param boolean $post_ok Can the post be shown to the user.
* @param int $post_id The post ID.
*
* @return boolean $post_ok True if the user is allowed to see the post,
* otherwise false.
*/
function relevanssi_paidmembershippro_compatibility( $post_ok, $post_id ) {
$pmpro_active = get_option( 'pmpro_filterqueries', 0 );
if ( $pmpro_active ) {
$status = relevanssi_get_post_status( $post_id );
if ( 'publish' === $status ) {
// Only apply to published posts, don't apply to drafts.
$current_user = wp_get_current_user();
$post_ok = pmpro_has_membership_access( $post_id, $current_user->ID );
}
}
return $post_ok;
}

View File

@@ -0,0 +1,205 @@
<?php
/**
* /lib/compatibility/polylang.php
*
* Polylang compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_modify_wp_query', 'relevanssi_polylang_filter' );
add_filter( 'relevanssi_where', 'relevanssi_polylang_where_include_terms' );
add_filter( 'relevanssi_hits_filter', 'relevanssi_polylang_term_filter' );
/**
* Removes the Polylang language filters.
*
* If the Polylang allow all option ('relevanssi_polylang_all_languages') is
* enabled this removes the Polylang language filter. By default Polylang
* filters the languages using a taxonomy query.
*
* @param object $query WP_Query object we need to clean up.
*/
function relevanssi_polylang_filter( $query ) {
$polylang_allow_all = get_option( 'relevanssi_polylang_all_languages' );
if ( 'on' === $polylang_allow_all ) {
$ok_queries = array();
if ( ! isset( $query->tax_query ) ) {
// No tax query set, backing off.
return;
}
if ( ! isset( $query->tax_query->queries ) || ! is_array( $query->tax_query->queries ) ) {
// No tax query set, backing off.
return;
}
foreach ( $query->tax_query->queries as $tax_query ) {
if ( isset( $tax_query['taxonomy'] ) && 'language' !== $tax_query['taxonomy'] ) {
// Not a language tax query.
$ok_queries[] = $tax_query;
}
}
$query->tax_query->queries = $ok_queries;
if ( isset( $query->query_vars['tax_query'] ) ) {
// Tax queries can be here as well, so let's sweep this one too.
$ok_queries = array();
foreach ( $query->query_vars['tax_query'] as $tax_query ) {
if ( isset( $tax_query['taxonomy'] ) ) {
if ( 'language' !== $tax_query['taxonomy'] ) {
$ok_queries[] = $tax_query;
}
} else {
// Relation parameter most likely.
$ok_queries[] = $tax_query;
}
}
$query->query_vars['tax_query'] = $ok_queries;
}
if ( isset( $query->query_vars['taxonomy'] ) && 'language' === $query->query_vars['taxonomy'] ) {
// Another way to set the taxonomy.
unset( $query->query_vars['taxonomy'] );
unset( $query->query_vars['term'] );
}
}
return $query;
}
/**
* Allows taxonomy terms in language-restricted searches.
*
* This is a bit of a hack, where the language taxonomy WHERE clause is modified
* on the go to allow all posts with the post ID -1 (which means taxonomy terms
* and users). This may break suddenly in updates, but I haven't come up with a
* better way so far.
*
* @param string $where The WHERE clause to modify.
*
* @return string The WHERE clause with additional filtering included.
*
* @since 2.1.6
*/
function relevanssi_polylang_where_include_terms( $where ) {
global $wpdb;
$current_language = substr( get_locale(), 0, 2 );
if ( function_exists( 'pll_current_language' ) ) {
$current_language = pll_current_language();
}
$languages = get_terms( array( 'taxonomy' => 'language' ) );
$language_id = 0;
foreach ( $languages as $language ) {
if (
! is_wp_error( $language ) &&
$language instanceof WP_Term &&
$language->slug === $current_language
) {
$language_id = intval( $language->term_id );
break;
}
}
// Language ID should now have current language ID.
if ( 0 !== $language_id ) {
// Do a simple search-and-replace to modify the query.
$where = preg_replace( '/\s+/', ' ', $where );
$where = preg_replace( '/\(\s/', '(', $where );
$where = str_replace(
"AND relevanssi.doc IN (SELECT DISTINCT(tr.object_id) FROM {$wpdb->prefix}term_relationships AS tr WHERE tr.term_taxonomy_id IN ($language_id))",
"AND (relevanssi.doc IN ( SELECT DISTINCT(tr.object_id) FROM {$wpdb->prefix}term_relationships AS tr WHERE tr.term_taxonomy_id IN ($language_id)) OR (relevanssi.doc = -1))",
$where
);
}
return $where;
}
/**
* Filters out taxonomy terms in the wrong language.
*
* If all languages are not allowed, this filter goes through the results and
* removes the taxonomy terms in the wrong language. This can't be done in the
* original query because the term language information is slightly hard to
* find.
*
* @param array $hits The found posts are in $hits[0].
*
* @return array The $hits array with the unwanted posts removed.
*
* @since 2.1.6
*/
function relevanssi_polylang_term_filter( $hits ) {
$polylang_allow_all = get_option( 'relevanssi_polylang_all_languages' );
if ( 'on' !== $polylang_allow_all ) {
$current_language = substr( get_locale(), 0, 2 );
if ( function_exists( 'pll_current_language' ) ) {
$current_language = pll_current_language();
}
$accepted_hits = array();
foreach ( $hits[0] as $hit ) {
$original_hit = $hit;
if ( is_numeric( $hit ) ) {
// In case "fields" is set to "ids", fetch the post object we need.
$original_hit = $hit;
$hit = get_post( $hit );
}
if ( ! isset( $hit->post_content ) && isset( $hit->ID ) ) {
// The "fields" is set to "id=>parent".
$original_hit = $hit;
$hit = get_post( $hit->ID );
}
if ( isset( $hit->ID ) && -1 === $hit->ID && isset( $hit->term_id ) ) {
$term_id = intval( $hit->term_id );
$translations = pll_get_term_translations( $term_id );
if (
isset( $translations[ $current_language ] ) &&
$translations[ $current_language ] === $term_id
) {
$accepted_hits[] = $original_hit;
}
} else {
$accepted_hits[] = $original_hit;
}
}
$hits[0] = $accepted_hits;
}
return $hits;
}
/**
* Returns the term_taxonomy_id matching the Polylang language based on locale.
*
* @param string $locale The locale string for the language.
*
* @return int The term_taxonomy_id for the language; 0 if nothing is found.
*/
function relevanssi_get_language_term_taxonomy_id( $locale ) {
global $wpdb, $relevanssi_language_term_ids;
if ( isset( $relevanssi_language_term_ids[ $locale ] ) ) {
return $relevanssi_language_term_ids[ $locale ];
}
$languages = $wpdb->get_results(
"SELECT term_taxonomy_id, description FROM $wpdb->term_taxonomy " .
"WHERE taxonomy = 'language'"
);
$term_id = 0;
foreach ( $languages as $row ) {
$description = unserialize( $row->description ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions
if ( $description['locale'] === $locale ) {
$term_id = $row->term_taxonomy_id;
break;
}
}
$relevanssi_language_term_ids[ $locale ] = $term_id;
return $term_id;
}

View File

@@ -0,0 +1,30 @@
<?php
/**
* /lib/compatibility/pretty-links.php
*
* Pretty Links compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_admin_search_ok', 'relevanssi_pretty_links_ok', 10, 2 );
add_filter( 'relevanssi_prevent_default_request', 'relevanssi_pretty_links_ok', 10, 2 );
add_filter( 'relevanssi_search_ok', 'relevanssi_pretty_links_ok', 10, 2 );
/**
* Returns false if the query post type is set to 'pretty-link'.
*
* @param boolean $ok Whether to allow the query.
* @param WP_Query $query The WP_Query object.
*
* @return boolean False if this is a Pretty Links query.
*/
function relevanssi_pretty_links_ok( $ok, $query ) {
if ( isset( $query->query['post_type'] ) && 'pretty-link' === $query->query['post_type'] ) {
$ok = false;
}
return $ok;
}

View File

@@ -0,0 +1,62 @@
<?php
/**
* /lib/compatibility/product-gtin-ean-upc-isbn-for-woocommerce.php.php
*
* Adds Product GTIN (EAN, UPC, ISBN) for WooCommerce support for Relevanssi.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_action( 'pre_option_wpm_pgw_search_by_code', 'relevanssi_disable_gtin_code' );
add_filter( 'relevanssi_index_custom_fields', 'relevanssi_add_wpm_gtin_code' );
add_filter( 'option_relevanssi_index_fields', 'relevanssi_wpm_pgw_fix_none_setting' );
/**
* Disables the 'wpm_pgw_search_by_code' option.
*
* If this option is enabled, it will break Relevanssi search when there's a
* match for the code.
*
* @return string 'no'.
*/
function relevanssi_disable_gtin_code() {
return 'no';
}
/**
* Adds the `_wpm_gtin_code` to the list of indexed custom fields.
*
* @param array|boolean $fields An array of custom fields to index, or false.
*
* @return array An array of custom fields, including `_wpm_gtin_code`.
*/
function relevanssi_add_wpm_gtin_code( $fields ) {
if ( ! is_array( $fields ) ) {
$fields = array();
}
if ( ! in_array( '_wpm_gtin_code', $fields, true ) ) {
$fields[] = '_wpm_gtin_code';
}
return $fields;
}
/**
* Makes sure the GTIN code is included in the index, even when the custom field
* setting is set to 'none'.
*
* @param string $value The custom field indexing setting value. The parameter
* is ignored, Relevanssi disables this filter and then checks the option to
* see what the value is.
*
* @return string If value is undefined, it's set to '_wpm_gtin_code'.
*/
function relevanssi_wpm_pgw_fix_none_setting( $value ) {
if ( ! $value ) {
$value = '_wpm_gtin_code';
}
return $value;
}

View File

@@ -0,0 +1,100 @@
<?php
/**
* /lib/compatibility/rankmath.php
*
* Rank Math noindex filtering function.
*
* @package Relevanssi
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_do_not_index', 'relevanssi_rankmath_noindex', 10, 2 );
add_filter( 'relevanssi_indexing_restriction', 'relevanssi_rankmath_exclude' );
add_action( 'relevanssi_indexing_tab_advanced', 'relevanssi_rankmath_form', 20 );
add_action( 'relevanssi_indexing_options', 'relevanssi_rankmath_options' );
/**
* Blocks indexing of posts marked "noindex" in the Rank Math settings.
*
* Attaches to the 'relevanssi_do_not_index' filter hook.
*
* @param boolean $do_not_index True, if the post shouldn't be indexed.
* @param integer $post_id The post ID number.
*
* @return string|boolean If the post shouldn't be indexed, this returns
* 'RankMath'. The value may also be a boolean.
*/
function relevanssi_rankmath_noindex( $do_not_index, $post_id ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $do_not_index;
}
$noindex = get_post_meta( $post_id, 'rank_math_robots', true );
if ( is_array( $noindex ) && in_array( 'noindex', $noindex, true ) ) {
$do_not_index = 'RankMath';
}
return $do_not_index;
}
/**
* Excludes the "noindex" posts from Relevanssi indexing.
*
* Adds a MySQL query restriction that blocks posts that have the Rank Math
* "rank_math_robots" setting set to something that includes "noindex".
*
* @param array $restriction An array with two values: 'mysql' for the MySQL
* query restriction to modify, 'reason' for the reason of restriction.
*/
function relevanssi_rankmath_exclude( $restriction ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $restriction;
}
global $wpdb;
// Backwards compatibility code for 2.8.0, remove at some point.
if ( is_string( $restriction ) ) {
$restriction = array(
'mysql' => $restriction,
'reason' => '',
);
}
$restriction['mysql'] .= " AND post.ID NOT IN (SELECT post_id FROM
$wpdb->postmeta WHERE meta_key = 'rank_math_robots'
AND meta_value LIKE '%noindex%' ) ";
$restriction['reason'] .= ' Rank Math';
return $restriction;
}
/**
* Prints out the form fields for disabling the feature.
*/
function relevanssi_rankmath_form() {
$seo_noindex = get_option( 'relevanssi_seo_noindex' );
$seo_noindex = relevanssi_check( $seo_noindex );
?>
<tr>
<th scope="row">
<label for='relevanssi_seo_noindex'><?php esc_html_e( 'Use Rank Math SEO noindex', 'relevanssi' ); ?></label>
</th>
<td>
<label for='relevanssi_seo_noindex'>
<input type='checkbox' name='relevanssi_seo_noindex' id='relevanssi_seo_noindex' <?php echo esc_attr( $seo_noindex ); ?> />
<?php esc_html_e( 'Use Rank Math SEO noindex.', 'relevanssi' ); ?>
</label>
<p class="description"><?php esc_html_e( 'If checked, Relevanssi will not index posts marked as "No index" in Rank Math SEO settings.', 'relevanssi' ); ?></p>
</td>
</tr>
<?php
}
/**
* Saves the SEO No index option.
*
* @param array $request An array of option values from the request.
*/
function relevanssi_rankmath_options( array $request ) {
relevanssi_update_off_or_on( $request, 'relevanssi_seo_noindex', true );
}

View File

@@ -0,0 +1,32 @@
<?php
/**
* /lib/compatibility/restrictcontentpro.php
*
* Restrict Content Pro compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_ok', 'relevanssi_restrictcontentpro_compatibility', 10, 2 );
/**
* Checks whether the user is allowed to see the post.
*
* @param boolean $post_ok Can the post be shown to the user.
* @param int $post_id The post ID.
*
* @return boolean $post_ok True if the user is allowed to see the post,
* otherwise false.
*/
function relevanssi_restrictcontentpro_compatibility( $post_ok, $post_id ) {
if ( ! $post_ok ) {
return $post_ok;
}
$post_ok = rcp_user_can_access( get_current_user_id(), $post_id );
return $post_ok;
}

View File

@@ -0,0 +1,96 @@
<?php
/**
* /lib/compatibility/seoframework.php
*
* The SEO Framework noindex filtering function.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_do_not_index', 'relevanssi_seoframework_noindex', 10, 2 );
add_filter( 'relevanssi_indexing_restriction', 'relevanssi_seoframework_exclude' );
add_action( 'relevanssi_indexing_tab_advanced', 'relevanssi_seoframework_form', 20 );
add_action( 'relevanssi_indexing_options', 'relevanssi_seoframework_options' );
/**
* Blocks indexing of posts marked "Exclude this page from all search queries
* on this site." in the SEO Framework settings.
*
* Attaches to the 'relevanssi_do_not_index' filter hook.
*
* @param boolean $do_not_index True, if the post shouldn't be indexed.
* @param integer $post_id The post ID number.
*
* @return string|boolean If the post shouldn't be indexed, this returns
* 'SEO Framework'. The value may also be a boolean.
*/
function relevanssi_seoframework_noindex( $do_not_index, $post_id ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $do_not_index;
}
$noindex = get_post_meta( $post_id, 'exclude_local_search', true );
if ( '1' === $noindex ) {
$do_not_index = 'SEO Framework';
}
return $do_not_index;
}
/**
* Excludes the "noindex" posts from Relevanssi indexing.
*
* Adds a MySQL query restriction that blocks posts that have the SEO Framework
* "Exclude this page from all search queries on this site" setting set to "1"
* from indexing.
*
* @param array $restriction An array with two values: 'mysql' for the MySQL
* query restriction to modify, 'reason' for the reason of restriction.
*/
function relevanssi_seoframework_exclude( $restriction ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $restriction;
}
global $wpdb;
$restriction['mysql'] .= " AND post.ID NOT IN (SELECT post_id FROM
$wpdb->postmeta WHERE meta_key = 'exclude_local_search'
AND meta_value = '1' ) ";
$restriction['reason'] .= ' SEO Framework';
return $restriction;
}
/**
* Prints out the form fields for disabling the feature.
*/
function relevanssi_seoframework_form() {
$seo_noindex = get_option( 'relevanssi_seo_noindex' );
$seo_noindex = relevanssi_check( $seo_noindex );
?>
<tr>
<th scope="row">
<label for='relevanssi_seo_noindex'><?php esc_html_e( 'Use SEO Framework noindex', 'relevanssi' ); ?></label>
</th>
<td>
<label for='relevanssi_seo_noindex'>
<input type='checkbox' name='relevanssi_seo_noindex' id='relevanssi_seo_noindex' <?php echo esc_attr( $seo_noindex ); ?> />
<?php esc_html_e( 'Use SEO Framework noindex.', 'relevanssi' ); ?>
</label>
<p class="description"><?php esc_html_e( 'If checked, Relevanssi will not index posts marked as "No index" in SEO Framework settings.', 'relevanssi' ); ?></p>
</td>
</tr>
<?php
}
/**
* Saves the SEO No index option.
*
* @param array $request An array of option values from the request.
*/
function relevanssi_seoframework_options( array $request ) {
relevanssi_update_off_or_on( $request, 'relevanssi_seo_noindex', true );
}

View File

@@ -0,0 +1,102 @@
<?php
/**
* /lib/compatibility/seopress.php
*
* SEOPress noindex filtering function.
*
* @package Relevanssi
* @author Benjamin Denis
* @source ./yoast-seo.php (Mikko Saari)
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_do_not_index', 'relevanssi_seopress_noindex', 10, 2 );
add_filter( 'relevanssi_indexing_restriction', 'relevanssi_seopress_exclude' );
add_action( 'relevanssi_indexing_tab_advanced', 'relevanssi_seopress_form', 20 );
add_action( 'relevanssi_indexing_options', 'relevanssi_seopress_options' );
/**
* Blocks indexing of posts marked "noindex" in the SEOPress settings.
*
* Attaches to the 'relevanssi_do_not_index' filter hook.
*
* @param boolean $do_not_index True, if the post shouldn't be indexed.
* @param integer $post_id The post ID number.
*
* @return string|boolean If the post shouldn't be indexed, this returns
* 'seopress'. The value may also be a boolean.
*/
function relevanssi_seopress_noindex( $do_not_index, $post_id ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $do_not_index;
}
$noindex = get_post_meta( $post_id, '_seopress_robots_index', true );
if ( 'yes' === $noindex ) {
$do_not_index = 'SEOPress';
}
return $do_not_index;
}
/**
* Excludes the "noindex" posts from Relevanssi indexing.
*
* Adds a MySQL query restriction that blocks posts that have the SEOPress
* "noindex" setting set to "1" from indexing.
*
* @param array $restriction An array with two values: 'mysql' for the MySQL
* query restriction to modify, 'reason' for the reason of restriction.
*/
function relevanssi_seopress_exclude( $restriction ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $restriction;
}
global $wpdb;
// Backwards compatibility code for 2.8.0, remove at some point.
if ( is_string( $restriction ) ) {
$restriction = array(
'mysql' => $restriction,
'reason' => '',
);
}
$restriction['mysql'] .= " AND post.ID NOT IN (SELECT post_id FROM
$wpdb->postmeta WHERE meta_key = '_seopress_robots_index'
AND meta_value = 'yes' ) ";
$restriction['reason'] .= 'SEOPress';
return $restriction;
}
/**
* Prints out the form fields for disabling the feature.
*/
function relevanssi_seopress_form() {
$seo_noindex = get_option( 'relevanssi_seo_noindex' );
$seo_noindex = relevanssi_check( $seo_noindex );
?>
<tr>
<th scope="row">
<label for='relevanssi_seo_noindex'><?php esc_html_e( 'Use SEOPress noindex', 'relevanssi' ); ?></label>
</th>
<td>
<label for='relevanssi_seo_noindex'>
<input type='checkbox' name='relevanssi_seo_noindex' id='relevanssi_seo_noindex' <?php echo esc_attr( $seo_noindex ); ?> />
<?php esc_html_e( 'Use SEOPress noindex.', 'relevanssi' ); ?>
</label>
<p class="description"><?php esc_html_e( 'If checked, Relevanssi will not index posts marked as "No index" in SEOPress settings.', 'relevanssi' ); ?></p>
</td>
</tr>
<?php
}
/**
* Saves the SEO No index option.
*
* @param array $request An array of option values from the request.
*/
function relevanssi_seopress_options( array $request ) {
relevanssi_update_off_or_on( $request, 'relevanssi_seo_noindex', true );
}

View File

@@ -0,0 +1,30 @@
<?php
/**
* /lib/compatibility/simplemembership.php
*
* Simple Membership compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_ok', 'relevanssi_simplemembership_compatibility', 10, 2 );
/**
* Checks whether the user is allowed to see the post.
*
* @param boolean $post_ok Can the post be shown to the user.
* @param int $post_id The post ID.
*
* @return boolean $post_ok True if the user is allowed to see the post,
* otherwise false.
*/
function relevanssi_simplemembership_compatibility( $post_ok, $post_id ) {
$access_ctrl = SwpmAccessControl::get_instance();
$post = get_post( $post_id );
$post_ok = $access_ctrl->can_i_read_post( $post );
return $post_ok;
}

Some files were not shown because too many files have changed in this diff Show More