Wordpress Invalid Range In Character Class After Update - php

I have a problem about Visual Compser Backend not showing any elements, it only shows the code in the classic mode editor.
See Screenshot
Warning: preg_match_all(): Compilation failed: invalid range in character class at offset 11 in /home/customer/www/******.com/public_html/wp-content/plugins/js_composer/include/autoload/hook-vc-grid.php on line 162
This is line 162
preg_match_all( "/$pattern/", $post->post_content, $found ); // fetch only needed shortcodes
```public function gridSavePostSettingsId( array $settings, $post_id, $post ) {
$pattern = $this->getShortcodeRegexForId();
preg_match_all( "/$pattern/", $post->post_content, $found ); // fetch only needed shortcodes
$settings['vc_grid_id'] = array();
if ( is_array( $found ) && ! empty( $found[0] ) ) {
$to_save = array();
if ( isset( $found[1] ) && is_array( $found[1] ) ) {
foreach ( $found[1] as $key => $parse_able ) {
if ( empty( $parse_able ) || '[' !== $parse_able ) {
$id_pattern = '/' . $this->grid_id_unique_name . '\:([\w-_]+)/';
$id_value = $found[4][ $key ];
preg_match( $id_pattern, $id_value, $id_matches );
if ( ! empty( $id_matches ) ) {
$id_to_save = $id_matches[1];
// why we need to check if shortcode is parse able?
// 1: if it is escaped it must not be displayed (parsed)
// 2: so if 1 is true it must not be saved in database meta
$shortcode_tag = $found[2][ $key ];
$shortcode_atts_string = $found[3][ $key ];
/** #var $atts array */
$atts = shortcode_parse_atts( $shortcode_atts_string );
$content = $found[6][ $key ];
$data = array(
'tag' => $shortcode_tag,
'atts' => $atts,
'content' => $content,
);
$to_save[ $id_to_save ] = $data;
}
}
}
}
if ( ! empty( $to_save ) ) {
$settings['vc_grid_id'] = array( 'shortcodes' => $to_save );
}
}
return $settings;
}```
I tried disabling all plug-ins and rollback wordpress version but still the same.
Is this problem related to the warning above? I know very little about coding. Please point me in the right direction.
Thank you!

Exactly same problem back-end mode didn't show any elements and /hook-vc-grid.php on line 162 error. " [\w-_] is wrong, it must be [\w-] " this helps only dissappear error but not solution for not showing elements.
Edit: php 7.1 works. It solved elements thing also.
Thank you guys

All hyphen '-' characters (that are not used as a range character) should be escaped '\-' as of PHP 7.3 so that it will NOT be treated anymore as a range character. Therefor the following WordPress function needs to be changed this way to make this expression work the same again:
private function getShortcodeRegexForId() {
return '\\[' // Opening bracket
. '(\\[?)' // 1: Optional second opening bracket for escaping shortcodes: [[tag]]
. '([\\w\-_]+)' // 2: Shortcode name
. '(?![\\w\-])' // Not followed by word character or hyphen

Related

Wordpress migration issue. Warning: PHP Startup: Expected parameter 1 to be an array, bool given in

I have encountered an issue while migrating my wordpress from localhost to the server. Below, there is a short explanation where was the problem and what I have tried to solve it (step by step). Unfortunately it is still not working.
1. When loading new database I have received an error like below:
#1273 - Unknown collation: 'utf8mb4_0900_ai_ci'
My solution to that was replacing unknown collation to "utf8mb4_unicode_520_ci" which is used by the other tables.
2. After doing above, database has loaded without errors, but the most important thing on the landing page has crashed. Where the FORM is placed, there is a bunch of warnings:
Warning: PHP Startup: Expected parameter 1 to be an array, bool given in /wordpress/wp-content/plugins/formidable/classes/helpers/FrmEntriesHelper.php on line 37
Here is the function where the line 37 was prompted as wrong:
public static function setup_new_vars( $fields, $form = '', $reset = false, $args = array() ) {
remove_action( 'media_buttons', 'FrmFormsController::insert_form_button' );
$values = array(
'name' => '',
'description' => '',
'item_key' => '',
);
$values['fields'] = array();
if ( empty( $fields ) ) {
return apply_filters( 'frm_setup_new_entry', $values );
}
foreach ( (array) $fields as $field ) {
$original_default = $field->default_value;
self::prepare_field_default_value( $field );
$new_value = self::get_field_value_for_new_entry( $field, $reset, $args );
$field_array = FrmAppHelper::start_field_array( $field );
$field_array['value'] = $new_value;
$field_array['type'] = apply_filters( 'frm_field_type', $field->type, $field, $new_value );
$field_array['parent_form_id'] = isset( $args['parent_form_id'] ) ? $args['parent_form_id'] : $field->form_id;
$field_array['reset_value'] = $reset;
$field_array['in_embed_form'] = isset( $args['in_embed_form'] ) ? $args['in_embed_form'] : '0';
$field_array['original_default'] = $original_default;
FrmFieldsHelper::prepare_new_front_field( $field_array, $field, $args );
$field_array = array_merge( $field->field_options, $field_array );
$values['fields'][] = $field_array;
if ( ! $form || ! isset( $form->id ) ) {
$form = FrmForm::getOne( $field->form_id );
}
}
FrmAppHelper::unserialize_or_decode( $form->options );
if ( is_array( $form->options ) ) {
$values = array_merge( $values, $form->options );
}
$form_defaults = FrmFormsHelper::get_default_opts();
$form_defaults['custom_style'] = FrmAppHelper::custom_style_value( array() );
$values = array_merge( $form_defaults, $values );
return apply_filters( 'frm_setup_new_entry', $values );
}
Line 37:
$field_array = array_merge( $field->field_options, $field_array );
This issue causes that some of the inputs that should be seen in the form are not displayed. Does anyone of you went through something similar?
Locally I got Mysql 8 installed, on there server there is Mysql 5.6 without possibility to upgrade.

Wordpress: Automatically change URLs in the_content section

The solution from here isn't solving our problem.
I have already a solution to change all links in a field form in our theme. I am using different arrays for every network like $example_network_1 $example_network_2 with a PHP foreach for each affiliate network.
Now I need a solution to use this same arrays for the content of a WordPress post.
This solution is working for one network, but it caused a 404e Error for YouTube videos. We put the URL from a YouTube video and WordPress generates automatically an embedded video. With the following code we get a 404 error iframe or something like this.
We need a solution for more than one network.
I am very thankful for every help!
$example_network_1 = array(
array('shop'=>'shop1.com','id'=>'11111'),
array('shop'=>'shop2.co.uk','id'=>'11112'),
);
$example_network_2 = array(
array('shop'=>'shop-x1.com','id'=>'11413'),
array('shop'=>'shop-x2.net','id'=>'11212'),
);
add_filter( 'the_content', 'wpso_change_urls' ) ;
function wpso_found_urls( $matches ) {
global $example_network_1,$example_network_2;
foreach( $example_network_1 as $rule ) {
if (strpos($matches[0], $rule['shop']) !== false) {
$raw_url = trim( $matches[0], '"' ) ;
return '"https://www.network-x.com/click/'. $rule['id'].'lorem_lorem='.rawurlencode($raw_url ) . '"';
}
/*
foreach( $example_network_2 as $rule ) {
if (strpos($matches[0], $rule['shop']) !== false) {
$raw_url = trim( $matches[0], '"' ) ;
return '"https://www.network-y.com/click/'. $rule['id'].'lorem='.rawurlencode($raw_url ) . '"';
}
*/
}
}
function wpso_change_urls( $content ) {
global $example_network_1,example_network_2;
return preg_replace_callback( '/"+(http|https)(\:\/\/\S*'. $example_network_1 ['shop'] .'\S*")/', 'wpso_found_urls', $content ) ;
// return preg_replace_callback( '/"+(http|https)(\:\/\/\S*'. $example_network_2 ['shop'] .'\S*")/', 'wpso_found_urls', $content ) ;
}
autoembed is hooked at the_content with priority 8 on wp-includes/class-wp-embed.php:39
Try to lower the priority of the the_content filter so that the URL replacement happens before the embed, something like this:
add_filter( 'the_content', function ( $content ) {
/*
* Here, we define the replacements for each site in the network.
* '1' = main blog
* '2' = site 2 in the network, and so on
*
* To add more sites, just add the key number '3', etc
*/
$network_replacements = [
'1' => [
[ 'shop' => 'shop1.com', 'id' => '11111' ],
[ 'shop' => 'shop2.co.uk', 'id' => '11112' ],
],
'2' => [
[ 'shop' => 'shop-x1.com', 'id' => '11413' ],
[ 'shop' => 'shop-x2.net', 'id' => '11212' ],
]
];
// Early bail: Current blog ID does not have replacements defined
if ( ! array_key_exists( get_current_blog_id(), $network_replacements ) ) {
return $content;
}
$replacements = $network_replacements[ get_current_blog_id() ];
return preg_replace_callback( '/"+(http|https)(\:\/\/\S*' . $replacements['shop'] . '\S*")/', function( $matches ) use ( $replacements ) {
foreach ( $replacements as $rule ) {
if ( strpos( $matches[0], $rule['shop'] ) !== false ) {
$raw_url = trim( $matches[0], '"' );
return '"https://www.network-x.com/click/' . $rule['id'] . 'lorem_lorem=' . rawurlencode( $raw_url ) . '"';
}
}
}, $content );
}, 1, 1 );
This is not a copy and paste solution, but should get you going. You might need to tweak your "preg_replace_callback" code, but you said it was working so I just left it is it was.
If preventing the wp auto-embed works, then just add this line to your theme functions.php
remove_filter( 'the_content', array( $GLOBALS['wp_embed'], 'autoembed' ), 8 );
I wrote solution without test. Your code is hard to test without your site but I think that problem is with regex. Callback is hard to debugging. My version below.
First step, change your structure. I suspect that domains are unique. One dimensional array is more useful.
$domains = array(
'shop1.com'=>'11111',
'shop2.co.uk'=>'11112',
'shop-x1.com'=>'11413',
'shop-x2.net'=>'11212',
);
Next:
$dangerouschars = array(
'.'=>'\.',
);
function wpso_change_urls( $content ) {
global $domains,$dangerouschars;
foreach($domains as $domain=>$id){
$escapedDomain = str_replace(array_keys($dangerouschars),array_values($dangerouschars), $domain);
if (preg_match_all('/=\s*"(\s*https?:\/\/(www\.)?'.$escapedDomain.'[^"]+)\s*"\s+/mi', $content, $matches)){
// $matches[0] - ="https://example.com"
// $matches[1] - https://example.com
for($i = 0; $i<count($matches[0]); $i++){
$matchedUrl = $matches[1][$i];
$url = rawurlencode($matchedUrl);
//is very important to replace with ="..."
$content = str_replace($matches[0][$i], "=\"https://www.network-x.com/click/{$id}lorem_lorem={$url}\" ", $content);
}
}
}
return $content;
}
Example script

How to fix "Warning: preg_match() [function.preg-match]: Compilation failed: nothing to repeat at offset 1" in WordPress

When I installed WooCommerce on a WordPress page I got the chance to manage a little while ago, I started getting these errors whenever I go to a subpage:
Warning: preg_match() [function.preg-match]: Compilation failed: nothing to ?repeat at offset 1 in /var/www/watertours.dk/public_html/wp-includes/class-wp.php on line 222
Warning: preg_match() [function.preg-match]: Compilation failed: nothing to repeat at offset 1 in /var/www/watertours.dk/public_html/wp-includes/class-wp.php on line 223"
It even shows up in the dashboard occasionally.
I have found this guide which I have already tried several times:
step 0: if possible, backup your WP installation folder.
step 1: temporary disable all the plugins (important step)
step 2: in WordPress admin dashboard, go to Settings -> Permalinks
step 3: remember or note down somewhere what you have in the custom permalinks field: http://awesomescreenshot.com/0534epzk0c 96
step 4: temporary enable (switch to) the default permalink: http://awesomescreenshot.com/0f74epyi15 79 Click Save Changes button.
step 5: verify the website is working now (not everything, because the plugins are disabled, but the preg_match error should be gone)
step 6: switch back to the custom permalinks setting you had at step 3
step 7: enable back all the plugins
The error should be gone."
It works for a little while (two minutes or so) and then those two errors start popping up again.
I am thinking of just remaking the WordPress site from the ground up since it is quite a mess anyway. But if anyone has a solution, I would be more than grateful. :)
EDIT:
* Parse request to find correct WordPress query.
*
* Sets up the query variables based on the request. There are also many
* filters and actions that can be used to further manipulate the result.
*
* #since 2.0.0
*
* #global WP_Rewrite $wp_rewrite
*
* #param array|string $extra_query_vars Set the extra query variables.
*/
public function parse_request( $extra_query_vars = '' ) {
global $wp_rewrite;
/**
* Filters whether to parse the request.
*
* #since 3.5.0
*
* #param bool $bool Whether or not to parse the request. Default true.
* #param WP $this Current WordPress environment instance.
* #param array|string $extra_query_vars Extra passed query variables.
*/
if ( ! apply_filters( 'do_parse_request', true, $this, $extra_query_vars ) ) {
return;
}
$this->query_vars = array();
$post_type_query_vars = array();
if ( is_array( $extra_query_vars ) ) {
$this->extra_query_vars = & $extra_query_vars;
} elseif ( ! empty( $extra_query_vars ) ) {
parse_str( $extra_query_vars, $this->extra_query_vars );
}
// Process PATH_INFO, REQUEST_URI, and 404 for permalinks.
// Fetch the rewrite rules.
$rewrite = $wp_rewrite->wp_rewrite_rules();
if ( ! empty( $rewrite ) ) {
// If we match a rewrite rule, this will be cleared.
$error = '404';
$this->did_permalink = true;
$pathinfo = isset( $_SERVER['PATH_INFO'] ) ? $_SERVER['PATH_INFO'] : '';
list( $pathinfo ) = explode( '?', $pathinfo );
$pathinfo = str_replace( '%', '%25', $pathinfo );
list( $req_uri ) = explode( '?', $_SERVER['REQUEST_URI'] );
$self = $_SERVER['PHP_SELF'];
$home_path = trim( parse_url( home_url(), PHP_URL_PATH ), '/' );
$home_path_regex = sprintf( '|^%s|i', preg_quote( $home_path, '|' ) );
// Trim path info from the end and the leading home path from the
// front. For path info requests, this leaves us with the requesting
// filename, if any. For 404 requests, this leaves us with the
// requested permalink.
$req_uri = str_replace( $pathinfo, '', $req_uri );
$req_uri = trim( $req_uri, '/' );
$req_uri = preg_replace( $home_path_regex, '', $req_uri );
$req_uri = trim( $req_uri, '/' );
$pathinfo = trim( $pathinfo, '/' );
$pathinfo = preg_replace( $home_path_regex, '', $pathinfo );
$pathinfo = trim( $pathinfo, '/' );
$self = trim( $self, '/' );
$self = preg_replace( $home_path_regex, '', $self );
$self = trim( $self, '/' );
// The requested permalink is in $pathinfo for path info requests and
// $req_uri for other requests.
if ( ! empty( $pathinfo ) && ! preg_match( '|^.*' . $wp_rewrite->index . '$|', $pathinfo ) ) {
$requested_path = $pathinfo;
} else {
// If the request uri is the index, blank it out so that we don't try to match it against a rule.
if ( $req_uri == $wp_rewrite->index ) {
$req_uri = '';
}
$requested_path = $req_uri;
}
$requested_file = $req_uri;
$this->request = $requested_path;
// Look for matches.
$request_match = $requested_path;
if ( empty( $request_match ) ) {
// An empty request could only match against ^$ regex
if ( isset( $rewrite['$'] ) ) {
$this->matched_rule = '$';
$query = $rewrite['$'];
$matches = array( '' );
}
} else {
foreach ( (array) $rewrite as $match => $query ) {
// If the requested file is the anchor of the match, prepend it to the path info.
if ( ! empty( $requested_file ) && strpos( $match, $requested_file ) === 0 && $requested_file != $requested_path ) {
$request_match = $requested_file . '/' . $requested_path;
}
if ( preg_match( "#^$match#", $request_match, $matches ) || // Line 222
preg_match( "#^$match#", urldecode( $request_match ), $matches ) ) { // Line 223
if ( $wp_rewrite->use_verbose_page_rules && preg_match( '/pagename=\$matches\[([0-9]+)\]/', $query, $varmatch ) ) {
// This is a verbose page match, let's check to be sure about it.
$page = get_page_by_path( $matches[ $varmatch[1] ] );
if ( ! $page ) {
continue;
}
$post_status_obj = get_post_status_object( $page->post_status );
if ( ! $post_status_obj->public && ! $post_status_obj->protected
&& ! $post_status_obj->private && $post_status_obj->exclude_from_search ) {
continue;
}
}
// Got a match.
$this->matched_rule = $match;
break;
}
}
}
if ( isset( $this->matched_rule ) ) {
// Trim the query of everything up to the '?'.
$query = preg_replace( '!^.+\?!', '', $query );
// Substitute the substring matches into the query.
$query = addslashes( WP_MatchesMapRegex::apply( $query, $matches ) );
$this->matched_query = $query;
// Parse the query.
parse_str( $query, $perma_query_vars );
// If we're processing a 404 request, clear the error var since we found something.
if ( '404' == $error ) {
unset( $error, $_GET['error'] );
}
}
// If req_uri is empty or if it is a request for ourself, unset error.
if ( empty( $requested_path ) || $requested_file == $self || strpos( $_SERVER['PHP_SELF'], 'wp-admin/' ) !== false ) {
unset( $error, $_GET['error'] );
if ( isset( $perma_query_vars ) && strpos( $_SERVER['PHP_SELF'], 'wp-admin/' ) !== false ) {
unset( $perma_query_vars );
}
$this->did_permalink = false;
}
}```

Cannot use a scalar value as an array in my PHP

I am actually just started to learn PHP and I use wordpress. I put this code but seems something wrong in it. It shows warning message : Cannot use a scalar value as an array. Can you guys help me with this. Its pretty annoying when I see the warning message on the add new product under the product data table.
Oh, I am using PHP 7.1 now.
I've tried to fix it using PHP checker and searching through the search engine but since I am a beginner, I couldn't find anything that can help.
/**
* Localizes a script, only if the script has already been added.
*
* #since 2.1.0
*
* #param string $handle Name of the script to attach data to.
* #param string $object_name Name of the variable that will contain the data.
* #param array $l10n Array of data to localize.
* #return bool True on success, false on failure.
*/
public function localize( $handle, $object_name, $l10n ) {
if ( $handle === 'jquery' ) {
$handle = 'jquery-core';
}
if ( is_array( $l10n ) && isset( $l10n['l10n_print_after'] ) ) { // back compat, preserve the code in 'l10n_print_after' if present.
$after = $l10n['l10n_print_after'];
unset( $l10n['l10n_print_after'] );
}
foreach ( (array) $l10n as $key => $value ) {
if (! is_scalar( $value ) ) {
continue;
}
$l10n[ $key ] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8' );
}
$script = "var $object_name = " . wp_json_encode( $l10n ) . ';';
if ( ! empty( $after ) ) {
$script .= "\n$after;";
}
$data = $this->get_data( $handle, 'data' );
if ( ! empty( $data ) ) {
$script = "$data\n$script";
}
return $this->add_data( $handle, 'data', $script );
}
Just want to see the warning message not showing up again.
Thanks in advance

Characters being replaced by bbcode plugin

I have a bbcode plugin for wordpress.
But for some reason, if I post something like
[i]v497212he2x2MfMi[/i] the "X" character is outputted as ×, which is some other sort of X. How can I fix this?
Plugin code is below:
class BBCode {
// Plugin initialization
function BBCode() {
// This version only supports WP 2.5+ (learn to upgrade please!)
if ( !function_exists('add_shortcode') ) return;
// Register the shortcodes
add_shortcode( 'b' , array(&$this, 'shortcode_bold') );
add_shortcode( 'i' , array(&$this, 'shortcode_italics') );
}
// No-name attribute fixing
function attributefix( $atts = array() ) {
if ( empty($atts[0]) ) return $atts;
if ( 0 !== preg_match( '#=("|\')(.*?)("|\')#', $atts[0], $match ) )
$atts[0] = $match[2];
return $atts;
}
// Bold shortcode
function shortcode_bold( $atts = array(), $content = NULL ) {
if ( NULL === $content ) return '';
return '<strong>' . do_shortcode( $content ) . '</strong>';
}
// Italics shortcode
function shortcode_italics( $atts = array(), $content = NULL ) {
if ( NULL === $content ) return '';
return '<em>' . do_shortcode( $content ) . '</em>';
}
}
// Start this plugin once all other plugins are fully loaded
add_action( 'plugins_loaded', create_function( '', 'global $BBCode; $BBCode = new BBCode();' ) );
This transformation is taking place because of Wordpress's wptexturize() function that returns given text with transformations of quotes to smart quotes, apostrophes, dashes, ellipses, the trademark symbol, and the multiplication symbol.
This is from WP 3.2.1 wp-includes/formatting.php line 55:
$dynamic_characters = array('/\'(\d\d(?:’|\')?s)/', '/\'(\d)/', '/(\s|\A|[([{<]|")\'/', '/(\d)"/', '/(\d)\'/', '/(\S)\'([^\'\s])/', '/(\s|\A|[([{<])"(?!\s)/', '/"(\s|\S|\Z)/', '/\'([\s.]|\Z)/', '/\b(\d+)x(\d+)\b/');
$dynamic_replacements = array('’$1','’$1', '$1‘', '$1″', '$1′', '$1’$2', '$1' . $opening_quote . '$2', $closing_quote . '$1', '’$1', '$1×$2');
The last regex in that $dynamic_characters array is the one turning the "X" into ×
As stated on the function page for wptexturize... "[t]ext enclosed in the tags <pre>, <code>, <kbd>, <style>, <script>, <tt>, and [code] will be skipped.", you can fix this by putting that bbcode in one of those tags, or use a plugin that can disable wptexturize, such as InScript or Disabler or Disable wptexturize.

Categories