← All changes
|
includes/rest-api/controller/version2/class-mainwp-rest-clients-controller.php
+250
-41
6.0.12
→
6.2.1
View file →
| @@ -741,8 +741,13 @@ | ||
| 741 | 741 | * |
| 742 | 742 | * @return WP_Error|WP_REST_Response |
| 743 | 743 | */ |
| 744 | 744 | public function client_fields( $request ) { // phpcs:ignore -- NOSONAR - complex. |
| 745 | + // pre_page shipped as the documented page size but was never read; keep it working through per_page. | |
| 746 | + if ( null === $request->get_param( 'per_page' ) && null !== $request->get_param( 'pre_page' ) ) { | |
| 747 | + $request->set_param( 'per_page', $request->get_param( 'pre_page' ) ); | |
| 748 | + } | |
| 749 | + | |
| 745 | 750 | // Prepare query args. |
| 746 | 751 | $args = $this->prepare_objects_query( $request, 'client_fields' ); |
| 747 | 752 | $page = ! empty( $args['paged'] ) ? (int) $args['paged'] : 1; |
| 748 | 753 | $per_page = ! empty( $args['items_per_page'] ) ? (int) $args['items_per_page'] : 20; |
| @@ -764,12 +769,14 @@ | ||
| 764 | 769 | } |
| 765 | 770 | |
| 766 | 771 | $data = array(); |
| 767 | 772 | foreach ( $fields as $field ) { |
| 773 | + // A stored "0" is reported as the value it is, not as an empty one. field_id is cast | |
| 774 | + // because wpdb answers every column as a string and the schema declares an integer. | |
| 768 | 775 | $record = array( |
| 769 | - 'field_id' => (int) $field->field_id ? $field->field_id : 0, | |
| 770 | - 'name' => $field->field_name ? $field->field_name : '', | |
| 771 | - 'description' => $field->field_desc ? $field->field_desc : '', | |
| 776 | + 'field_id' => isset( $field->field_id ) ? (int) $field->field_id : 0, | |
| 777 | + 'name' => isset( $field->field_name ) ? $field->field_name : '', | |
| 778 | + 'description' => isset( $field->field_desc ) ? $field->field_desc : '', | |
| 772 | 779 | ); |
| 773 | 780 | $data[] = $this->filter_response_data_by_allowed_fields( $record, 'field_view' ); |
| 774 | 781 | } |
| 775 | 782 | |
| @@ -804,28 +811,57 @@ | ||
| 804 | 811 | * @return WP_Error|WP_REST_Response |
| 805 | 812 | */ |
| 806 | 813 | public function create_client_fields( $request ) { |
| 807 | 814 | // Get request body. |
| 808 | - $body = $request->get_body_params(); | |
| 809 | - if ( empty( $body ) ) { | |
| 815 | + $body = $this->get_request_body( $request ); | |
| 816 | + if ( is_wp_error( $body ) ) { | |
| 817 | + return $body; | |
| 818 | + } | |
| 819 | + | |
| 820 | + $invalid = $this->validate_client_field_values( $body ); | |
| 821 | + if ( is_wp_error( $invalid ) ) { | |
| 822 | + return $invalid; | |
| 823 | + } | |
| 824 | + | |
| 825 | + // Validate request body. "0" is a value the column stores, so a required value is one whose | |
| 826 | + // key was sent carrying something other than whitespace, not one that passes a falsy test. | |
| 827 | + // validate_client_field_values() has already refused a key sent as anything but a string. | |
| 828 | + foreach ( array( 'name', 'description' ) as $required ) { | |
| 829 | + if ( ! isset( $body[ $required ] ) || '' === trim( $body[ $required ] ) ) { | |
| 830 | + return new WP_Error( | |
| 831 | + 'empty_name', | |
| 832 | + __( 'Name and description are required.', 'mainwp' ), | |
| 833 | + array( 'status' => 400 ) | |
| 834 | + ); | |
| 835 | + } | |
| 836 | + } | |
| 837 | + | |
| 838 | + $client_id = 0; | |
| 839 | + $name = sanitize_text_field( wp_unslash( $body['name'] ) ); | |
| 840 | + $desc = sanitize_text_field( wp_unslash( $body['description'] ) ); | |
| 841 | + | |
| 842 | + // field_name is varchar(191), so a longer name is truncated by wpdb before the unique index sees | |
| 843 | + // it and the duplicate lookup, which queries the untruncated name, would not recognise the refusal. | |
| 844 | + // A body read as raw JSON skips the registered maxLength, so the limit is enforced here as well. | |
| 845 | + if ( mb_strlen( $name ) > 191 ) { | |
| 810 | 846 | return new WP_Error( |
| 811 | - 'empty_body', | |
| 812 | - __( 'Request body is empty.', 'mainwp' ), | |
| 847 | + 'invalid_field_value', | |
| 848 | + __( 'Name must be 191 characters or fewer.', 'mainwp' ), | |
| 849 | + array( 'status' => 400 ) | |
| 813 | 850 | ); |
| 814 | 851 | } |
| 815 | 852 | |
| 816 | - // Validate request body. | |
| 817 | - if ( empty( $body['name'] ) || empty( $body['description'] ) ) { | |
| 853 | + // field_desc is varchar(255), so a longer description is either refused by the write or stored | |
| 854 | + // truncated depending on the server's strict mode, and neither answers what the caller sent. | |
| 855 | + // A body read as raw JSON skips the registered maxLength, so the limit is enforced here as well. | |
| 856 | + if ( mb_strlen( $desc ) > 255 ) { | |
| 818 | 857 | return new WP_Error( |
| 819 | - 'empty_name', | |
| 820 | - __( 'Name and description are required.', 'mainwp' ), | |
| 858 | + 'invalid_field_value', | |
| 859 | + __( 'Description must be 255 characters or fewer.', 'mainwp' ), | |
| 860 | + array( 'status' => 400 ) | |
| 821 | 861 | ); |
| 822 | 862 | } |
| 823 | 863 | |
| 824 | - $client_id = 0; | |
| 825 | - $name = sanitize_text_field( wp_unslash( $body['name'] ) ); | |
| 826 | - $desc = sanitize_text_field( wp_unslash( $body['description'] ) ); | |
| 827 | - | |
| 828 | 864 | $field = MainWP_DB_Client::instance()->add_client_field( |
| 829 | 865 | array( |
| 830 | 866 | 'field_name' => $name, |
| 831 | 867 | 'field_desc' => $desc, |
| @@ -833,19 +869,27 @@ | ||
| 833 | 869 | ) |
| 834 | 870 | ); |
| 835 | 871 | |
| 836 | 872 | if ( ! $field ) { |
| 873 | + // add_client_field() returns false for a name it refuses to store as well as for a failed | |
| 874 | + // insert, so a name left empty by sanitizing or already taken stays a client error and | |
| 875 | + // everything else is a server failure. | |
| 876 | + $taken = $this->client_field_name_taken( $name, $client_id ); | |
| 877 | + $caller_fault = ( '' === $name || $taken ); | |
| 878 | + | |
| 837 | 879 | return new WP_Error( |
| 838 | 880 | 'create_field_failed', |
| 839 | - __( 'Create client field failed.', 'mainwp' ), | |
| 881 | + $caller_fault ? __( 'Create client field failed.', 'mainwp' ) : __( 'Creating the client field failed.', 'mainwp' ), | |
| 882 | + array( 'status' => $caller_fault ? 400 : 500 ) | |
| 840 | 883 | ); |
| 841 | 884 | } |
| 842 | 885 | |
| 843 | - // Prepare response data. | |
| 886 | + // Prepare response data. A stored "0" is reported as the value it is, not as an empty one. | |
| 887 | + // field_id is cast because wpdb answers every column as a string and the schema declares an integer. | |
| 844 | 888 | $data = array( |
| 845 | - 'field_id' => (int) $field->field_id ? $field->field_id : 0, | |
| 846 | - 'name' => $field->field_name ? $field->field_name : '', | |
| 847 | - 'description' => $field->field_desc ? $field->field_desc : '', | |
| 889 | + 'field_id' => isset( $field->field_id ) ? (int) $field->field_id : 0, | |
| 890 | + 'name' => isset( $field->field_name ) ? $field->field_name : '', | |
| 891 | + 'description' => isset( $field->field_desc ) ? $field->field_desc : '', | |
| 848 | 892 | ); |
| 849 | 893 | |
| 850 | 894 | return rest_ensure_response( |
| 851 | 895 | array( |
| @@ -871,35 +915,75 @@ | ||
| 871 | 915 | if ( empty( $field ) ) { |
| 872 | 916 | return new WP_Error( |
| 873 | 917 | 'invalid_field_id', |
| 874 | 918 | __( 'Invalid client field.', 'mainwp' ), |
| 919 | + array( 'status' => 404 ) | |
| 875 | 920 | ); |
| 876 | 921 | } |
| 877 | 922 | |
| 878 | 923 | // Get request body. |
| 879 | - $body = $request->get_json_params(); | |
| 880 | - if ( empty( $body ) ) { | |
| 924 | + $body = $this->get_request_body( $request ); | |
| 925 | + if ( is_wp_error( $body ) ) { | |
| 926 | + return $body; | |
| 927 | + } | |
| 928 | + | |
| 929 | + $invalid = $this->validate_client_field_values( $body ); | |
| 930 | + if ( is_wp_error( $invalid ) ) { | |
| 931 | + return $invalid; | |
| 932 | + } | |
| 933 | + | |
| 934 | + // Only a key left out, or sent with nothing but whitespace, keeps the stored value. The add | |
| 935 | + // route reads a value the same way, and sanitizing trims whitespace away, so a value tested | |
| 936 | + // untrimmed here would sanitize down to an empty string the DB layer refuses. "0" is a value | |
| 937 | + // the column stores, and a falsy test would drop it and answer that the edit succeeded. | |
| 938 | + $name = isset( $body['name'] ) && '' !== trim( $body['name'] ) ? sanitize_text_field( wp_unslash( $body['name'] ) ) : $field->field_name; | |
| 939 | + $desc = isset( $body['description'] ) && '' !== trim( $body['description'] ) ? sanitize_text_field( wp_unslash( $body['description'] ) ) : $field->field_desc; | |
| 940 | + | |
| 941 | + // field_name is varchar(191), so a longer name is truncated by wpdb before the unique index sees | |
| 942 | + // it and the duplicate lookup, which queries the untruncated name, would not recognise the refusal. | |
| 943 | + // A body read as raw JSON skips the registered maxLength, so the limit is enforced here as well. | |
| 944 | + if ( mb_strlen( $name ) > 191 ) { | |
| 881 | 945 | return new WP_Error( |
| 882 | - 'empty_body', | |
| 883 | - __( 'Request body is empty.', 'mainwp' ), | |
| 946 | + 'invalid_field_value', | |
| 947 | + __( 'Name must be 191 characters or fewer.', 'mainwp' ), | |
| 948 | + array( 'status' => 400 ) | |
| 884 | 949 | ); |
| 885 | 950 | } |
| 886 | 951 | |
| 887 | - $name = ! empty( $body['name'] ) ? sanitize_text_field( wp_unslash( $body['name'] ) ) : $field->field_name; | |
| 888 | - $desc = ! empty( $body['description'] ) ? sanitize_text_field( wp_unslash( $body['description'] ) ) : $field->field_desc; | |
| 952 | + // field_desc is varchar(255), so a longer description is either refused by the write or stored | |
| 953 | + // truncated depending on the server's strict mode, and neither answers what the caller sent. | |
| 954 | + // A body read as raw JSON skips the registered maxLength, so the limit is enforced here as well. | |
| 955 | + if ( mb_strlen( $desc ) > 255 ) { | |
| 956 | + return new WP_Error( | |
| 957 | + 'invalid_field_value', | |
| 958 | + __( 'Description must be 255 characters or fewer.', 'mainwp' ), | |
| 959 | + array( 'status' => 400 ) | |
| 960 | + ); | |
| 961 | + } | |
| 889 | 962 | |
| 890 | - $updated = MainWP_DB_Client::instance()->update_client_field( | |
| 891 | - $field->field_id, | |
| 892 | - array( | |
| 893 | - 'field_name' => $name, | |
| 894 | - 'field_desc' => $desc, | |
| 895 | - ) | |
| 896 | - ); | |
| 897 | - if ( ! $updated ) { | |
| 898 | - return new WP_Error( | |
| 899 | - 'update_field_failed', | |
| 900 | - __( 'Field already exists, try different field name.', 'mainwp' ), | |
| 963 | + // $wpdb->update() reports no changed rows for an edit that stores the values already there, and | |
| 964 | + // the DB layer cannot tell that apart from a failure, so an edit that changes nothing is not run. | |
| 965 | + if ( $name !== $field->field_name || $desc !== $field->field_desc ) { | |
| 966 | + $updated = MainWP_DB_Client::instance()->update_client_field( | |
| 967 | + $field->field_id, | |
| 968 | + array( | |
| 969 | + 'field_name' => $name, | |
| 970 | + 'field_desc' => $desc, | |
| 971 | + ) | |
| 901 | 972 | ); |
| 973 | + if ( ! $updated ) { | |
| 974 | + // The DB layer refuses a name left empty by sanitizing, and the unique index on | |
| 975 | + // (client_id, field_name) refuses a rename onto a name another field of this client | |
| 976 | + // already owns. Both are the caller's fault; anything else is the write itself failing. | |
| 977 | + $owned = $this->client_field_name_taken( $name, $field->client_id, $field->field_id ); | |
| 978 | + $caller_fault = ( '' === $name || $owned ); | |
| 979 | + | |
| 980 | + return new WP_Error( | |
| 981 | + 'update_field_failed', | |
| 982 | + $caller_fault ? __( 'Field already exists, try different field name.', 'mainwp' ) : __( 'Updating the client field failed.', 'mainwp' ), | |
| 983 | + array( 'status' => $caller_fault ? 400 : 500 ) | |
| 984 | + ); | |
| 985 | + } | |
| 902 | 986 | } |
| 903 | 987 | |
| 904 | 988 | return rest_ensure_response( |
| 905 | 989 | array( |
| @@ -953,19 +1037,26 @@ | ||
| 953 | 1037 | * |
| 954 | 1038 | * @return array |
| 955 | 1039 | */ |
| 956 | 1040 | public function edit_client_fields_allowed_fields() { |
| 1041 | + // WordPress only runs the type check its own sanitizer carries, and a registered | |
| 1042 | + // sanitize_callback replaces it, so without an explicit validate_callback a JSON 42 or true | |
| 1043 | + // would reach the handler already cast to text by sanitize_text_field(). | |
| 957 | 1044 | return array( |
| 958 | 1045 | 'name' => array( |
| 959 | 1046 | 'required' => false, |
| 960 | 1047 | 'type' => 'string', |
| 1048 | + 'maxLength' => 191, | |
| 961 | 1049 | 'sanitize_callback' => 'sanitize_text_field', |
| 1050 | + 'validate_callback' => 'rest_validate_request_arg', | |
| 962 | 1051 | 'description' => __( 'Field name.', 'mainwp' ), |
| 963 | 1052 | ), |
| 964 | 1053 | 'description' => array( |
| 965 | 1054 | 'required' => false, |
| 966 | 1055 | 'type' => 'string', |
| 1056 | + 'maxLength' => 255, | |
| 967 | 1057 | 'sanitize_callback' => 'sanitize_text_field', |
| 1058 | + 'validate_callback' => 'rest_validate_request_arg', | |
| 968 | 1059 | 'description' => __( 'Field description.', 'mainwp' ), |
| 969 | 1060 | ), |
| 970 | 1061 | ); |
| 971 | 1062 | } |
| @@ -972,22 +1063,28 @@ | ||
| 972 | 1063 | |
| 973 | 1064 | /** |
| 974 | 1065 | * Create client fields allowed fields. |
| 975 | 1066 | * |
| 976 | - * @return WP_Error|WP_REST_Response | |
| 1067 | + * @return array | |
| 977 | 1068 | */ |
| 978 | 1069 | public function create_client_fields_allowed_fields() { |
| 1070 | + // See edit_client_fields_allowed_fields(): the registered sanitizer displaces the type check | |
| 1071 | + // WordPress would otherwise run, so the declared type needs its own validate_callback. | |
| 979 | 1072 | return array( |
| 980 | 1073 | 'name' => array( |
| 981 | 1074 | 'required' => true, |
| 982 | 1075 | 'type' => 'string', |
| 1076 | + 'maxLength' => 191, | |
| 983 | 1077 | 'sanitize_callback' => 'sanitize_text_field', |
| 1078 | + 'validate_callback' => 'rest_validate_request_arg', | |
| 984 | 1079 | 'description' => __( 'Field name.', 'mainwp' ), |
| 985 | 1080 | ), |
| 986 | 1081 | 'description' => array( |
| 987 | 1082 | 'required' => true, |
| 988 | 1083 | 'type' => 'string', |
| 1084 | + 'maxLength' => 255, | |
| 989 | 1085 | 'sanitize_callback' => 'sanitize_text_field', |
| 1086 | + 'validate_callback' => 'rest_validate_request_arg', | |
| 990 | 1087 | 'description' => __( 'Field description.', 'mainwp' ), |
| 991 | 1088 | ), |
| 992 | 1089 | ); |
| 993 | 1090 | } |
| @@ -1023,20 +1120,131 @@ | ||
| 1023 | 1120 | 'minimum' => 1, |
| 1024 | 1121 | 'sanitize_callback' => 'absint', |
| 1025 | 1122 | 'description' => __( 'Page number.', 'mainwp' ), |
| 1026 | 1123 | ), |
| 1124 | + 'per_page' => array( | |
| 1125 | + 'required' => false, | |
| 1126 | + 'type' => 'integer', | |
| 1127 | + 'sanitize_callback' => 'absint', | |
| 1128 | + 'validate_callback' => 'rest_validate_request_arg', | |
| 1129 | + 'minimum' => 1, | |
| 1130 | + 'maximum' => 200, | |
| 1131 | + 'description' => __( 'Number of client fields per page.', 'mainwp' ), | |
| 1132 | + ), | |
| 1027 | 1133 | 'pre_page' => array( |
| 1028 | 1134 | 'required' => false, |
| 1029 | 1135 | 'type' => 'integer', |
| 1030 | 1136 | 'sanitize_callback' => 'absint', |
| 1137 | + 'validate_callback' => 'rest_validate_request_arg', | |
| 1031 | 1138 | 'minimum' => 1, |
| 1032 | 1139 | 'maximum' => 200, |
| 1033 | - 'description' => __( 'Number of client fields per page.', 'mainwp' ), | |
| 1140 | + 'description' => __( 'Deprecated alias of per_page. Number of client fields per page.', 'mainwp' ), | |
| 1034 | 1141 | ), |
| 1035 | 1142 | ); |
| 1036 | 1143 | } |
| 1037 | 1144 | |
| 1038 | 1145 | /** |
| 1146 | + * Get request body. | |
| 1147 | + * | |
| 1148 | + * @param WP_REST_Request $request Full details about the request. | |
| 1149 | + * | |
| 1150 | + * @return array|WP_Error Body payload, or an error when the request carries none. | |
| 1151 | + */ | |
| 1152 | + private function get_request_body( $request ) { | |
| 1153 | + // Get request body from form-encoded senders. | |
| 1154 | + $body = $request->get_body_params(); | |
| 1155 | + if ( ! empty( $body ) && is_array( $body ) ) { | |
| 1156 | + return $body; | |
| 1157 | + } | |
| 1158 | + | |
| 1159 | + // Get request body from JSON senders. | |
| 1160 | + $body = $request->get_json_params(); | |
| 1161 | + if ( ! empty( $body ) && is_array( $body ) ) { | |
| 1162 | + return $body; | |
| 1163 | + } | |
| 1164 | + | |
| 1165 | + // Get request body from raw, for JSON sent without the JSON content type. | |
| 1166 | + $body = $request->get_body(); | |
| 1167 | + if ( ! empty( $body ) && is_string( $body ) ) { | |
| 1168 | + $body = json_decode( $body, true ); | |
| 1169 | + if ( is_array( $body ) && ! empty( $body ) ) { | |
| 1170 | + return $body; | |
| 1171 | + } | |
| 1172 | + } | |
| 1173 | + | |
| 1174 | + return new WP_Error( | |
| 1175 | + 'empty_body', | |
| 1176 | + __( 'Request body is empty.', 'mainwp' ), | |
| 1177 | + array( 'status' => 400 ) | |
| 1178 | + ); | |
| 1179 | + } | |
| 1180 | + | |
| 1181 | + /** | |
| 1182 | + * Validate the client field text values carried by a request body. | |
| 1183 | + * | |
| 1184 | + * @param array $body Request body. | |
| 1185 | + * | |
| 1186 | + * @return WP_Error|true Error when a value cannot be stored as text. | |
| 1187 | + */ | |
| 1188 | + private function validate_client_field_values( $body ) { | |
| 1189 | + foreach ( array( 'name', 'description' ) as $key ) { | |
| 1190 | + // A body read as raw JSON skips the registered sanitizers, so a value that is not already | |
| 1191 | + // text reaches sanitize_text_field() and is stored as a cast of itself or as an empty | |
| 1192 | + // string, wiping what it meant to set. A key sent as null counts as sent, not as omitted. | |
| 1193 | + if ( array_key_exists( $key, $body ) && ! is_string( $body[ $key ] ) ) { | |
| 1194 | + return new WP_Error( | |
| 1195 | + 'invalid_field_value', | |
| 1196 | + __( 'Name and description must be text values.', 'mainwp' ), | |
| 1197 | + array( 'status' => 400 ) | |
| 1198 | + ); | |
| 1199 | + } | |
| 1200 | + } | |
| 1201 | + | |
| 1202 | + return true; | |
| 1203 | + } | |
| 1204 | + | |
| 1205 | + /** | |
| 1206 | + * Whether a client already has a field stored under the given name. | |
| 1207 | + * | |
| 1208 | + * @param string $name Field name as the handler sanitized it before the write. | |
| 1209 | + * @param int $client_id Client the field belongs to. | |
| 1210 | + * @param int $exclude_id Field id to skip, for a rename that keeps its own name. | |
| 1211 | + * | |
| 1212 | + * @uses MainWP_DB_Client::instance()->get_client_fields_by_params() | |
| 1213 | + * | |
| 1214 | + * @return bool | |
| 1215 | + */ | |
| 1216 | + private function client_field_name_taken( $name, $client_id, $exclude_id = 0 ) { | |
| 1217 | + // A field_name lookup strips [ and ] from the value it queries with while the stored name keeps | |
| 1218 | + // them, and a PHP comparison would call two names that differ only in case distinct while the | |
| 1219 | + // column collation and the unique index call them the same. The match is left to the database | |
| 1220 | + // on the stored value so this answer agrees with the index that refused the write. | |
| 1221 | + $client_id = (int) $client_id; | |
| 1222 | + $fields = MainWP_DB_Client::instance()->get_client_fields_by_params( | |
| 1223 | + array( | |
| 1224 | + 'client_id' => $client_id, | |
| 1225 | + 'field_name_exact' => (string) $name, | |
| 1226 | + ) | |
| 1227 | + ); | |
| 1228 | + | |
| 1229 | + if ( ! is_array( $fields ) ) { | |
| 1230 | + return false; | |
| 1231 | + } | |
| 1232 | + | |
| 1233 | + foreach ( $fields as $existing ) { | |
| 1234 | + // Client 0 holds the general fields this route writes, and 0 is not a value the query filters | |
| 1235 | + // on, so the owner check happens here. | |
| 1236 | + if ( (int) $existing->client_id !== $client_id || (int) $existing->field_id === (int) $exclude_id ) { | |
| 1237 | + continue; | |
| 1238 | + } | |
| 1239 | + | |
| 1240 | + return true; | |
| 1241 | + } | |
| 1242 | + | |
| 1243 | + return false; | |
| 1244 | + } | |
| 1245 | + | |
| 1246 | + /** | |
| 1039 | 1247 | * Get client field request id or name |
| 1040 | 1248 | * |
| 1041 | 1249 | * @param WP_REST_Request $request Full details about the request. |
| 1042 | 1250 | * |
| @@ -1048,13 +1256,14 @@ | ||
| 1048 | 1256 | $raw = $request->get_param( 'id_name' ); |
| 1049 | 1257 | $decoded = rawurldecode( (string) $raw ); |
| 1050 | 1258 | $field_value = trim( sanitize_text_field( wp_unslash( $decoded ) ) ); |
| 1051 | 1259 | |
| 1052 | - if ( empty( $field_value ) ) { | |
| 1260 | + if ( '' === $field_value ) { | |
| 1053 | 1261 | return false; |
| 1054 | 1262 | } |
| 1055 | 1263 | |
| 1056 | - // Get client field by id. | |
| 1264 | + // Get client field by id. A digit-only segment is an id, so "0" and any other all-digit name is | |
| 1265 | + // addressable by its own id only, never by name. | |
| 1057 | 1266 | if ( ctype_digit( $field_value ) ) { |
| 1058 | 1267 | return MainWP_DB_Client::instance()->get_client_fields_by( 'field_id', (int) $field_value ); |
| 1059 | 1268 | } |
| 1060 | 1269 | |