5
5
namespace Atk4 \Data \Model ;
6
6
7
7
use Atk4 \Core \Factory ;
8
- use Atk4 \Data \Model ;
9
8
10
9
trait UserActionsTrait
11
10
{
@@ -14,22 +13,23 @@ trait UserActionsTrait
14
13
*
15
14
* @var string|array
16
15
*/
17
- public $ _default_seed_action = [Model \ UserAction::class];
16
+ public $ _default_seed_action = [UserAction::class];
18
17
19
18
/**
20
- * @var array<string, Model\ UserAction> Collection of user actions - using key as action system name
19
+ * @var array<string, UserAction> Collection of user actions - using key as action system name
21
20
*/
22
21
protected $ userActions = [];
23
22
24
23
/**
25
24
* Register new user action for this model. By default UI will allow users to trigger actions
26
25
* from UI.
27
26
*
28
- * @param string $name Action name
29
27
* @param array|\Closure $defaults
30
28
*/
31
- public function addUserAction (string $ name , $ defaults = []): Model \ UserAction
29
+ public function addUserAction (string $ name , $ defaults = []): UserAction
32
30
{
31
+ $ this ->assertIsModel ();
32
+
33
33
if ($ defaults instanceof \Closure) {
34
34
$ defaults = ['callback ' => $ defaults ];
35
35
}
@@ -38,54 +38,88 @@ public function addUserAction(string $name, $defaults = []): Model\UserAction
38
38
$ defaults ['caption ' ] = $ this ->readableCaption ($ name );
39
39
}
40
40
41
- /** @var Model\ UserAction $action */
41
+ /** @var UserAction $action */
42
42
$ action = Factory::factory ($ this ->_default_seed_action , $ defaults );
43
43
44
44
$ this ->_addIntoCollection ($ name , $ action , 'userActions ' );
45
45
46
46
return $ action ;
47
47
}
48
48
49
+ /**
50
+ * Returns true if user action with a corresponding name exists.
51
+ */
52
+ public function hasUserAction (string $ name ): bool
53
+ {
54
+ if ($ this ->isEntity () && $ this ->getModel ()->hasUserAction ($ name )) {
55
+ return true ;
56
+ }
57
+
58
+ return $ this ->_hasInCollection ($ name , 'userActions ' );
59
+ }
60
+
61
+ private function addUserActionFromModel (string $ name , UserAction $ action ): void
62
+ {
63
+ $ this ->assertIsEntity ();
64
+ $ action ->getOwner ()->assertIsModel (); // @phpstan-ignore-line
65
+
66
+ // clone action and store it in entity
67
+ $ action = clone $ action ;
68
+ $ action ->unsetOwner ();
69
+ $ this ->_addIntoCollection ($ name , $ action , 'userActions ' );
70
+ }
71
+
49
72
/**
50
73
* Returns list of actions for this model. Can filter actions by records they apply to.
51
74
* It will also skip system user actions (where system === true).
52
75
*
53
- * @param string $appliesTo e.g. Model\ UserAction::APPLIES_TO_ALL_RECORDS
76
+ * @param string $appliesTo e.g. UserAction::APPLIES_TO_ALL_RECORDS
54
77
*
55
- * @return array<string, Model\ UserAction>
78
+ * @return array<string, UserAction>
56
79
*/
57
80
public function getUserActions (string $ appliesTo = null ): array
58
81
{
82
+ if ($ this ->isEntity ()) {
83
+ foreach (array_diff_key ($ this ->getModel ()->getUserActions ($ appliesTo ), $ this ->userActions ) as $ name => $ action ) {
84
+ $ this ->addUserActionFromModel ($ name , $ action );
85
+ }
86
+ }
87
+
59
88
return array_filter ($ this ->userActions , function ($ action ) use ($ appliesTo ) {
60
89
return !$ action ->system && ($ appliesTo === null || $ action ->appliesTo === $ appliesTo );
61
90
});
62
91
}
63
92
64
93
/**
65
- * Returns true if user action with a corresponding name exists.
66
- *
67
- * @param string $name UserAction name
94
+ * Returns one action object of this model. If action not defined, then throws exception.
68
95
*/
69
- public function hasUserAction (string $ name ): bool
96
+ public function getUserAction (string $ name ): UserAction
70
97
{
71
- return $ this ->_hasInCollection ($ name , 'userActions ' );
98
+ if ($ this ->isEntity () && !$ this ->_hasInCollection ($ name , 'userActions ' ) && $ this ->getModel ()->hasUserAction ($ name )) {
99
+ $ this ->addUserActionFromModel ($ name , $ this ->getModel ()->getUserAction ($ name ));
100
+ }
101
+
102
+ return $ this ->_getFromCollection ($ name , 'userActions ' );
72
103
}
73
104
74
105
/**
75
- * Returns one action object of this model. If action not defined, then throws exception .
106
+ * Remove specified action.
76
107
*
77
- * @param string $name Action name
108
+ * @return $this
78
109
*/
79
- public function getUserAction (string $ name ): Model \ UserAction
110
+ public function removeUserAction (string $ name )
80
111
{
81
- return $ this ->_getFromCollection ($ name , 'userActions ' );
112
+ $ this ->assertIsModel ();
113
+
114
+ $ this ->_removeFromCollection ($ name , 'userActions ' );
115
+
116
+ return $ this ;
82
117
}
83
118
84
119
/**
85
120
* Execute specified action with specified arguments.
86
121
*
87
- * @param string $name UserAction name
88
- * @param mixed ...$args
122
+ * @param mixed ...$args
89
123
*
90
124
* @return mixed
91
125
*/
@@ -94,17 +128,39 @@ public function executeUserAction(string $name, ...$args)
94
128
return $ this ->getUserAction ($ name )->execute (...$ args );
95
129
}
96
130
97
- /**
98
- * Remove specified action(s).
99
- *
100
- * @return $this
101
- */
102
- public function removeUserAction (string $ name )
131
+ protected function initUserActions (): void
103
132
{
104
- foreach ((array ) $ name as $ action ) {
105
- $ this ->_removeFromCollection ($ action , 'userActions ' );
106
- }
107
-
108
- return $ this ;
133
+ // Declare our basic Crud actions for the model.
134
+ $ this ->addUserAction ('add ' , [
135
+ 'fields ' => true ,
136
+ 'modifier ' => UserAction::MODIFIER_CREATE ,
137
+ 'appliesTo ' => UserAction::APPLIES_TO_NO_RECORDS ,
138
+ 'callback ' => 'save ' ,
139
+ 'description ' => 'Add ' . $ this ->getModelCaption (),
140
+ ]);
141
+
142
+ $ this ->addUserAction ('edit ' , [
143
+ 'fields ' => true ,
144
+ 'modifier ' => UserAction::MODIFIER_UPDATE ,
145
+ 'appliesTo ' => UserAction::APPLIES_TO_SINGLE_RECORD ,
146
+ 'callback ' => 'save ' ,
147
+ ]);
148
+
149
+ $ this ->addUserAction ('delete ' , [
150
+ 'appliesTo ' => UserAction::APPLIES_TO_SINGLE_RECORD ,
151
+ 'modifier ' => UserAction::MODIFIER_DELETE ,
152
+ 'callback ' => function ($ model ) {
153
+ return $ model ->delete ();
154
+ },
155
+ ]);
156
+
157
+ $ this ->addUserAction ('validate ' , [
158
+ //'appliesTo' => any!
159
+ 'description ' => 'Provided with modified values will validate them but will not save ' ,
160
+ 'modifier ' => UserAction::MODIFIER_READ ,
161
+ 'fields ' => true ,
162
+ 'system ' => true , // don't show by default
163
+ 'args ' => ['intent ' => 'string ' ],
164
+ ]);
109
165
}
110
166
}
0 commit comments