如何将 WC_Data_Store 转换为 WC_Product_Variable_Data_Store_CPT 或具有 $prices_array 属性的东西?

如何解决如何将 WC_Data_Store 转换为 WC_Product_Variable_Data_Store_CPT 或具有 $prices_array 属性的东西?

我必须执行以下反射代码,因为我可用的 WooCommerce 版本有一个错误 (v4.9.2)。

请查看下面代码中的注释:

// checked before the existence of the class with class_exists
$rp = new ReflectionProperty('WC_Product_Variable_Data_Store_CPT','prices_array');
$rp->setAccessible(true);
var_dump('start'); // echoes something to the html code
$protected_prices_array = $rp->getValue($ths); // crashes the PHP script instance
var_dump('stop'); // this is not printed anymore

如果需要,我可以提供更多代码。

目前我正在尝试继承给定的类,看看我是否可以解决这个错误。

在临时站点上,我有 PHP 7.4.16。

更新 1

我在自己的 function my_read_price_data( $ths,&$product,$for_display = false ) { ... 中有此代码,它与 WC 数据存储的 read_price_data 公共方法相同,该方法访问受保护的价格数组属性。

更新 2

/**
 * Modified function from WC.
 *
 * @param WC_Product_Variable_Data_Store_CPT $ths
 * @param WC_Product_Variable $product
 * @param boolean $for_display
 * @return void
 */
function my_read_price_data( $ths,$for_display = false ) {

  /**
   * Transient name for storing prices for this product (note: Max transient length is 45)
   *
   * @since 2.5.0 a single transient is used per product for all prices,rather than many transients per product.
   */
  $transient_name    = 'wc_var_prices_' . $product->get_id();
  $transient_version = WC_Cache_Helper::get_transient_version( 'product' );
  $price_hash = my_get_price_hash($ths,$product,$for_display); // with this it does not crash (*)

  // NOTE: maybe inherit from WC_Product_Variable_Data_Store_CPT to not use reflection.
  $rp = new ReflectionProperty('WC_Product_Variable_Data_Store_CPT','prices_array'); // the class exists
  $rp->setAccessible(true);
  var_dump('start');
  $protected_prices_array = $rp->getValue($ths);  // (*) until this
  var_dump('stop');

  // Check if prices array is stale.
  if ( ! isset( $protected_prices_array['version'] ) || $protected_prices_array['version'] !== $transient_version ) {
    $rp->setValue($ths,array(
      'version' => $transient_version,));
  }

  $protected_prices_array = $rp->getValue($ths); 

  /**
   * $this->prices_array is an array of values which may have been modified from what is stored in transients - this may not match $transient_cached_prices_array.
   * If the value has already been generated,we don't need to grab the values again so just return them. They are already filtered.
   */
  if ( empty( $protected_prices_array[ $price_hash ] ) ) {
    $transient_cached_prices_array = array_filter( (array) json_decode( strval( get_transient( $transient_name ) ),true ) );

    // If the product version has changed since the transient was last saved,reset the transient cache.
    if ( ! isset( $transient_cached_prices_array['version'] ) || $transient_version !== $transient_cached_prices_array['version'] ) {
      $transient_cached_prices_array = array(
        'version' => $transient_version,);
    }

    // If the prices are not stored for this hash,generate them and add to the transient.
    if ( empty( $transient_cached_prices_array[ $price_hash ] ) ) {
      $prices_array = array(
        'price'         => array(),'regular_price' => array(),'sale_price'    => array(),);

      $variation_ids = $product->get_visible_children();

      if ( is_callable( '_prime_post_caches' ) ) {
        _prime_post_caches( $variation_ids );
      }

      foreach ( $variation_ids as $variation_id ) {
        $variation = wc_get_product( $variation_id );

        if ( $variation ) {
          $price         = apply_filters( 'woocommerce_variation_prices_price',$variation->get_price( 'edit' ),$variation,$product );
          $regular_price = apply_filters( 'woocommerce_variation_prices_regular_price',$variation->get_regular_price( 'edit' ),$product );
          $sale_price    = apply_filters( 'woocommerce_variation_prices_sale_price',$variation->get_sale_price( 'edit' ),$product );

          // Skip empty prices.
          if ( '' === $price ) {
            continue;
          }

          // If sale price does not equal price,the product is not yet on sale.
          if ( $sale_price === $regular_price || $sale_price !== $price ) {
            $sale_price = $regular_price;
          }

          // If we are getting prices for display,we need to account for taxes.
          if ( $for_display ) {
            if ( 'incl' === get_option( 'woocommerce_tax_display_shop' ) ) {
              $price         = '' === $price ? '' : wc_get_price_including_tax(
                $variation,array(
                  'qty'   => 1,'price' => $price,)
              );
              $regular_price = '' === $regular_price ? '' : wc_get_price_including_tax(
                $variation,'price' => $regular_price,)
              );
              $sale_price    = '' === $sale_price ? '' : wc_get_price_including_tax(
                $variation,'price' => $sale_price,)
              );
            } else {
              $price         = '' === $price ? '' : wc_get_price_excluding_tax(
                $variation,)
              );
              $regular_price = '' === $regular_price ? '' : wc_get_price_excluding_tax(
                $variation,)
              );
              $sale_price    = '' === $sale_price ? '' : wc_get_price_excluding_tax(
                $variation,)
              );
            }
          }

          $prices_array['price'][ $variation_id ]         = wc_format_decimal( $price,wc_get_price_decimals() );
          $prices_array['regular_price'][ $variation_id ] = wc_format_decimal( $regular_price,wc_get_price_decimals() );
          $prices_array['sale_price'][ $variation_id ]    = wc_format_decimal( $sale_price,wc_get_price_decimals() );

          $prices_array = apply_filters( 'woocommerce_variation_prices_array',$prices_array,$for_display );
        }
      }

      // Add all pricing data to the transient array.
      foreach ( $prices_array as $key => $values ) {
        $transient_cached_prices_array[ $price_hash ][ $key ] = $values;
      }

      set_transient( $transient_name,wp_json_encode( $transient_cached_prices_array ),DAY_IN_SECONDS * 30 );
    }

    /**
     * Give plugins one last chance to filter the variation prices array which has been generated and store locally to the class.
     * This value may differ from the transient cache. It is filtered once before storing locally.
     */
    $protected_prices_array = $rp->getValue($ths);

    $protected_prices_array[$price_hash] = apply_filters( 'woocommerce_variation_prices',$transient_cached_prices_array[ $price_hash ],$for_display );

    $rp->setValue($ths,$protected_prices_array);
  }
  return $rp->getValue($ths)[ $price_hash ];
}

更新 3

上面的函数 my_read_price_data 被调用:

/**
 * Function modified from WC.
 *
 * @param WC_Product_Variable $p
 * @param boolean $for_display
 * @return void
 */
function my_get_variation_prices( $p,$for_display = false ) {
  $ds = $p->get_data_store(); // $p->data_store;
  $prices = my_read_price_data($ds,$p,$for_display);

  foreach ( $prices as $price_key => $variation_prices ) {
    $prices[ $price_key ] = asort( $variation_prices );
  }

  return $prices;
}

这是由以下函数调用的,该函数是 WC 函数的修改版本,但这次修改是为了将输出更改为客户端想要的内容:

function my_get_price_html( $price = '' ) {
  global $product;
  $prices = my_get_variation_prices($product,true);

  if ( empty( $prices['price'] ) ) {
    $price = apply_filters( 'woocommerce_variable_empty_price_html','',$product  );
  } else {
    $min_price     = current( $prices['price'] );
    $max_price     = end( $prices['price'] );
    $min_reg_price = current( $prices['regular_price'] );
    $max_reg_price = end( $prices['regular_price'] );

    if ( $min_price !== $max_price ) {
      $price = wc_format_price_range( $min_price,$max_price );
    } elseif ( $product->is_on_sale() && $min_reg_price === $max_reg_price ) {
      $price = my_wc_format_sale_price( $prices['regular_price'],$prices['price'] );
    } else {
      $price = wc_price( $min_price );
    }

    $price = apply_filters( 'woocommerce_variable_price_html',$price . $product->get_price_suffix(),$product );
  }

  return apply_filters( 'woocommerce_get_price_html',$price,$product );
}

正如你在上面看到的,我使用了 my_wc_format_sale_price,它在这里:

/**
 * Format a sale price for display.
 *
 * @since  3.0.0
 * @param  float $regular_price Regular price.
 * @param  float $sale_price    Sale price.
 * @return string
 */
function my_wc_format_sale_price( $regular_price,$sale_price ) {
    $price = '<span>' . get_my_percent($regular_price,$sale_price) . '</span> <ins>' . ( is_numeric( $sale_price ) ? wc_price( $sale_price ) : $sale_price ) . '</ins>';
    return apply_filters( 'woocommerce_format_sale_price',$regular_price,$sale_price );
}

我认为这是最后一个重要的函数(它有一个文档注释说它返回一个字符串):

function get_my_percent($regular_price,$sale_price) {
  $a = ($regular_price - $sale_price) / $regular_price * 100;
  return "$a% reducere";
}

更新 4

我通过 https://stackoverflow.com/a/21429652/258462 发现了以下内容。

提供给反射机制的对象似乎与预期类型不同。

来自 WooCommerce 4.9.2 的源代码:

/**
 * WC Variable Product Data Store: Stored in CPT.
 *
 * @version 3.0.0
 */
class WC_Product_Variable_Data_Store_CPT extends WC_Product_Data_Store_CPT implements WC_Object_Data_Store_Interface,WC_Product_Variable_Data_Store_Interface {

    /**
     * Cached & hashed prices array for child variations.
     *
     * @var array
     */
    protected $prices_array = array()

...

那么问题是如何将 WC_Data_Store 转换为具有 $prices_array 属性的内容?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res