post_type !== 'easy_invoice_payment') { throw new \Exception('Invalid payment post'); } $this->id = $post->ID; $this->loadMeta(); } /** * Load payment meta data */ private function loadMeta() { $this->data = array( 'invoice_id' => get_post_meta($this->id, '_invoice_id', true), 'amount' => get_post_meta($this->id, '_amount', true), 'payment_method' => get_post_meta($this->id, '_payment_method', true), 'status' => get_post_meta($this->id, '_status', true), 'transaction_id' => get_post_meta($this->id, '_transaction_id', true), 'payment_date' => get_post_meta($this->id, '_payment_date', true), 'notes' => get_post_meta($this->id, '_notes', true), 'payment_type' => get_post_meta($this->id, '_payment_type', true), 'recurring_id' => get_post_meta($this->id, '_recurring_id', true), 'parent_payment_id' => get_post_meta($this->id, '_parent_payment_id', true), 'gateway_response' => get_post_meta($this->id, '_gateway_response', true), 'currency' => get_post_meta($this->id, '_currency', true), 'currency_symbol' => get_post_meta($this->id, '_currency_symbol', true), ); } /** * Magic getter for dynamic properties * * @param string $name * @return mixed */ public function __get($name) { if (isset($this->data[$name])) { return $this->data[$name]; } return null; } /** * Magic setter for dynamic properties * * @param string $name * @param mixed $value */ public function __set($name, $value) { $this->data[$name] = $value; $this->is_modified = true; } /** * Magic isset for dynamic properties * * @param string $name * @return bool */ public function __isset($name) { return isset($this->data[$name]); } /** * Magic unset for dynamic properties * * @param string $name */ public function __unset($name) { unset($this->data[$name]); $this->is_modified = true; } /** * Dynamic getter method * * @since 1.0.0 * @param string $name Method name * @param array $arguments Method arguments * @return mixed */ public function __call($name, $arguments) { // Handle getter methods (getFieldName) if (strpos($name, 'get') === 0) { $field_name = $this->camelCaseToSnakeCase(substr($name, 3)); // Remove 'get' prefix return $this->__get($field_name); } // Handle setter methods (setFieldName) if (strpos($name, 'set') === 0) { $field_name = $this->camelCaseToSnakeCase(substr($name, 3)); // Remove 'set' prefix $value = $arguments[0] ?? null; $this->__set($field_name, $value); return null; } // Handle isset methods (isFieldName) if (strpos($name, 'is') === 0) { $field_name = $this->camelCaseToSnakeCase(substr($name, 2)); // Remove 'is' prefix return (bool) $this->__get($field_name); } // Handle has methods (hasFieldName) if (strpos($name, 'has') === 0) { $field_name = $this->camelCaseToSnakeCase(substr($name, 3)); // Remove 'has' prefix return !empty($this->__get($field_name)); } throw new \BadMethodCallException("Method $name does not exist"); } /** * Convert camelCase to snake_case * * @since 1.0.0 * @param string $camelCase * @return string */ private function camelCaseToSnakeCase($camelCase) { return strtolower(preg_replace('/(?id; } public function isModified(): bool { return $this->is_modified; } public function toArray(): array { return array_merge(['id' => $this->id], $this->data); } /** * Check if payment exists * * @return bool */ public function exists(): bool { return $this->id > 0 && get_post($this->id) !== null; } /** * Update payment data * * @param array $data Payment data to update * @return bool True on success, false on failure */ public function update(array $data): bool { if (!$this->exists()) { return false; } // Update post meta for each field $meta_fields = [ 'invoice_id' => '_invoice_id', 'amount' => '_amount', 'payment_method' => '_payment_method', 'status' => '_status', 'transaction_id' => '_transaction_id', 'payment_date' => '_payment_date', 'notes' => '_notes', 'payment_type' => '_payment_type', 'recurring_id' => '_recurring_id', 'parent_payment_id' => '_parent_payment_id', 'gateway_response' => '_gateway_response', 'currency' => '_currency', 'currency_symbol' => '_currency_symbol', ]; $success = true; foreach ($meta_fields as $field => $meta_key) { if (isset($data[$field])) { // update_post_meta returns false if value is unchanged (not an error) // It returns meta_id on success, or true if updated // We need to check if the meta exists to determine real failure $old_value = get_post_meta($this->id, $meta_key, true); $result = update_post_meta($this->id, $meta_key, $data[$field]); // Only consider it a failure if the result is false AND the value wasn't already the same if ($result === false && $old_value !== $data[$field]) { //$success = false; } // Always update local data since we're setting it $this->data[$field] = $data[$field]; } } // Update the post title if invoice_id is provided if (isset($data['invoice_id']) && $data['invoice_id']) { $invoice = new \EasyInvoice\Models\Invoice($data['invoice_id']); if ($invoice->exists()) { $post_title = sprintf( __('Payment for Invoice %s', 'easy-invoice'), $invoice->getNumber() ); wp_update_post([ 'ID' => $this->id, 'post_title' => $post_title ]); } } $this->is_modified = false; return $success; } }