@@ -336,8 +336,9 @@ public static function get_total_items( array $args = [] ): int {
336336 * Updates multiple rows into the table.
337337 *
338338 * @since 3.0.0
339+ * @since 3.1.4 Enabled unfolding the value if is an array.
339340 *
340- * @param array<mixed > $entries The entries to update.
341+ * @param array<array<string, null|int|string|float|bool|DateTimeInterface|string[]|int[]|float[]|DateTimeInterface[]> > $entries The entries to update.
341342 *
342343 * @return bool Whether the update was successful.
343344 */
@@ -372,7 +373,7 @@ public static function update_many( array $entries ): bool {
372373
373374 [ $ value , $ placeholder ] = self ::prepare_value_for_query ( $ column , $ value );
374375
375- $ set_statement [] = $ database ::prepare ( "%i = {$ placeholder }" , ...array_filter ( [ $ column , $ value ], static fn ( $ v ) => null !== $ v ) );
376+ $ set_statement [] = $ database ::prepare ( "%i = {$ placeholder }" , ...array_filter ( [ $ column , ... self :: ensure_array ( $ value ) ], static fn ( $ v ) => null !== $ v ) );
376377 }
377378
378379 $ set_statement = implode ( ', ' , $ set_statement );
@@ -672,12 +673,13 @@ protected static function get_join_parts( string $join_table, string $join_condi
672673 *
673674 * @since 3.0.0
674675 * @since 3.1.1 Added the $order_by parameter.
676+ * @since 3.1.4 Enabled unfolding the value if is an array.
675677 *
676- * @param string $column The column to get the models by.
677- * @param mixed $value The value to get the models by.
678- * @param string $operator The operator to use.
679- * @param int $limit The limit of models to return.
680- * @param string $order_by The order by clause to use.
678+ * @param string $column The column to get the models by.
679+ * @param null|int|string|float|bool|DateTimeInterface|string[]|int[]|float[]|DateTimeInterface[] $value The value to get the models by.
680+ * @param string $operator The operator to use.
681+ * @param int $limit The limit of models to return.
682+ * @param string $order_by The order by clause to use.
681683 *
682684 * @return mixed[] The models, or an empty array if no models are found.
683685 *
@@ -690,12 +692,12 @@ public static function get_all_by( string $column, $value, string $operator = '=
690692
691693 $ database = Config::get_db ();
692694 $ results = [];
693- foreach ( static ::fetch_all_where ( $ database ::prepare ( "WHERE %i {$ operator } {$ placeholder }" , ...array_filter ( [ $ column , $ value ], static fn ( $ v ) => null !== $ v ) ), $ limit , ARRAY_A , $ order_by ) as $ task_array ) {
694- if ( empty ( $ task_array [ static ::uid_column () ] ) ) {
695+ foreach ( static ::fetch_all_where ( $ database ::prepare ( "WHERE %i {$ operator } {$ placeholder }" , ...array_filter ( [ $ column , ... self :: ensure_array ( $ value ) ], static fn ( $ v ) => null !== $ v ) ), $ limit , ARRAY_A , $ order_by ) as $ data_array ) {
696+ if ( empty ( $ data_array [ static ::uid_column () ] ) ) {
695697 continue ;
696698 }
697699
698- $ results [] = static ::transform_from_array ( self ::amend_value_types ( $ task_array ) );
700+ $ results [] = static ::transform_from_array ( self ::amend_value_types ( $ data_array ) );
699701 }
700702
701703 return $ results ;
@@ -705,34 +707,44 @@ public static function get_all_by( string $column, $value, string $operator = '=
705707 * Gets the first model by a column.
706708 *
707709 * @since 3.0.0
710+ * @since 3.1.4 Enabled unfolding the value if is an array.
711+ * @since 3.1.4 Added the $operator parameter.
708712 *
709- * @param string $column The column to get the model by.
710- * @param mixed $value The value to get the model by.
713+ * @param string $column The column to get the model by.
714+ * @param null|int|string|float|bool|DateTimeInterface|string[]|int[]|float[]|DateTimeInterface[] $value The value to get the model by.
715+ * @param string $operator The operator to use.
711716 *
712717 * @return ?mixed The model, or `null` if no model is found.
713718 *
714719 * @throws InvalidArgumentException If the column does not exist.
720+ * @throws InvalidArgumentException If the operator is invalid.
715721 */
716- public static function get_first_by ( string $ column , $ value ) {
722+ public static function get_first_by ( string $ column , $ value, string $ operator = ' = ' ) {
717723 [ $ value , $ placeholder ] = self ::prepare_value_for_query ( $ column , $ value );
718724
725+ $ operator = strtoupper ( $ operator );
726+
727+ if ( ! in_array ( $ operator , self ::operators (), true ) ) {
728+ throw new InvalidArgumentException ( "Invalid operator: {$ operator }. " );
729+ }
730+
719731 $ database = Config::get_db ();
720- $ task_array = static ::fetch_first_where ( $ database ::prepare ( "WHERE %i = {$ placeholder }" , ...array_filter ( [ $ column , $ value ], static fn ( $ v ) => null !== $ v ) ), ARRAY_A );
732+ $ data_array = static ::fetch_first_where ( $ database ::prepare ( "WHERE %i { $ operator } {$ placeholder }" , ...array_filter ( [ $ column , ... self :: ensure_array ( $ value ) ], static fn ( $ v ) => null !== $ v ) ), ARRAY_A );
721733
722- if ( empty ( $ task_array [ static ::uid_column () ] ) ) {
734+ if ( empty ( $ data_array [ static ::uid_column () ] ) ) {
723735 return null ;
724736 }
725737
726- return static ::transform_from_array ( self ::amend_value_types ( $ task_array ) );
738+ return static ::transform_from_array ( self ::amend_value_types ( $ data_array ) );
727739 }
728740
729741 /**
730742 * Prepares a value for a query.
731743 *
732744 * @since 3.0.0
733745 *
734- * @param string $column The column to prepare the value for.
735- * @param mixed $value The value to prepare.
746+ * @param string $column The column to prepare the value for.
747+ * @param null|string|int|float|bool|DateTimeInterface|array<null|string|int|float|bool|DateTimeInterface> $value The value to prepare.
736748 *
737749 * @return array{0: mixed, 1: string} The prepared value and placeholder.
738750 *
@@ -791,6 +803,10 @@ private static function prepare_value_for_query( string $column, $value ): array
791803 throw new InvalidArgumentException ( "Unsupported column type: $ column_type. " );
792804 }
793805
806+ if ( is_array ( $ value ) && ! $ value ) {
807+ return [ null , '(NULL) ' ];
808+ }
809+
794810 // @phpstan-ignore-next-line
795811 return [ $ value , is_array ( $ value ) ? '( ' . implode ( ', ' , array_fill ( 0 , count ( $ value ), $ placeholder ) ) . ') ' : $ placeholder ];
796812 }
@@ -918,4 +934,29 @@ public static function cast_value_based_on_type( string $type, $value ) {
918934 throw new InvalidArgumentException ( "Unsupported column type: {$ type }. " );
919935 }
920936 }
937+
938+ /**
939+ * Ensures the value is an array.
940+ *
941+ * @since 3.1.4
942+ *
943+ * @param null|string|int|float|bool|DateTimeInterface|string[]|int[]|float[]|DateTimeInterface[] $value The value to ensure is an array.
944+ *
945+ * @return array<null|string|int|float|bool|DateTimeInterface> The value as an array.
946+ */
947+ private static function ensure_array ( $ value ): array {
948+ if ( null !== $ value && ! is_int ( $ value ) && ! is_string ( $ value ) && ! is_float ( $ value ) && ! is_bool ( $ value ) && ! $ value instanceof DateTimeInterface && ! is_array ( $ value ) ) {
949+ throw new InvalidArgumentException ( 'Value should be an integer, string, float, boolean, DateTimeInterface, or array. ' );
950+ }
951+
952+ if ( is_array ( $ value ) && $ value ) {
953+ foreach ( $ value as $ k => $ v ) {
954+ if ( null !== $ v && ! is_int ( $ v ) && ! is_string ( $ v ) && ! is_float ( $ v ) && ! is_bool ( $ v ) && ! $ v instanceof DateTimeInterface ) {
955+ throw new InvalidArgumentException ( 'Value with offset ' . $ k . ' should be an integer, string, float, boolean or DateTimeInterface. ' );
956+ }
957+ }
958+ }
959+
960+ return is_array ( $ value ) ? $ value : [ $ value ];
961+ }
921962}
0 commit comments