新鲜的WordPress在线商店插件

前一段时间,我需要在WordPress上创建在线商店。 官方存储库中有很多好的解决方案。 其中,领导者-Woocommerce早已脱颖而出。 我认为他不需要介绍。 数百万的用户大军,数百个付费和免费扩展程序以及令人难以置信的灵活性。 这就是Woocommerce拥有超过500万活跃安装并覆盖全球在线商店大部分的原因。

尽管如此,我还是决定发明我的自行车。 一方面是为了提高技能,另一方面是为了尝试制作一个非资源密集型且足够快的电子商务插件。 我最近将其发布在官方存储库中 ,因此,我邀请所有人对其进行测试。 在本文中,我不会对各种可能性进行概述,而只会谈论一些有趣的技术解决方案。



固定链接问题


通常,WordPress中的永久链接是最困难的网站之一,因为它们需要解决许多连接和依赖性问题。 WpStore具有管理永久链接的能力。 例如,您可以从product url中删除product ,更改为自己的product ,或者向其中添加类别信息甚至类别嵌套。 产品链接可能看起来像这样: ./-/---/---/-/ 。 还不错

为了使类别嵌套,我不得不大汗淋漓。 使用wp_get_object_terms,函数wp_get_object_terms,我们获得指定产品的类别,然后在循环中,我们收集弱点并根据从父级到子级的层次结构形成URL。 为了显示必要的链接,我们使用post_link过滤器。 这只是代码的一部分(您可以在源代码中看到完整的代码):

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

但是此时,出现了性能问题。 该站点的工作开始缓慢,特别是在几种产品的输出页面上。 例如,在仅输出16种产品的类别页面上,对数据库进行了近90个查询,服务器响应时间显着增加了25%至30%。

事实证明,当调用the_permalink函数时 WordPress执行许多操作:它获取CNC的类型并根据该类型收集发布数据。 为了显示1个链接,WordPress会向数据库生成多个未缓存的请求。 此外,获取商品分类和层次结构的过程并不是最快的。

由于不断生成的链接不适合我们,因此将其存储在某个位置然后从那里拉出来是合乎逻辑的。 决定使用guid表的特殊guid字段。 尽管WP开发人员不建议更改它,但出于以下几个原因,我们仍然可以忽略此警告:

  • guid用于生成RSS,很少有人使用它。
  • RSS中仅显示条目,而我们的帖子类型为product。

为了正确地将链接保留在数据库中,我们save_post挂起函数save_post来更新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 ); } } 

我们仍然需要拦截post_type_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; } 

在这里,我们检查引导字段,桩类型和CNC类型的完整性。 如果三个参数的值适合我们,则显示先前保存的链接。

现在,最好的部分是:查看结果。 对数据库的查询数量几乎减少了2倍-从几乎90个减少到44个! 测试主机上的服务器响应时间降至可接受的0.24秒。

更新guid字段不仅在创建和编辑商品期间发生。 该插件具有用于通过csv导入商品的内置系统,因此更新也将在导入完成时发生。

更新: 插件文档

Source: https://habr.com/ru/post/zh-CN467937/


All Articles