| @@ -140,9 +140,9 @@ | ||
| 140 | 140 | $field_name = $this->camelCaseToSnakeCase(substr($name, 3)); // Remove 'has' prefix |
| 141 | 141 | return !empty($this->__get($field_name)); |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | - throw new \BadMethodCallException("Method $name does not exist"); | |
| 144 | + throw new \BadMethodCallException(esc_html("Method $name does not exist")); | |
| 145 | 145 | } |
| 146 | 146 | |
| 147 | 147 | /** |
| 148 | 148 | * Convert camelCase to snake_case |
| @@ -161,47 +161,60 @@ | ||
| 161 | 161 | protected function loadFromUserMeta() { |
| 162 | 162 | if ($this->id <= 0) { |
| 163 | 163 | return; |
| 164 | 164 | } |
| 165 | - | |
| 166 | - // Load all client fields from user meta with simple field names | |
| 165 | + | |
| 166 | + // Easy-Invoice-owned meta (what the user explicitly set through this plugin). | |
| 167 | 167 | $this->data['business_client_name'] = get_user_meta($this->id, ClientFields::BUSINESS_CLIENT_NAME, true); |
| 168 | - $this->data['email'] = get_user_meta($this->id, ClientFields::EMAIL, true); | |
| 169 | - $this->data['username'] = get_user_meta($this->id, ClientFields::USERNAME, true); | |
| 170 | - $this->data['address'] = get_user_meta($this->id, ClientFields::ADDRESS, true); | |
| 171 | - $this->data['extra_info'] = get_user_meta($this->id, ClientFields::EXTRA_INFO, true); | |
| 172 | - $this->data['first_name'] = get_user_meta($this->id, ClientFields::FIRST_NAME, true); | |
| 173 | - $this->data['last_name'] = get_user_meta($this->id, ClientFields::LAST_NAME, true); | |
| 174 | - $this->data['website'] = get_user_meta($this->id, ClientFields::WEBSITE, true); | |
| 175 | - $this->data['phone'] = get_user_meta($this->id, ClientFields::PHONE, true); // Now uses dedicated phone key | |
| 176 | - | |
| 177 | - // If email is not set in meta, try to get it from user data | |
| 168 | + $this->data['email'] = get_user_meta($this->id, ClientFields::EMAIL, true); | |
| 169 | + $this->data['username'] = get_user_meta($this->id, ClientFields::USERNAME, true); | |
| 170 | + $this->data['address'] = get_user_meta($this->id, ClientFields::ADDRESS, true); | |
| 171 | + $this->data['extra_info'] = get_user_meta($this->id, ClientFields::EXTRA_INFO, true); | |
| 172 | + $this->data['first_name'] = get_user_meta($this->id, ClientFields::FIRST_NAME, true); | |
| 173 | + $this->data['last_name'] = get_user_meta($this->id, ClientFields::LAST_NAME, true); | |
| 174 | + $this->data['website'] = get_user_meta($this->id, ClientFields::WEBSITE, true); | |
| 175 | + $this->data['phone'] = get_user_meta($this->id, ClientFields::PHONE, true); | |
| 176 | + | |
| 177 | + // Fallback chain for clients NOT created through Easy Invoice | |
| 178 | + // (typically WooCommerce customers imported via order placement, | |
| 179 | + // or plain WP users with profile fields filled in): | |
| 180 | + // | |
| 181 | + // 1. EI meta (above) — explicit entry in Easy Invoice | |
| 182 | + // 2. WP standard meta — user profile / WC sync | |
| 183 | + // 3. WC billing_* meta — set the first time a customer checks out | |
| 184 | + // | |
| 185 | + // Without this fallback, WooCommerce customers render as their bare | |
| 186 | + // user_login (e.g. "callum_smith42") everywhere — Clients listing, | |
| 187 | + // invoice builder client-search dropdown, and invoice header — even | |
| 188 | + // though their real name sits in billing_first_name / billing_last_name. | |
| 189 | + $user = get_user_by('id', $this->id); | |
| 190 | + | |
| 178 | 191 | if (empty($this->data['email'])) { |
| 179 | - $user = get_user_by('id', $this->id); | |
| 180 | - if ($user) { | |
| 181 | - $this->data['email'] = $user->user_email; | |
| 192 | + $this->data['email'] = $user ? (string) $user->user_email : ''; | |
| 193 | + if (empty($this->data['email'])) { | |
| 194 | + $this->data['email'] = (string) get_user_meta($this->id, 'billing_email', true); | |
| 182 | 195 | } |
| 183 | 196 | } |
| 184 | - | |
| 185 | - // If username is not set in meta, try to get it from user data | |
| 186 | 197 | if (empty($this->data['username'])) { |
| 187 | - $user = get_user_by('id', $this->id); | |
| 188 | - if ($user) { | |
| 189 | - $this->data['username'] = $user->user_login; | |
| 198 | + $this->data['username'] = $user ? (string) $user->user_login : ''; | |
| 199 | + } | |
| 200 | + if (empty($this->data['first_name'])) { | |
| 201 | + $this->data['first_name'] = $user ? (string) $user->first_name : ''; | |
| 202 | + if (empty($this->data['first_name'])) { | |
| 203 | + $this->data['first_name'] = (string) get_user_meta($this->id, 'billing_first_name', true); | |
| 190 | 204 | } |
| 191 | 205 | } |
| 192 | - | |
| 193 | - // If first/last name are not set in meta, try to get them from user data | |
| 194 | - if (empty($this->data['first_name']) || empty($this->data['last_name'])) { | |
| 195 | - $user = get_user_by('id', $this->id); | |
| 196 | - if ($user) { | |
| 197 | - if (empty($this->data['first_name'])) { | |
| 198 | - $this->data['first_name'] = $user->first_name; | |
| 199 | - } | |
| 200 | - if (empty($this->data['last_name'])) { | |
| 201 | - $this->data['last_name'] = $user->last_name; | |
| 202 | - } | |
| 206 | + if (empty($this->data['last_name'])) { | |
| 207 | + $this->data['last_name'] = $user ? (string) $user->last_name : ''; | |
| 208 | + if (empty($this->data['last_name'])) { | |
| 209 | + $this->data['last_name'] = (string) get_user_meta($this->id, 'billing_last_name', true); | |
| 203 | 210 | } |
| 211 | + } | |
| 212 | + if (empty($this->data['business_client_name'])) { | |
| 213 | + $this->data['business_client_name'] = (string) get_user_meta($this->id, 'billing_company', true); | |
| 214 | + } | |
| 215 | + if (empty($this->data['phone'])) { | |
| 216 | + $this->data['phone'] = (string) get_user_meta($this->id, 'billing_phone', true); | |
| 204 | 217 | } |
| 205 | 218 | } |
| 206 | 219 | |
| 207 | 220 | // Essential methods only |