AyeCode /
invoicing
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
| 1 | <?php |
||||||
| 2 | /** |
||||||
| 3 | * Shared logic for WP based data stores. |
||||||
| 4 | * |
||||||
| 5 | * @version 1.0.19 |
||||||
| 6 | */ |
||||||
| 7 | |||||||
| 8 | defined( 'ABSPATH' ) || exit; |
||||||
| 9 | |||||||
| 10 | /** |
||||||
| 11 | * GetPaid_Data_Store_WP class. |
||||||
| 12 | * |
||||||
| 13 | * Datastores that extend this class use CPTs to store data. |
||||||
| 14 | */ |
||||||
| 15 | class GetPaid_Data_Store_WP { |
||||||
| 16 | |||||||
| 17 | /** |
||||||
| 18 | * Meta type. This should match up with |
||||||
| 19 | * the types available at https://developer.wordpress.org/reference/functions/add_metadata/. |
||||||
| 20 | * WP defines 'post', 'user', 'comment', and 'term'. |
||||||
| 21 | * |
||||||
| 22 | * @var string |
||||||
| 23 | */ |
||||||
| 24 | protected $meta_type = 'post'; |
||||||
| 25 | |||||||
| 26 | /** |
||||||
| 27 | * This only needs set if you are using a custom metadata type. |
||||||
| 28 | * |
||||||
| 29 | * @var string |
||||||
| 30 | */ |
||||||
| 31 | protected $object_id_field_for_meta = ''; |
||||||
| 32 | |||||||
| 33 | /** |
||||||
| 34 | * Data stored in meta keys, but not considered "meta" for an object. |
||||||
| 35 | * |
||||||
| 36 | * @since 1.0.19 |
||||||
| 37 | * |
||||||
| 38 | * @var array |
||||||
| 39 | */ |
||||||
| 40 | protected $internal_meta_keys = array(); |
||||||
| 41 | |||||||
| 42 | /** |
||||||
| 43 | * Meta data which should exist in the DB, even if empty. |
||||||
| 44 | * |
||||||
| 45 | * @since 1.0.19 |
||||||
| 46 | * |
||||||
| 47 | * @var array |
||||||
| 48 | */ |
||||||
| 49 | protected $must_exist_meta_keys = array(); |
||||||
| 50 | |||||||
| 51 | /** |
||||||
| 52 | * A map of meta keys to data props. |
||||||
| 53 | * |
||||||
| 54 | * @since 1.0.19 |
||||||
| 55 | * |
||||||
| 56 | * @var array |
||||||
| 57 | */ |
||||||
| 58 | protected $meta_key_to_props = array(); |
||||||
| 59 | |||||||
| 60 | /** |
||||||
| 61 | * Returns an array of meta for an object. |
||||||
| 62 | * |
||||||
| 63 | * @since 1.0.19 |
||||||
| 64 | * @param GetPaid_Data $object GetPaid_Data object. |
||||||
| 65 | * @return array |
||||||
| 66 | */ |
||||||
| 67 | public function read_meta( &$object ) { |
||||||
| 68 | global $wpdb; |
||||||
| 69 | $db_info = $this->get_db_info(); |
||||||
| 70 | $raw_meta_data = $wpdb->get_results( |
||||||
| 71 | $wpdb->prepare( |
||||||
| 72 | "SELECT {$db_info['meta_id_field']} as meta_id, meta_key, meta_value |
||||||
| 73 | FROM {$db_info['table']} |
||||||
| 74 | WHERE {$db_info['object_id_field']} = %d |
||||||
| 75 | ORDER BY {$db_info['meta_id_field']}", |
||||||
| 76 | $object->get_id() |
||||||
| 77 | ) |
||||||
| 78 | ); |
||||||
| 79 | |||||||
| 80 | $this->internal_meta_keys = array_merge( array_map( array( $this, 'prefix_key' ), $object->get_data_keys() ), $this->internal_meta_keys ); |
||||||
| 81 | $meta_data = array_filter( $raw_meta_data, array( $this, 'exclude_internal_meta_keys' ) ); |
||||||
| 82 | return apply_filters( "getpaid_data_store_wp_{$this->meta_type}_read_meta", $meta_data, $object, $this ); |
||||||
| 83 | } |
||||||
| 84 | |||||||
| 85 | /** |
||||||
| 86 | * Deletes meta based on meta ID. |
||||||
| 87 | * |
||||||
| 88 | * @since 1.0.19 |
||||||
| 89 | * @param GetPaid_Data $object GetPaid_Data object. |
||||||
| 90 | * @param stdClass $meta (containing at least ->id). |
||||||
| 91 | */ |
||||||
| 92 | public function delete_meta( &$object, $meta ) { |
||||||
| 93 | delete_metadata_by_mid( $this->meta_type, $meta->id ); |
||||||
| 94 | } |
||||||
| 95 | |||||||
| 96 | /** |
||||||
| 97 | * Add new piece of meta. |
||||||
| 98 | * |
||||||
| 99 | * @since 1.0.19 |
||||||
| 100 | * @param GetPaid_Data $object GetPaid_Data object. |
||||||
| 101 | * @param stdClass $meta (containing ->key and ->value). |
||||||
| 102 | * @return int meta ID |
||||||
| 103 | */ |
||||||
| 104 | public function add_meta( &$object, $meta ) { |
||||||
| 105 | return add_metadata( $this->meta_type, $object->get_id(), $meta->key, is_string( $meta->value ) ? wp_slash( $meta->value ) : $meta->value, false ); |
||||||
|
0 ignored issues
–
show
|
|||||||
| 106 | } |
||||||
| 107 | |||||||
| 108 | /** |
||||||
| 109 | * Update meta. |
||||||
| 110 | * |
||||||
| 111 | * @since 1.0.19 |
||||||
| 112 | * @param GetPaid_Data $object GetPaid_Data object. |
||||||
| 113 | * @param stdClass $meta (containing ->id, ->key and ->value). |
||||||
| 114 | */ |
||||||
| 115 | public function update_meta( &$object, $meta ) { |
||||||
| 116 | update_metadata_by_mid( $this->meta_type, $meta->id, $meta->value, $meta->key ); |
||||||
| 117 | } |
||||||
| 118 | |||||||
| 119 | /** |
||||||
| 120 | * Table structure is slightly different between meta types, this function will return what we need to know. |
||||||
| 121 | * |
||||||
| 122 | * @since 1.0.19 |
||||||
| 123 | * @return array Array elements: table, object_id_field, meta_id_field |
||||||
| 124 | */ |
||||||
| 125 | protected function get_db_info() { |
||||||
| 126 | global $wpdb; |
||||||
| 127 | |||||||
| 128 | $meta_id_field = 'meta_id'; // users table calls this umeta_id so we need to track this as well. |
||||||
| 129 | $table = $wpdb->prefix; |
||||||
| 130 | |||||||
| 131 | // If we are dealing with a type of metadata that is not a core type, the table should be prefixed. |
||||||
| 132 | if ( ! in_array( $this->meta_type, array( 'post', 'user', 'comment', 'term' ), true ) ) { |
||||||
| 133 | $table .= 'getpaid_'; |
||||||
| 134 | } |
||||||
| 135 | |||||||
| 136 | $table .= $this->meta_type . 'meta'; |
||||||
| 137 | $object_id_field = $this->meta_type . '_id'; |
||||||
| 138 | |||||||
| 139 | // Figure out our field names. |
||||||
| 140 | if ( 'user' === $this->meta_type ) { |
||||||
| 141 | $meta_id_field = 'umeta_id'; |
||||||
| 142 | $table = $wpdb->usermeta; |
||||||
| 143 | } |
||||||
| 144 | |||||||
| 145 | if ( ! empty( $this->object_id_field_for_meta ) ) { |
||||||
| 146 | $object_id_field = $this->object_id_field_for_meta; |
||||||
| 147 | } |
||||||
| 148 | |||||||
| 149 | return array( |
||||||
| 150 | 'table' => $table, |
||||||
| 151 | 'object_id_field' => $object_id_field, |
||||||
| 152 | 'meta_id_field' => $meta_id_field, |
||||||
| 153 | ); |
||||||
| 154 | } |
||||||
| 155 | |||||||
| 156 | /** |
||||||
| 157 | * Internal meta keys we don't want exposed as part of meta_data. This is in |
||||||
| 158 | * addition to all data props with _ prefix. |
||||||
| 159 | * |
||||||
| 160 | * @since 1.0.19 |
||||||
| 161 | * |
||||||
| 162 | * @param string $key Prefix to be added to meta keys. |
||||||
| 163 | * @return string |
||||||
| 164 | */ |
||||||
| 165 | protected function prefix_key( $key ) { |
||||||
| 166 | return '_' === substr( $key, 0, 1 ) ? $key : '_' . $key; |
||||||
| 167 | } |
||||||
| 168 | |||||||
| 169 | /** |
||||||
| 170 | * Callback to remove unwanted meta data. |
||||||
| 171 | * |
||||||
| 172 | * @param object $meta Meta object to check if it should be excluded or not. |
||||||
| 173 | * @return bool |
||||||
| 174 | */ |
||||||
| 175 | protected function exclude_internal_meta_keys( $meta ) { |
||||||
| 176 | return ! in_array( $meta->meta_key, $this->internal_meta_keys, true ) && 0 !== stripos( $meta->meta_key, 'wp_' ); |
||||||
| 177 | } |
||||||
| 178 | |||||||
| 179 | /** |
||||||
| 180 | * Gets a list of props and meta keys that need updated based on change state |
||||||
| 181 | * or if they are present in the database or not. |
||||||
| 182 | * |
||||||
| 183 | * @param GetPaid_Data $object The GetPaid_Data object. |
||||||
| 184 | * @param array $meta_key_to_props A mapping of meta keys => prop names. |
||||||
| 185 | * @param string $meta_type The internal WP meta type (post, user, etc). |
||||||
| 186 | * @return array A mapping of meta keys => prop names, filtered by ones that should be updated. |
||||||
| 187 | */ |
||||||
| 188 | protected function get_props_to_update( $object, $meta_key_to_props, $meta_type = 'post' ) { |
||||||
| 189 | $props_to_update = array(); |
||||||
| 190 | $changed_props = $object->get_changes(); |
||||||
| 191 | |||||||
| 192 | // Props should be updated if they are a part of the $changed array or don't exist yet. |
||||||
| 193 | foreach ( $meta_key_to_props as $meta_key => $prop ) { |
||||||
| 194 | if ( array_key_exists( $prop, $changed_props ) || ! metadata_exists( $meta_type, $object->get_id(), $meta_key ) ) { |
||||||
| 195 | $props_to_update[ $meta_key ] = $prop; |
||||||
| 196 | } |
||||||
| 197 | } |
||||||
| 198 | |||||||
| 199 | return $props_to_update; |
||||||
| 200 | } |
||||||
| 201 | |||||||
| 202 | /** |
||||||
| 203 | * Read object data. |
||||||
| 204 | * |
||||||
| 205 | * @param GetPaid_Data $object GetPaid_Data object. |
||||||
| 206 | * @param WP_Post $post_object Post object. |
||||||
| 207 | * @since 1.0.19 |
||||||
| 208 | */ |
||||||
| 209 | protected function read_object_data( &$object, $post_object ) { |
||||||
| 210 | $id = $object->get_id(); |
||||||
| 211 | $props = array(); |
||||||
| 212 | |||||||
| 213 | foreach ( $this->meta_key_to_props as $meta_key => $prop ) { |
||||||
| 214 | $props[ $prop ] = get_post_meta( $id, $meta_key, true ); |
||||||
| 215 | } |
||||||
| 216 | |||||||
| 217 | // Set object properties. |
||||||
| 218 | $object->set_props( $props ); |
||||||
| 219 | |||||||
| 220 | // Gets extra data associated with the object if needed. |
||||||
| 221 | foreach ( $object->get_extra_data_keys() as $key ) { |
||||||
| 222 | $function = 'set_' . $key; |
||||||
| 223 | if ( is_callable( array( $object, $function ) ) ) { |
||||||
| 224 | $object->{$function}( get_post_meta( $object->get_id(), $key, true ) ); |
||||||
| 225 | } |
||||||
| 226 | } |
||||||
| 227 | } |
||||||
| 228 | |||||||
| 229 | /** |
||||||
| 230 | * Helper method that updates all the post meta for an object based on it's settings in the GetPaid_Data class. |
||||||
| 231 | * |
||||||
| 232 | * @param GetPaid_Data $object GetPaid_Data object. |
||||||
| 233 | * @since 1.0.19 |
||||||
| 234 | */ |
||||||
| 235 | protected function update_post_meta( &$object ) { |
||||||
| 236 | |||||||
| 237 | $updated_props = array(); |
||||||
| 238 | $props_to_update = $this->get_props_to_update( $object, $this->meta_key_to_props ); |
||||||
| 239 | $object_type = $object->get_object_type(); |
||||||
| 240 | |||||||
| 241 | foreach ( $props_to_update as $meta_key => $prop ) { |
||||||
| 242 | $value = $object->{"get_$prop"}( 'edit' ); |
||||||
| 243 | $value = is_string( $value ) ? wp_slash( $value ) : $value; |
||||||
| 244 | |||||||
| 245 | $updated = $this->update_or_delete_post_meta( $object, $meta_key, $value ); |
||||||
| 246 | |||||||
| 247 | if ( $updated ) { |
||||||
| 248 | $updated_props[] = $prop; |
||||||
| 249 | } |
||||||
| 250 | } |
||||||
| 251 | |||||||
| 252 | do_action( "getpaid_{$object_type}_object_updated_props", $object, $updated_props ); |
||||||
| 253 | } |
||||||
| 254 | |||||||
| 255 | /** |
||||||
| 256 | * Update meta data in, or delete it from, the database. |
||||||
| 257 | * |
||||||
| 258 | * Avoids storing meta when it's either an empty string or empty array or null. |
||||||
| 259 | * Other empty values such as numeric 0 should still be stored. |
||||||
| 260 | * Data-stores can force meta to exist using `must_exist_meta_keys`. |
||||||
| 261 | * |
||||||
| 262 | * Note: WordPress `get_metadata` function returns an empty string when meta data does not exist. |
||||||
| 263 | * |
||||||
| 264 | * @param GetPaid_Data $object The GetPaid_Data object. |
||||||
| 265 | * @param string $meta_key Meta key to update. |
||||||
| 266 | * @param mixed $meta_value Value to save. |
||||||
| 267 | * |
||||||
| 268 | * @since 1.0.19 Added to prevent empty meta being stored unless required. |
||||||
| 269 | * |
||||||
| 270 | * @return bool True if updated/deleted. |
||||||
| 271 | */ |
||||||
| 272 | protected function update_or_delete_post_meta( $object, $meta_key, $meta_value ) { |
||||||
| 273 | if ( in_array( $meta_value, array( array(), '', null ), true ) && ! in_array( $meta_key, $this->must_exist_meta_keys, true ) ) { |
||||||
| 274 | $updated = delete_post_meta( $object->get_id(), $meta_key ); |
||||||
| 275 | } else { |
||||||
| 276 | $updated = update_post_meta( $object->get_id(), $meta_key, $meta_value ); |
||||||
| 277 | } |
||||||
| 278 | |||||||
| 279 | return (bool) $updated; |
||||||
| 280 | } |
||||||
| 281 | |||||||
| 282 | /** |
||||||
| 283 | * Return list of internal meta keys. |
||||||
| 284 | * |
||||||
| 285 | * @since 1.0.19 |
||||||
| 286 | * @return array |
||||||
| 287 | */ |
||||||
| 288 | public function get_internal_meta_keys() { |
||||||
| 289 | return $this->internal_meta_keys; |
||||||
| 290 | } |
||||||
| 291 | |||||||
| 292 | /** |
||||||
| 293 | * Clear any caches. |
||||||
| 294 | * |
||||||
| 295 | * @param GetPaid_Data $object GetPaid_Data object. |
||||||
| 296 | * @since 1.0.19 |
||||||
| 297 | */ |
||||||
| 298 | protected function clear_caches( &$object ) { |
||||||
| 299 | clean_post_cache( $object->get_id() ); |
||||||
| 300 | } |
||||||
| 301 | |||||||
| 302 | /** |
||||||
| 303 | * Method to delete a data object from the database. |
||||||
| 304 | * |
||||||
| 305 | * @param GetPaid_Data $object GetPaid_Data object. |
||||||
| 306 | * @param array $args Array of args to pass to the delete method. |
||||||
| 307 | * |
||||||
| 308 | * @return void |
||||||
| 309 | */ |
||||||
| 310 | public function delete( &$object, $args = array() ) { |
||||||
| 311 | $id = $object->get_id(); |
||||||
| 312 | $object_type = $object->get_object_type(); |
||||||
| 313 | |||||||
| 314 | if ( 'invoice' == $object_type ) { |
||||||
| 315 | $object_type = $object->get_type(); |
||||||
|
0 ignored issues
–
show
The method
get_type() does not exist on GetPaid_Data. It seems like you code against a sub-type of GetPaid_Data such as WPInv_Invoice or WPInv_Item or WPInv_Discount.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 316 | } |
||||||
| 317 | |||||||
| 318 | $args = wp_parse_args( |
||||||
| 319 | $args, |
||||||
| 320 | array( |
||||||
| 321 | 'force_delete' => false, |
||||||
| 322 | ) |
||||||
| 323 | ); |
||||||
| 324 | |||||||
| 325 | if ( ! $id ) { |
||||||
| 326 | return; |
||||||
| 327 | } |
||||||
| 328 | |||||||
| 329 | if ( $args['force_delete'] ) { |
||||||
| 330 | do_action( "getpaid_delete_$object_type", $object ); |
||||||
| 331 | wp_delete_post( $id, true ); |
||||||
| 332 | $object->set_id( 0 ); |
||||||
| 333 | } else { |
||||||
| 334 | do_action( "getpaid_trash_$object_type", $object ); |
||||||
| 335 | wp_trash_post( $id ); |
||||||
| 336 | $object->set_status( 'trash' ); |
||||||
| 337 | } |
||||||
| 338 | } |
||||||
| 339 | |||||||
| 340 | /** |
||||||
| 341 | * Get the status to save to the post object. |
||||||
| 342 | * |
||||||
| 343 | * |
||||||
| 344 | * @since 1.0.19 |
||||||
| 345 | * @param GetPaid_Data $object GetPaid_Data object. |
||||||
| 346 | * @return string |
||||||
| 347 | */ |
||||||
| 348 | protected function get_post_status( $object ) { |
||||||
| 349 | $object_status = $object->get_status( 'edit' ); |
||||||
| 350 | $object_type = $object->get_object_type(); |
||||||
| 351 | |||||||
| 352 | if ( ! $object_status ) { |
||||||
| 353 | $object_status = apply_filters( "getpaid_default_{$object_type}_status", 'draft' ); |
||||||
| 354 | } |
||||||
| 355 | |||||||
| 356 | return $object_status; |
||||||
| 357 | } |
||||||
| 358 | |||||||
| 359 | } |
||||||
| 360 |
If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.