• Hello guys!

    I have a problem, which I need some help to solve.
    Okay – here goes the explanation:

    – I have a customer, who has a shop plugin and a custom post type called “dictionary”. The problem is, when you go to an shop-item, it shows up fine – the link looks like this:

    “www.mysite.com/shoes/sneakers/vans/vans-s-3”

    Thats okay.. But there’s a problem here… I can change “shoes” and “sneakers” to whatever I want, and it will STILL show me the correct product(!)

    While products are working (somewhat working) – dictionary is more problematic.
    When I add a word in the dictionary, it shows the url:

    “www.mysite.com/ord/hello”

    When I visit this URL – nothing comes up – I get an 404-page.
    BUT! If i go to the backend, and update the post, then I can visit the exact same URL, and it’s working!

    I’ve narrowed it down to this function:

    add_action( 'generate_rewrite_rules', 'register_product_rewrite_rules' );
    function register_product_rewrite_rules( $wp_rewrite ) {
    
    	$new_rules = array(
    		'([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/page/(\d{1,})/?$' => 'index.php?name=' . $wp_rewrite->preg_index( 5 ) . '&paged=' . $wp_rewrite->preg_index( 6 ),
    		'([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$'               => 'index.php?name=' . $wp_rewrite->preg_index( 5 ),
    		'([^/]+)/([^/]+)/([^/]+)/([^/]+)/page/(\d{1,})/?$'         => 'index.php?name=' . $wp_rewrite->preg_index( 4 ) . '&paged=' . $wp_rewrite->preg_index( 5 ),
    		'([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$'                       => 'index.php?name=' . $wp_rewrite->preg_index( 4 ),
    		'([^/]+)/([^/]+)/([^/]+)/page/(\d{1,})/?$'                 => 'index.php?name=' . $wp_rewrite->preg_index( 3 ) . '&paged=' . $wp_rewrite->preg_index( 4 ),
    		'([^/]+)/([^/]+)/([^/]+)/?$'                               => 'index.php?name=' . $wp_rewrite->preg_index( 3 ),
    		'([^/]+)/([^/]+)/page/(\d{1,})/?$'                         => 'index.php?name=' . $wp_rewrite->preg_index( 2 ) . '&paged=' . $wp_rewrite->preg_index( 3 ),
    		'([^/]+)/([^/]+)/?$'                                       => 'index.php?name=' . $wp_rewrite->preg_index( 2 ),
    		'([^/]+)/([^/]+)/([^/]+)/'                                 => 'index.php?name=' . $wp_rewrite->preg_index( 2 )
    	);
    
    	$wp_rewrite->rules = $new_rules+$wp_rewrite->rules;
    
    }

    To summarize in short:

    – Products are working – but I can change some of the URL as I want
    – Dictionary is NOT working, unless I update the post

    If I disable/remove this function, dictionary is working fine – but then products are not working at all… Please help me – I’m so lost right now…

    Best regards
    Aris Kuckovic

Viewing 7 replies - 1 through 7 (of 7 total)
  • Moderator t-p

    (@t-p)

    I have a customer, who has a shop plugin and

    – What’s the full name of this plugin?
    – Downloaded from?

    Thread Starter kuckovic

    (@kuckovic)

    Hi @t-p

    Thanks for your quick reply.
    It’s a custom made shop plugin – but we’ve narrowed it down to the function I posted above.

    It’s really hard to understamd what they’re thinking. Especially when they don’t work there anymore.

    Moderator bcworkz

    (@bcworkz)

    Be sure you visit the permalinks setting screen when you make rewrite changes. It sounds like you’ve been doing so, but it’s worth mentioning anyway.

    That’s not the best way to add rewrite rules. Your dictionary request is captured by one of the product rules before the proper rule is reached. I hate to perpetuate bad practice, but not doing so will probably break the product rewrites. Identify the dictionary rewrite rule. Make a similar function like the product’s, but hook ‘generate_rewrite_rules’ with a larger priority so your dictionary rule is added to the top last. It’ll then be captured before the product rules are checked.

    Thread Starter kuckovic

    (@kuckovic)

    Hi @bcworkz,

    I have been doing so – and I appreciate you mentioning it anyways.

    I know it’s not the best – the plugin has been developed by a group of developers who are not longer a part of the company. I’m here to fix their ….. work..

    Okay, makes sense regarding the dictionary-function with a higher priority, I will try this tomorrow as the first thing. Now, what about the product “categories” – I can change them to whatever I like, and it will still be able to find the product?

    I’m sorry for all these questions, but I have read so much of their code – and corrected so many errors – now I’m just getting stuck.

    Best regards
    Aris Kuckovic

    Moderator bcworkz

    (@bcworkz)

    You have my sympathy, taking over others work can be endlessly frustrating. I had a clear sense those rewrite rules were not your doing. Besides bypassing the Rewrite API, those are very “grabby” rules to be putting on top. They will match practically any permalink, rewriting before proper rules have a chance.

    The relativity of priority is easily misinterpreted. Conceptually, a “higher” priority is of course what we want. When passing a priority argument to an action hook, we could think a priority of 1 is the highest priority. While it does mean your callback is called before others, it often does not have the desired effect. In this case we want to have the final say, so our callback should execute last. Thus a large priority is actually the proper argument. Priority of 20 is probably adequate, but some devs will do 9999 or even PHP_INT_MAX

    It can be useful to examine the final rewrite rule list in order to analyze why certain requests are misdirected. They are all stored in the global $wp_rewrite I’m not sure where/when the global is finalized and used to handle requests. Var_dumping $wp_rewrite from the “init” action should be plenty late enough. WP basically steps through the list until a match is found. It takes first match, not “best” match.

    I’m not sure I am following your intent with product categories. I think you want to change the taxonomy references in some way and want to be sure the shop category functions will still work. It’s hard to say. It depends on what you actually change and what the product queries use to reference category terms. Changing the taxonomy slug will likely fail in several ways, but even that is not a given. If you simply change the labels, there is a better chance of things working. Still not a given though. All I can suggest is give it a try, then test thoroughly. Naturally, keep a backup on the chance you will need to revert.

    No need to apologize for all the questions, it’s what these forums are for and the reason many here take the time to read topics. If anyone is bothered by all the questions, they don’t need to respond ??

    Thread Starter kuckovic

    (@kuckovic)

    Hi @bcworkz,

    I managed to make dictionary work, by creating a similar function, but higher priority.
    It hurts my eyes to look at this coding.

    Now – I have an issue regarding the products.
    One of my products has following URL:

    https://mywebsite.com/shoes/sneakers/vans/vans-s

    Now, I can change that to:

    https://mywebsite.com/lalalala/lolololoolo/foo/vans-s

    And I will still see the “vans-s” shoes product-page?
    I guess it’s because the RegEx matches the “vans-s” part, and ignores everyting else completely! Do you know a way around this? Really annoying!

    Thank you so much for the help so far!

    Best regards
    Aris Kuckovic

    Moderator bcworkz

    (@bcworkz)

    Yes, that’s the default WP behavior. If a matching slug is found for a single post, that post is returned regardless of anything else occurring before in the URL. An important caveat is the terms occurring before must have no meaning to the parser. For example, if you requested example.com/lalalala/2020/vans-s/, WP will recognize 2020 as a date term and try to query post_name = ‘vans-s’ AND post_date = ‘2020’. Unless the date matches that of the post, nothing will be returned even though the vans-s is a recognized post slug.

    It’s possible the shoes, sneakers, vans terms were picked up by the parser. As long as they actually relate to the post, all is well. If you requested /nike/vans-s and IF nike was recognized as a taxonomy term, but is not assigned to vans-s, WP will return nothing found. Whether nike is recognized as a taxonomy term or not depends on which rewrite rule was applied.

    Because the post slug is all WP needs to return the correct single post, anything else you choose to put in front of that term is mainly for human and SEO readability purposes. WP doesn’t need them and can sometimes be confused by them.

    I’m not sure what you are trying to workaround. I think you want something like /foobar/vans-s to return nothing instead of vans-s. For that to happen, foobar would need to be identified as a valid taxonomy term. To be valid, it has to be in the DB. Invalid terms are ignored. Even if foobar was a valid term, though not applied to vans-s, the correct rewrite rule would need to be applied. With ‘grabby’ rules like those inserted by the code in your OP, getting to the desired rewrite rule can be a challenge.

    Probably one way to get closer to a workaround is to use fixed base terms in the URL so there is less ambiguity. Something like example.com/brand/vans/model/vans-s where brand and model always exist and the rewrite rule RegExp specifically requires these base terms to make a match. But if the request matches one of those grabby rules first, the use of base terms still won’t help.

    Another possibility would be to pass terms as URL query args. As in example.com/vans-s?apparel=shoes&style=sneakers&brand=vans. This largely bypasses the rewrite rules. The query args need to be whitelisted in order to show up as WP_Query query args. As query args, they are added to the SQL WHERE clause and they all must match for the query to return anything. WP cannot ignore these kind of arguments. Clearly not SEO or human friendly, though at least Google Search Console will let you specify custom query args that GoogleBot will be able to understand. Meaningless for other search engine spiders.

Viewing 7 replies - 1 through 7 (of 7 total)
  • The topic ‘Problems with $wp_rewrite’ is closed to new replies.