Skip to content
Merged
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
22 changes: 22 additions & 0 deletions inc/models/class-broadcast.php
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,26 @@ public function set_status($status): void {

$this->status = $status;
}

/**
* Transform the object into an assoc array.
*
* Overrides Base_Model::to_array() to ensure lazy-loaded meta properties
* are populated before serialization so REST API responses include all fields.
*
* @since 2.0.11
* @return array
*/
public function to_array() {

// Only trigger lazy-loading when the model has been persisted (has an ID).
// For unsaved models (during validate/save), meta is not available and the
// getters return default values that can fail validation rules.
if ($this->get_id()) {
$this->get_migrated_from_id();
$this->get_notice_type();
}

return parent::to_array();
}
}
22 changes: 22 additions & 0 deletions inc/models/class-checkout-form.php
Original file line number Diff line number Diff line change
Expand Up @@ -1625,4 +1625,26 @@ public static function add_new_site_form_fields() {

return apply_filters('wu_checkout_form_add_new_site_form_fields', $steps);
}

/**
* Transform the object into an assoc array.
*
* Overrides Base_Model::to_array() to ensure lazy-loaded meta properties
* are populated before serialization so REST API responses include all fields.
*
* @since 2.0.11
* @return array
*/
public function to_array() {

// Only trigger lazy-loading when the model has been persisted (has an ID).
// For unsaved models (during validate/save), meta is not available and the
// getters return default values that can fail validation rules.
if ($this->get_id()) {
$this->get_thank_you_page_id();
$this->get_conversion_snippets();
}

return parent::to_array();
}
}
22 changes: 22 additions & 0 deletions inc/models/class-customer.php
Original file line number Diff line number Diff line change
Expand Up @@ -962,4 +962,26 @@ public function set_network_id($network_id): void {

$this->network_id = $network_id ? absint($network_id) : null;
}

/**
* Transform the object into an assoc array.
*
* Overrides Base_Model::to_array() to ensure lazy-loaded meta properties
* are populated before serialization so REST API responses include all fields.
*
* @since 2.0.11
* @return array
*/
public function to_array() {

// Only trigger lazy-loading when the model has been persisted (has an ID).
// For unsaved models (during validate/save), meta is not available and the
// getters return default values that can fail validation rules.
if ($this->get_id()) {
$this->has_trialed();
$this->get_extra_information();
}

return parent::to_array();
}
}
22 changes: 22 additions & 0 deletions inc/models/class-email.php
Original file line number Diff line number Diff line change
Expand Up @@ -818,4 +818,26 @@ public function set_legacy($legacy): void {

$this->meta[ self::META_LEGACY ] = $legacy;
}

/**
* Transform the object into an assoc array.
*
* Overrides Base_Model::to_array() to ensure lazy-loaded meta properties
* are populated before serialization so REST API responses include all fields.
*
* @since 2.0.11
* @return array
*/
public function to_array() {

// Only trigger lazy-loading when the model has been persisted (has an ID).
// For unsaved models (during validate/save), meta is not available and the
// getters return default values that can fail validation rules.
if ($this->get_id()) {
$this->get_event();
$this->has_schedule();
}

return parent::to_array();
}
}
22 changes: 22 additions & 0 deletions inc/models/class-payment.php
Original file line number Diff line number Diff line change
Expand Up @@ -1158,4 +1158,26 @@ public function duplicate() {

return $new_payment;
}

/**
* Transform the object into an assoc array.
*
* Overrides Base_Model::to_array() to ensure lazy-loaded meta properties
* are populated before serialization so REST API responses include all fields.
*
* @since 2.0.11
* @return array
*/
public function to_array() {

// Only trigger lazy-loading when the model has been persisted (has an ID).
// For unsaved models (during validate/save), meta is not available and the
// getters return default values that can fail validation rules.
if ($this->get_id()) {
$this->get_line_items();
$this->get_invoice_number();
}

return parent::to_array();
}
}
31 changes: 31 additions & 0 deletions inc/models/class-product.php
Original file line number Diff line number Diff line change
Expand Up @@ -1586,6 +1586,37 @@ public function get_price_variation($duration, $duration_unit) {
return apply_filters('wu_product_get_price_variation', $price_variation, $duration, $duration_unit, $this);
}

/**
* Transform the object into an assoc array.
*
* Overrides Base_Model::to_array() to ensure lazy-loaded meta properties
* are populated before serialization so REST API responses include all fields.
*
* @since 2.0.11
* @return array
*/
public function to_array() {

// Only trigger lazy-loading when the model has been persisted (has an ID).
// For unsaved models (during validate/save), meta is not available and the
// getters return default values (e.g. false) that can fail validation rules
// like 'integer', preventing the model from being saved at all.
if ($this->get_id()) {
$this->get_featured_image_id();
$this->get_tax_category();
$this->get_contact_us_label();
$this->get_contact_us_link();
$this->get_feature_list();
$this->get_available_addons();
$this->get_legacy_options();
$this->get_pwyw_minimum_amount();
$this->get_pwyw_suggested_amount();
$this->get_pwyw_recurring_mode();
}

return parent::to_array();
}

/**
* Save (create or update) the model on the database.
*
Expand Down
35 changes: 35 additions & 0 deletions inc/models/class-site.php
Original file line number Diff line number Diff line change
Expand Up @@ -1696,6 +1696,41 @@ function ($replace_list, $from_site_id, $to_site_id) use ($transient) { // phpcs
}
}

/**
* Transform the object into an assoc array.
*
* Overrides Base_Model::to_array() to ensure lazy-loaded meta properties
* are populated before serialization. Without this, properties such as
* customer_id, membership_id, type, active, etc. remain null in REST API
* responses because get_object_vars() captures the raw (unloaded) values.
*
* @since 2.0.11
* @return array
*/
public function to_array() {

// Only trigger lazy-loading when the model has been persisted (has an ID).
// For unsaved models (during validate/save), meta is not available and the
// getters return default values (e.g. false) that can fail validation rules
// like 'integer', preventing the model from being saved at all.
if ($this->get_id()) {
$this->get_customer_id();
$this->get_membership_id();
$this->get_template_id();
$this->get_featured_image_id();
$this->get_categories();
$this->get_type();
$this->is_active();
}

$array = parent::to_array();

// Expose blog_id as id so callers get the correct non-zero value.
$array['id'] = $this->get_id();

return $array;
}

/**
* Save (create or update) the model on the database.
*
Expand Down
23 changes: 23 additions & 0 deletions tests/WP_Ultimo/Models/Broadcast_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -301,4 +301,27 @@ public function test_query_class(): void {

$this->assertEquals(\WP_Ultimo\Database\Broadcasts\Broadcast_Query::class, $query_class);
}

/**
* Test that to_array() populates lazy-loaded meta properties (issue #469).
*
* migrated_from_id and notice_type are only loaded from meta when their
* getter is first called. Without the to_array() override they remain null.
*/
public function test_to_array_includes_lazy_loaded_meta_properties(): void {
$broadcast = new \WP_Ultimo\Models\Broadcast();
$broadcast->set_type('broadcast_notice');
$broadcast->set_notice_type('warning');
$broadcast->set_migrated_from_id(99);

$array = $broadcast->to_array();

$this->assertIsArray($array, 'to_array() should return an array.');
$this->assertArrayHasKey('notice_type', $array, 'to_array() must include notice_type.');
$this->assertNotNull($array['notice_type'], 'notice_type must not be null in to_array() output.');
$this->assertEquals('warning', $array['notice_type'], 'notice_type must match the set value.');
$this->assertArrayHasKey('migrated_from_id', $array, 'to_array() must include migrated_from_id.');
$this->assertNotNull($array['migrated_from_id'], 'migrated_from_id must not be null in to_array() output.');
$this->assertEquals(99, $array['migrated_from_id'], 'migrated_from_id must match the set value.');
}
}
23 changes: 23 additions & 0 deletions tests/WP_Ultimo/Models/Checkout_Form_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -2195,4 +2195,27 @@ public function test_get_field_returns_extra_attributes(): void {
$this->assertEquals('you@example.com', $field['placeholder']);
$this->assertEquals('Enter your email', $field['tooltip']);
}

/**
* Test that to_array() populates lazy-loaded meta properties (issue #469).
*
* thank_you_page_id and conversion_snippets are only loaded from meta when
* their getter is first called. Without the to_array() override they remain null.
*/
public function test_to_array_includes_lazy_loaded_meta_properties(): void {
$form = new \WP_Ultimo\Models\Checkout_Form();
$form->set_name('Test Form');
$form->set_slug('test-form');
$form->set_thank_you_page_id(42);
$form->set_conversion_snippets('<script>ga("send","event")</script>');

$array = $form->to_array();

$this->assertIsArray($array, 'to_array() should return an array.');
$this->assertArrayHasKey('thank_you_page_id', $array, 'to_array() must include thank_you_page_id.');
$this->assertNotNull($array['thank_you_page_id'], 'thank_you_page_id must not be null in to_array() output.');
$this->assertEquals(42, $array['thank_you_page_id'], 'thank_you_page_id must match the set value.');
$this->assertArrayHasKey('conversion_snippets', $array, 'to_array() must include conversion_snippets.');
$this->assertNotNull($array['conversion_snippets'], 'conversion_snippets must not be null in to_array() output.');
}
}
26 changes: 26 additions & 0 deletions tests/WP_Ultimo/Models/Customer_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -403,4 +403,30 @@ public function tearDown(): void {

parent::tearDown();
}

/**
* Test that to_array() populates lazy-loaded meta properties (issue #469).
*
* has_trialed and extra_information are only loaded from meta when their
* getter is first called. Without the to_array() override they remain null.
*/
public function test_to_array_includes_lazy_loaded_meta_properties(): void {
$user_id = self::factory()->user->create(['user_email' => 'lazy@example.com']);

$customer = new Customer();
$customer->set_user_id($user_id);
$customer->set_type('customer');
$customer->set_email_verification('none');
$customer->set_date_registered('2023-01-01 00:00:00');
$customer->set_has_trialed(false);
$customer->set_extra_information(['key' => 'value']);

$array = $customer->to_array();

$this->assertIsArray($array, 'to_array() should return an array.');
$this->assertArrayHasKey('has_trialed', $array, 'to_array() must include has_trialed.');
$this->assertNotNull($array['has_trialed'], 'has_trialed must not be null in to_array() output.');
$this->assertArrayHasKey('extra_information', $array, 'to_array() must include extra_information.');
$this->assertNotNull($array['extra_information'], 'extra_information must not be null in to_array() output.');
}
}
22 changes: 22 additions & 0 deletions tests/WP_Ultimo/Models/Email_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -1740,4 +1740,26 @@ public function tearDown(): void {
parent::tearDown();
}

/**
* Test that to_array() populates lazy-loaded meta properties (issue #469).
*
* event and schedule are only loaded from meta when their getter is first
* called. Without the to_array() override they remain null.
*/
public function test_to_array_includes_lazy_loaded_meta_properties(): void {
$email = new \WP_Ultimo\Models\Email();
$email->set_slug('test-email');
$email->set_event('user_registration');
$email->set_schedule(true);

$array = $email->to_array();

$this->assertIsArray($array, 'to_array() should return an array.');
$this->assertArrayHasKey('event', $array, 'to_array() must include event.');
$this->assertNotNull($array['event'], 'event must not be null in to_array() output.');
$this->assertEquals('user_registration', $array['event'], 'event must match the set value.');
$this->assertArrayHasKey('schedule', $array, 'to_array() must include schedule.');
$this->assertNotNull($array['schedule'], 'schedule must not be null in to_array() output.');
}

}
23 changes: 23 additions & 0 deletions tests/WP_Ultimo/Models/Payment_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -1577,4 +1577,27 @@ public static function tear_down_after_class() {
$wpdb->query("TRUNCATE TABLE {$wpdb->prefix}wu_payments");
parent::tear_down_after_class();
}

/**
* Test that to_array() populates lazy-loaded meta properties (issue #469).
*
* line_items and invoice_number are only loaded from meta when their
* getter is first called. Without the to_array() override they remain null.
*/
public function test_to_array_includes_lazy_loaded_meta_properties(): void {
$payment = new \WP_Ultimo\Models\Payment();
$payment->set_status('pending');
$payment->set_currency('USD');
$payment->set_subtotal(100);
$payment->set_total(100);
$payment->set_invoice_number('INV-001');

$array = $payment->to_array();

$this->assertIsArray($array, 'to_array() should return an array.');
$this->assertArrayHasKey('line_items', $array, 'to_array() must include line_items.');
$this->assertArrayHasKey('invoice_number', $array, 'to_array() must include invoice_number.');
$this->assertNotNull($array['invoice_number'], 'invoice_number must not be null in to_array() output.');
$this->assertEquals('INV-001', $array['invoice_number'], 'invoice_number must match the set value.');
}
}
Loading
Loading