Nouveau plugin de boutique en ligne WordPress

Il y a quelque temps, j'avais besoin de créer une boutique en ligne sur WordPress. Il existe de nombreuses bonnes solutions dans le référentiel officiel. Parmi eux, le leader - Woocommerce se distingue depuis longtemps. Je pense qu'il n'a pas besoin de présentation. Une armée de plusieurs millions d'utilisateurs, des centaines d'extensions payantes et gratuites et une flexibilité incroyable. C'est pourquoi Woocommerce compte plus de 5 millions d'installations actives et couvre une grande partie des magasins en ligne dans le monde.

Pourtant, j'ai décidé d'inventer mon vélo. En partie pour pomper les compétences, en partie pour essayer de créer un plugin de commerce électronique non gourmand en ressources et assez rapide. Je l'ai récemment posté dans le dépôt officiel , donc j'invite tout le monde à le tester. Dans cet article, je ne ferai pas un aperçu des possibilités, mais je ne parlerai que de quelques solutions techniques intéressantes.



Problème de permaliens


En général, les permaliens dans WordPress sont l'un des sites les plus difficiles, car ils nécessitent de résoudre un certain nombre de problèmes de connexions et de dépendances. WpStore a la capacité de gérer les permaliens. Par exemple, vous pouvez supprimer le slug du product URL du product , passer au vôtre ou lui ajouter le slug de catégorie ou même l'imbrication de catégorie. Les liens vers les produits peuvent ressembler à ceci: ./-/---/---/-/ . Pas mal.

J'ai dû beaucoup transpirer pour que les catégories s'emboîtent. En utilisant la fonction wp_get_object_terms, nous obtenons les catégories du produit spécifié, puis dans le cycle nous collectons les faiblesses et formons l'url selon la hiérarchie du parent à l'enfant. Pour afficher les liens nécessaires, nous utilisons le filtre post_link. Voici juste une partie du code (vous pouvez voir le code complet dans la 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 ) { .... /** * Works only in the admin panel when changing the structure of permanent links or creating/updating the product * In the frontend to display links to products using $post->guid * Relevant if the structure of permalinks are used %category% or %categories% */ if ( is_admin() ) { // get all terms (product categories) of this post (product) by hierarchicaly // change %category% if ( strpos( get_option( 'product_permalink' ), '%category%' ) !== false && $terms = wpsl_get_terms_hierarchicaly( $post->ID, 'product_cat' ) ) { $custom_slug = str_replace( '%category%', isset( $terms[0] ) && is_object( $terms[0] ) ? $terms[0]->slug : '', $custom_slug ); } // change %categories% if ( strpos( get_option( 'product_permalink' ), '%categories%' ) !== false && $terms = wpsl_get_terms_hierarchicaly( $post->ID, 'product_cat' ) ) { foreach( $terms as $term ) { $hierarchical_slugs[] = $term->slug; } $custom_slug = str_replace( '%categories%', implode( '/', $hierarchical_slugs ), $custom_slug ); } else { $custom_slug = str_replace( '%categories%', 'product', $custom_slug ); } } .... return $permalink; } 

Mais à ce stade, un problème de performances est survenu. Le site a commencé à fonctionner plus lentement, en particulier sur la page de sortie de plusieurs produits. Par exemple, sur la page de catégorie avec la sortie de seulement 16 produits, près de 90 requêtes ont été faites à la base de données et le temps de réponse du serveur a augmenté considérablement d'environ 25-30%.

Il s'est avéré que lors de l'appel de la fonction_permalink , WordPress effectue de nombreuses opérations: il obtient le type de CNC et collecte les données de publication en fonction de ce type. Pour afficher 1 lien, WordPress génère plusieurs requêtes non mises en cache vers la base de données. De plus, le processus d'obtention de taxonomies et de hiérarchies de biens n'est pas le plus rapide.

Étant donné que la génération constante du lien ne nous convient pas, il est logique de le stocker quelque part, puis de le retirer de là. Il a été décidé d'utiliser le champ guid spécial de la table guid . Bien que les développeurs WP ne recommandent pas de le modifier, nous pouvons toujours ignorer cet avertissement pour plusieurs raisons:

  • guid est utilisé pour générer des flux RSS, et peu de gens l'utilisent.
  • seules les entrées sont affichées en RSS, et notre type de publication est produit.

Afin de conserver correctement les liens dans la base de données, nous accrocherons à l'événement save_post une fonction qui met à jour le champ guid:

 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 ); } } 

Il nous reste à intercepter la sortie du lien sur le hook post_type_link et à sortir le lien généré:

 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; } 

Ici, nous vérifions l'exhaustivité du champ guid, du type de poste et du type CNC. Si les valeurs des trois paramètres nous conviennent, affichez le lien précédemment enregistré.

Maintenant, la meilleure partie est: regardez les résultats. Le nombre de requêtes vers la base de données a diminué de près de 2 fois, passant de près de 90 à 44! Et le temps de réponse du serveur sur l'hébergement de test est tombé à 0,24 seconde acceptable.

La mise à jour du champ GUID se produit non seulement lors de la création et de la modification des marchandises. Le plug-in a un système intégré pour importer des marchandises via csv, donc la mise à jour se produit également lorsque l'importation est terminée.

Mise à jour: documentation du plugin

Source: https://habr.com/ru/post/fr467937/


All Articles