Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/Orders/Order/Shipping.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ private function set_shipping_rate() {
return;
}
$shipping_rate = ShoppingFeedHelper::get_wc_shipping_from_sf_carrier( $this->method );

/**
* Filter the shipping method data used when creating the shipping rates.
*
* @param array $shipping_rate the shipping method data.
* @param OrderResource $sf_order the ShoppingFeed order.
*/
$shipping_rate = apply_filters( 'shopping_feed_order_shipping_rate', $shipping_rate, $this->sf_order );

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Filter data type mismatch causes downstream errors.

The filter shopping_feed_order_shipping_rate allows external code to return non-array values that bypass the empty() check but cause errors when accessed as array keys later. If the filter returns a non-empty, non-array value (like a string or number), execution continues past line 111 but then fails at lines 124-131 when trying to access array keys like method_rate_id and method_title on a non-array value.

Fix in Cursor Fix in Web

if ( empty( $shipping_rate ) ) {
$shipping_rate = $default_shipping_method;
}
Expand Down
34 changes: 28 additions & 6 deletions src/ShoppingFeedHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,27 +56,49 @@ public static function get_wc_version() {
}

/**
* Return the feed's directory
* Return the feed's directory.
*
* @return string
*/
public static function get_feed_directory() {
return SF_FEED_DIR;
/**
* Filter the path to the directory where product feeds are stored.
*
* @param string $path Path to the directory.
*/
return (string) apply_filters( 'shopping_feed_feed_directory_path', SF_FEED_DIR );
}

/**
* Return the feed's parts directory
* Return the feed's parts directory.
*
* @return string
*/
public static function get_feed_parts_directory() {
return SF_FEED_PARTS_DIR;
/**
* Filter the path to the directory where product feeds parts are stored.
*
* @param string $path Path to the directory.
*/
return (string) apply_filters( 'shopping_feed_feed_parts_directory_path', SF_FEED_PARTS_DIR );
}

/**
* Return the feed's file name
* Return the feed's file name.
*
* The filename doesn't contain the file extension.
*
* @return string
*/
public static function get_feed_filename() {
return 'products';
/**
* Filter the product feed's filename.
*
* The filename must not contain the file extension.
*
* @param string $path Feed's filename.
*/
return (string) apply_filters( 'shopping_feed_feed_filename', 'products' );
}

/**
Expand Down
83 changes: 83 additions & 0 deletions tests/wpunit/Feed/HelperFunctionsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

namespace ShoppingFeed\ShoppingFeedWC\Tests\wpunit\Feed;

use ShoppingFeed\ShoppingFeedWC\ShoppingFeedHelper;

class HelperFunctionsTest extends \Codeception\TestCase\WPTestCase {

private static $upload_dir;

public static function setUpBeforeClass(): void {
self::$upload_dir = wp_upload_dir();
}

public function test_get_feed_directory() {
$this->assertEquals(
self::$upload_dir['basedir'] . '/shopping-feed',
ShoppingFeedHelper::get_feed_directory()
);
}

public function test_get_feed_directory_filter() {
$custom_feed_directory = '/tmp/shopping-feed';

add_filter(
'shopping_feed_feed_directory_path',
function ( $dir ) use ( $custom_feed_directory ) {
return $custom_feed_directory;
}
);

$this->assertEquals(
$custom_feed_directory,
ShoppingFeedHelper::get_feed_directory()
);
}

public function test_get_feed_part_directory() {
$this->assertEquals(
self::$upload_dir['basedir'] . '/shopping-feed/parts',
ShoppingFeedHelper::get_feed_parts_directory()
);
}

public function test_get_feed_part_directory_filter() {
$custom_feed_directory = '/tmp/shopping-feed-parts';

add_filter(
'shopping_feed_feed_parts_directory_path',
function ( $dir ) use ( $custom_feed_directory ) {
return $custom_feed_directory;
}
);

$this->assertEquals(
$custom_feed_directory,
ShoppingFeedHelper::get_feed_parts_directory()
);
}

public function test_get_feed_filename() {
$this->assertEquals(
'products',
ShoppingFeedHelper::get_feed_filename()
);
}

public function test_get_feed_filename_filter() {
$custom_feed_filename = 'custom-products';

add_filter(
'shopping_feed_feed_filename',
function ( $filename ) use ( $custom_feed_filename ) {
return $custom_feed_filename;
}
);

$this->assertEquals(
$custom_feed_filename,
ShoppingFeedHelper::get_feed_filename()
);
}
}
Loading