@@ -8,70 +8,191 @@ class Selectable
88{
99 private Collection $ _collection ;
1010 private string $ _value ;
11- private string $ _text ;
11+ private string $ _label ;
1212 private mixed $ _selected = null ;
13+ private mixed $ _disabled = null ;
1314
14- public function __construct (Collection $ collection , string |null $ text = null , string |null $ value = null , mixed $ selected = null )
15+ public function __construct (Collection $ collection , string |null $ label = null , string |null $ value = null , mixed $ selected = null , mixed $ disabled = null )
1516 {
16- $ this ->_collection = $ collection ;
17- $ this ->_text = $ text ?? 'name ' ;
18- $ this ->_value = $ value ?? 'name ' ;
17+ $ this ->_collection = $ collection ;
18+ $ this ->_label = $ label ?? 'name ' ;
19+ $ this ->_value = $ value ?? 'id ' ;
1920 $ this ->_selected = $ selected ?? null ;
21+ $ this ->_disabled = $ disabled ?? null ;
2022 }
2123
2224
2325 /**
2426 * Generate select options from a Collection instance
2527 * @param Collection $collection the collection instance to be used
26- * @param string|null $text the field to be used as the main text of the option (default is 'name')
28+ * @param string|null $label the field to be used as the main text of the option (default is 'name')
2729 * @param string|null $value the field to be used as value of the option (default is 'id')
2830 * @param mixed $selected selected value/values
31+ * @param mixed|null $disabled
2932 * @return string
3033 */
31- public static function collectionToSelectOptions (
32- Collection $ collection ,
33- string |null $ text = null ,
34+ public static function collectionToSelectOptions (
35+ Collection $ collection ,
36+ string |null $ label = null ,
3437 string |null $ value = null ,
35- mixed $ selected = null ,
38+ mixed $ selected = null ,
39+ mixed $ disabled = null ,
3640 ): string
3741 {
38- return (new self ($ collection , $ text , $ value , $ selected ))->toSelectOptions ();
42+ return (new self ($ collection , $ label , $ value , $ selected, $ disabled ))->toSelectOptions ();
3943 }
4044
45+
4146 /**
4247 * Generate select options from this instance
4348 * @return string
4449 */
4550 public function toSelectOptions (): string
4651 {
4752
53+
4854 $ html = "" ;
4955 foreach ($ this ->_collection as $ index => $ item ) {
50- $ lineText = $ item ->{$ this ->_text } ?? "N/A " ;
56+ $ lineLabel = $ item ->{$ this ->_label } ?? "N/A " ;
5157 $ lineValue = $ item ->{$ this ->_value } ?? "" ;
5258 $ html .= "<option value= \"{$ lineValue }\"" ;
53- if (is_array ($ this ->_selected )) {
54- foreach ($ this ->_selected as $ selectedItem ) {
55- if (is_object ($ selectedItem )) {
56- if ((string ) $ selectedItem ->{$ this ->_value } === (string ) $ lineValue ) {
57- $ html .= " selected " ;
58- }
59- } else if (is_array ($ selectedItem )) {
60- if (array_key_exists ($ this ->_value , $ selectedItem ) && (string )$ selectedItem [$ this ->_value ] === (string ) $ lineValue ) {
61- $ html .= " selected " ;
62- }
63- } else if ((string ) $ selectedItem === (string ) $ lineValue ) {
64- $ html .= " selected " ;
65- }
66- }
67- } else if ((string ) $ this ->_selected === (string ) $ lineValue ) {
59+ if ($ this ->_shouldSelect ($ item )){
6860 $ html .= " selected " ;
6961 }
70- $ html .= "> {$ lineText }</option> " ;
62+ if ($ this ->_shouldDisable ($ item )){
63+ $ html .= " disabled " ;
64+ }
65+ $ html .= " > {$ lineLabel }</option> " ;
7166 }
7267 return $ html ;
7368 }
7469
70+ /**
71+ * Check if the item should be selected
72+ * @param object $item
73+ * @return bool
74+ */
75+ private function _shouldSelect (object $ item ): bool
76+ {
77+ $ lineValue = $ item ->{$ this ->_value } ?? "" ;
78+ if (is_callable ($ this ->_selected )) {
79+ if (call_user_func ($ this ->_selected , $ item ) === true ) {
80+ return true ;
81+ }
82+ } else if (is_object ($ this ->_selected )){
83+ if ((string )$ this ->_selected ->{$ this ->_value } === (string )$ lineValue ){
84+ return true ;
85+ }
86+ } else if (is_array ($ this ->_selected )) {
87+ foreach ($ this ->_selected as $ selectedItem ) {
88+ if (is_object ($ selectedItem )) {
89+ if ((string )$ selectedItem ->{$ this ->_value } === (string )$ lineValue ) {
90+ return true ;
91+ }
92+ } else if (is_array ($ selectedItem )) {
93+ if (array_key_exists ($ this ->_value , $ selectedItem ) && (string )$ selectedItem [$ this ->_value ] === (string )$ lineValue ) {
94+ return true ;
95+ }
96+ } else if ((string )$ selectedItem === (string )$ lineValue ) {
97+ return true ;
98+ }
99+ }
100+ } else if ((string )$ this ->_selected === (string )$ lineValue ) {
101+ return true ;
102+ }
103+ return false ;
104+ }
105+
106+ /**
107+ * Check if the item should be selected
108+ * @param object $item
109+ * @return bool
110+ */
111+ private function _shouldDisable (object $ item ): bool
112+ {
113+ $ lineValue = $ item ->{$ this ->_value } ?? "" ;
114+ if (is_callable ($ this ->_disabled )) {
115+ if (call_user_func ($ this ->_disabled , $ item ) === true ) {
116+ return true ;
117+ }
118+ } else if (is_object ($ this ->_disabled )){
119+ if ((string )$ this ->_disabled ->{$ this ->_value } === (string )$ lineValue ){
120+ return true ;
121+ }
122+ } else if (is_array ($ this ->_disabled )) {
123+ foreach ($ this ->_disabled as $ disabledItem ) {
124+ if (is_object ($ disabledItem )) {
125+ if ((string )$ disabledItem ->{$ this ->_value } === (string )$ lineValue ) {
126+ return true ;
127+ }
128+ } else if (is_array ($ disabledItem )) {
129+ if (array_key_exists ($ this ->_value , $ disabledItem ) && (string )$ disabledItem [$ this ->_value ] === (string )$ lineValue ) {
130+ return true ;
131+ }
132+ } else if ((string )$ disabledItem === (string )$ lineValue ) {
133+ return true ;
134+ }
135+ }
136+ } else if ((string ) $ this ->_disabled === (string ) $ lineValue ) {
137+ return true ;
138+ }
139+ return false ;
140+ }
141+
142+ /**
143+ * Return a collection of selectable items (for use in spa components)
144+ * @return Collection
145+ */
146+ public function toSelectItems (): Collection
147+ {
148+ return $ this ->_collection ->map (function ($ item ) {
149+ return [
150+ 'value ' => $ item ->{$ this ->_value } ?? "" ,
151+ 'label ' => $ item ->{$ this ->_label },
152+ 'isSelected ' => $ this ->_shouldSelect ($ item ),
153+ 'isDisabled ' => $ this ->_shouldDisable ($ item ),
154+ ];
155+ });
156+ }
157+
158+ //// Builders
159+
160+ /**
161+ * @param string $label name of the field to be used as label
162+ * @return $this
163+ */
164+ public function withLabel (string $ label ): self
165+ {
166+ $ this ->_label = $ label ;
167+ return $ this ;
168+ }
169+
170+ /**
171+ * @param string $value name of the field to be used as value
172+ * @return $this
173+ */
174+ public function withValue (string $ value ): self
175+ {
176+ $ this ->_value = $ value ;
177+ return $ this ;
178+ }
179+
180+ /**
181+ * @param mixed $selected
182+ * @return $this
183+ */
184+ public function withSelected (mixed $ selected ): self
185+ {
186+ $ this ->_selected = $ selected ;
187+ return $ this ;
188+ }
189+
190+ public function withDisabled (mixed $ disabled ): self
191+ {
192+ $ this ->_disabled = null ;
193+ return $ this ;
194+ }
195+
75196 /**
76197 * Convert a Selectable instance back to a Collection instance
77198 * @return Collection
0 commit comments