Some time ago I needed to create an online store on WordPress.  There are many good solutions in the official repository.  Among them, the leader - Woocommerce has long stood out.  I think he does not need an introduction.  A multimillion army of users, hundreds of paid and free extensions and incredible flexibility.  This is why Woocommerce has over 5 million active installations and covers a large share of online stores worldwide. 
      
        
        
        
      
    
      
        
        
        
      
      Still, I decided to invent my bike.  Partly, to upgrade skills, partly to try to make a non-resource-intensive and fast enough ecommerce plugin.  I recently posted it 
in the official repository , therefore, I invite everyone to test it.  In this article I will not do an overview of the possibilities, but I will only talk about some interesting technical solutions. 
      
        
        
        
      
    
      
        
        
        
      
     
      
        
        
        
      
    
      
        
        
        
      
      Permalinks Problem 
      
        
        
        
      
      In general, permalinks in WordPress are one of the most difficult sites, as they require solving a number of problems of connections and dependencies.  WpStore has the ability to manage permalinks.  For example, you can remove the 
product
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     slug from the 
product
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     url, change to your own or add the category slug or even category nesting to it.  Links to products may look like this: 
./-/---/---/-/
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     .  Not bad. 
      
        
        
        
      
    
      
        
        
        
      
      I had to sweat a lot to get categories nesting.  Using the 
wp_get_object_terms,
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     function 
wp_get_object_terms,
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     we obtain the categories of the specified product, and then in the cycle we collect the weaknesses and form the url hierarchy from parent to child.  To display the necessary links we use the post_link filter.  Here is just part of the code (you can see the full code in the source): 
      
        
        
        
      
    
      
        
        
        
      
     add_filter( 'post_link', 'wpsl_post_type_permalink', 20, 3 ); add_filter( 'post_type_link', 'wpsl_post_type_permalink', 20, 3 ); function wpsl_post_type_permalink( $permalink, $post_id, $leavename ) { ....  if ( is_admin() ) { 
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
 
      
        
        
        
      
      But at this point, a performance problem arose.  The site began to work more slowly, especially on the output page of several products.  For example, on the category page with the output of only 16 products, almost 90 queries were made to the database and the server response time increased dramatically by about 25-30%. 
      
        
        
        
      
    
      
        
        
        
      
      It turned out that when calling 
the_permalink function 
, WordPress performs many operations: it gets the type of CNC and collects the 
post data depending on this type.  To display 1 link WordPress produces several non-cached requests to the database.  Moreover, the process of obtaining taxonomies and hierarchies of goods is not the fastest. 
      
        
        
        
      
    
      
        
        
        
      
      Since the constant generation of the link does not suit us, it is logical to store it somewhere and then just pull it from there.  It was decided to use the special 
guid
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     field of the 
guid
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     table.  Although WP developers do not recommend changing it, we can still ignore this warning for several reasons: 
      
        
        
        
      
    
      
        
        
        
      
    -   guid is used to generate RSS, and few people use it. 
-   only entries are displayed in RSS, and our post type is product. 
      In order to keep the links in the database correctly, we 
save_post
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     function on the 
save_post
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     event that updates the guid field: 
      
        
        
        
      
    
      
        
        
        
      
     add_action( 'save_post', 'wpsl_guid_rewrite', 100 ); function wpsl_guid_rewrite( $id ) { if( !is_admin() ) return; if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return false; if ( strpos( get_option( 'product_permalink' ), '%category%' ) !== false || strpos( get_option( 'product_permalink' ), '%categories%' ) !== false ) { if( $id && get_post_type( (int)$id ) == 'product' ){ global $wpdb; $wpdb->update( $wpdb->posts, [ 'guid' => ( get_permalink( $id ) ) ], [ 'ID' => intval( $id ) ] ); } clean_post_cache( $id ); } }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
 
      
        
        
        
      
      We 
post_type_link
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     have to intercept the output of the link on the 
post_type_link
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     hook and output the generated link: 
      
        
        
        
      
    
      
        
        
        
      
     add_filter( 'post_type_link', 'wpsl_get_permalink_change', 10, 4 ); function wpsl_get_permalink_change( $post_link, $post, $leavename, $sample ){ if ( isset( $post->guid ) && $post->guid && $post->post_type == 'product' && ( strpos( get_option( 'product_permalink' ), '%category%' ) !== false || strpos( get_option( 'product_permalink' ), '%categories%' ) !== false ) ) { return $post->guid; } return $post_link; }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
 
      
        
        
        
      
      Here we check the completeness of the guid field, post type and CNC type.  If the values โโof the three parameters suit us, display the previously saved link. 
      
        
        
        
      
    
      
        
        
        
      
      Now, the best part is: look at the results.  The number of queries to the database decreased by almost 2 times - from almost 90 to 44!  And the server response time on the test hosting dropped to an acceptable 0.24 seconds. 
      
        
        
        
      
    
      
        
        
        
      
      Updating the guid field occurs not only during the creation and editing of goods.  The plugin has a built-in system for importing goods through csv, so the update also occurs when the import is complete. 
      
        
        
        
      
    
      
        
        
        
      
      Update: 
plugin documentation