diff --git a/src/class-convertkit-resource-v4.php b/src/class-convertkit-resource-v4.php index 95a9d2a..9a56a48 100644 --- a/src/class-convertkit-resource-v4.php +++ b/src/class-convertkit-resource-v4.php @@ -181,15 +181,15 @@ public function get_by_id( $id ) { */ public function get_by( $key, $value ) { - // Don't mutate the underlying resources, so multiple calls to get() - // with different order_by and order properties are supported. - $resources = $this->resources; - // Don't attempt sorting if no resources exist. if ( ! $this->exist() ) { - return $resources; + return false; } + // Don't mutate the underlying resources, so multiple calls to get() + // with different order_by and order properties are supported. + $resources = $this->resources; + foreach ( $resources as $id => $resource ) { // Remove this resource if it doesn't have the array key. if ( ! array_key_exists( $key, $resource ) ) { @@ -332,6 +332,21 @@ public function exist() { return false; } + // If the resources are not an array, no resources exist. + if ( ! is_array( $this->resources ) ) { + return false; + } + + // Ignore cached resources stored in the options table if they are a flat array + // that originates from between 1.6.0 and 1.9.5.2 of the Plugin + // i.e. [id => name], rather than [id => [id => '...', name => '...', ...]]. + // The Plugin's upgrade routine must handle converting the flat array to the new array format, but the + // resource classes are typically loaded before this happens, so this check is necessary to avoid + // fatal errors when a user upgrades from 1.6.0...1.9.5.2 to 1.9.6 or higher. + if ( ! is_array( reset( $this->resources ) ) ) { + return false; + } + return ( count( $this->resources ) ? true : false ); } diff --git a/tests/Integration/ResourceTest.php b/tests/Integration/ResourceTest.php index 78e8f70..08b0f4e 100644 --- a/tests/Integration/ResourceTest.php +++ b/tests/Integration/ResourceTest.php @@ -258,6 +258,34 @@ public function testGetByMultipleValues() $this->assertEquals('Z Name', end($result)[ $this->resource->order_by ]); } + /** + * Tests that the get_by() function returns false when queried with invalid resource data. + * + * @since 2.1.6 + */ + public function testGetByWithInvalidResourceData() + { + // Mock invalid resource data. + $this->mockInvalidData(); + + // Assert result is false. + $this->assertFalse($this->resource->get_by('name', 'Z Name')); + } + + /** + * Tests that the exist() function returns false when queried with invalid resource data. + * + * @since 2.1.6 + */ + public function testExistWithInvalidResourceData() + { + // Mock invalid resource data. + $this->mockInvalidData(); + + // Assert result is false. + $this->assertFalse($this->resource->exist()); + } + /** * Tests that the refresh() function for Forms returns resources in an array, and that they are * in alphabetical ascending order by default. @@ -669,4 +697,16 @@ private function mockData() ], ]; } + + /** + * Defines an array of resources when mocking invalid resource data in tests. + * + * @since 2.1.6 + */ + private function mockInvalidData() + { + $this->resource->resources = [ + 2780977 => 'Resource', + ]; + } }