1Workflow::Action(3) User Contributed Perl Documentation Workflow::Action(3)
2
3
4
6 Workflow::Action - Base class for Workflow actions
7
9 This documentation describes version 1.09 of this package
10
12 # Configure the Action...
13 <action name="CreateUser"
14 class="MyApp::Action::CreateUser">
15 <field name="username" is_required="yes"/>
16 <field name="email" is_required="yes"/>
17 <validator name="IsUniqueUser">
18 <arg>$username</arg>
19 </validator>
20 <validator name="IsValidEmail">
21 <arg>$email</arg>
22 </validator>
23 </action>
24
25 # Define the action
26
27 package MyApp::Action::CreateUser;
28
29 use base qw( Workflow::Action );
30 use Workflow::Exception qw( workflow_error );
31
32 sub execute {
33 my ( $self, $wf ) = @_;
34 my $context = $wf->context;
35
36 # Since 'username' and 'email' have already been validated we
37 # don't need to check them for uniqueness, well-formedness, etc.
38
39 my $user = eval {
40 User->create({ username => $context->param( 'username' ),
41 email => $context->param( 'email' ) })
42 };
43
44 # Wrap all errors returned...
45
46 if ( $@ ) {
47 workflow_error
48 "Cannot create new user with name '", $context->param( 'username' ), "': $EVAL_ERROR";
49 }
50
51 # Set the created user in the context for the application and/or
52 # other actions (observers) to use
53
54 $context->param( user => $user );
55
56 # return the username since it might be used elsewhere...
57 return $user->username;
58 }
59
61 This is the base class for all Workflow Actions. You do not have to use
62 it as such but it is strongly recommended.
63
65 You configure your actions and map them to a specific module in your
66 actions configuration file using the syntax above and that shown in
67 Workflow. In some cases, you'll have actions that apply to all
68 workflows. In more elaborate configurations, you may have one workflow
69 server loading multiple workflows and multiple actions for each. In
70 these cases, you'll have multiple workflow types and you may want
71 actions with the same names to have different behaviors for each type.
72
73 For example, you may have a workflow type Ticket and another type
74 Order_Parts. They both may have a Submit action, but you'll want the
75 Submit to be different for each.
76
77 You can specify a type in your actions configuration to associate that
78 action with that workflow type. If you don't provide a type, the action
79 is available to all types. For example:
80
81 <actions>
82 <type>Ticket</type>
83 <description>Actions for the Ticket workflow only.</description>
84 <action name="TIX_NEW"
85 class="TestApp::Action::TicketCreate">
86 ...Addtional configuration...
87
88 The type must match an existing workflow type or the action will never
89 be called.
90
92 You can validate additional attributes in of your action by doing two
93 things:
94
95 · Set $Workflow::Factory::VALIDATE_ACTION_CONFIG to 1.
96
97 · Provide function validate_config() in your action class.
98
99 Then, this function will be called with all the acton attributes when
100 it is parsed. For exmaple, if your action XML looks like this:
101
102 <action name="BEGIN" class="My::Class" when="NOW">
103
104 You can validate it like this:
105
106 sub My::Class::validate_config {
107 my $config = shift;
108 unless ('NOW' eq $config->{when}) {
109 configuration_error "`$$config{when}' is not a valid value " .
110 "for `when'";
111 }
112 }
113
115 Public Methods
116 new()
117
118 Subclasses may override this method, but it's not very common. It is
119 called when you invoke a method in your Workflow object that returns an
120 Action object, for example, methods such as $wf->_get_action will call
121 this method.
122
123 Your action classes usually subclass directly from Workflow::Action and
124 they don't need to override this method at all. However, under some
125 circumstances, you may find the need to extend your action classes.
126
127 Suppose you want to define some extra properties to actions but you
128 also want for some of these properties to depend on a particular state.
129 For example, the action "icon" will almost allways be the same, but the
130 action "index" will depend on state, so you can display your actions in
131 a certain order according to that particular state. Here is an example
132 on how you easily do this by overriding new():
133
134 1) Set the less changing properties in your action definition:
135
136 <actions>
137 <type>foo</type>
138 <action name="Browse"
139 type="menu_button" icon="list_icon"
140 class="actual::action::class">
141 </action>
142
143 2) Set the state dependant properties in the state definition:
144
145 <state name="INITIAL">
146 <description>
147 Manage Manufaturers
148 </description>
149 <action index="0" name="Browse" resulting_state="BROWSE">
150 <condition name="roleis_oem_mgmt"/>
151 </action>
152 <action index="1" name="Create" resulting_state="CREATE">
153 <condition name="roleis_oem_mgmt"/>
154 </action>
155 <action index="2" name="Back" resulting_state="CLOSED"/>
156 </state>
157
158 3) Craft a custom action base class
159
160 package your::action::base::class;
161
162 use warnings;
163 use strict;
164
165 use base qw( Workflow::Action );
166 use Workflow::Exception qw( workflow_error );
167
168 # extra action class properties
169 my @EXTRA_PROPS = qw( index icon type data );
170 __PACKAGE__->mk_accessors(@EXTRA_PROPS);
171
172 sub new {
173 my ($class, $wf, $params) = @_;
174 my $self = $class->SUPER::new($wf, $params);
175 # set only our extra properties from action class def
176 foreach my $prop (@EXTRA_PROPS) {
177 next if ( $self->$prop );
178 $self->$prop( $params->{$prop} );
179 }
180 # override specific extra action properties according to state
181 my $wf_state = $wf->_get_workflow_state;
182 my $action = $wf_state->{_actions}->{$self->name};
183 $self->index($action->{index});
184 return $self;
185 }
186
187
188 1;
189
190 Note: this hack takes advantage of the fact that the XML parser picks
191 up the extra parameters and add them to the action hash of the current
192 $wf_state. Your milage may vary.
193
194 4) Use your custom action base class instead of the default
195
196 package actual::action::class;
197
198 use warnings;
199 use strict;
200
201 use base qw( your::base::action::class );
202 use Workflow::Exception qw( workflow_error );
203
204 sub execute {
205 ...
206 }
207
208 1;
209
210 Private Methods
211 init( $workflow, \%params )
212
213 init is called in conjuction with the overall workflow initialization.
214
215 It sets up the necessary validators based on the on configured actions,
216 input fields and required fields.
217
218 add_field( @fields )
219
220 Add one or more Workflow::Action::InputFields to the action.
221
222 required_fields()
223
224 Return a list of Workflow::Action::InputField objects that are
225 required.
226
227 optional_fields()
228
229 Return a list of Workflow::Action::InputField objects that are
230 optional.
231
232 fields()
233
234 Return a list of all Workflow::Action::InputField objects associated
235 with this action.
236
237 add_validators( @validator_config )
238
239 Given the 'validator' configuration declarations in the action
240 configuration, ask the Workflow::Factory for the Workflow::Validator
241 object associated with each name and store that along with the
242 arguments to be used, runtime and otherwise.
243
244 get_validators()
245
246 Get a list of all the validator hashrefs, each with two keys:
247 'validator' and 'args'. The 'validator' key contains the appropriate
248 Workflow::Validator object, while 'args' contains an arrayref of
249 arguments to pass to the validator, some of which may need to be
250 evaluated at runtime.
251
252 validate( $workflow )
253
254 Run through all validators for this action. If any fail they will throw
255 a Workflow::Exception, the validation subclass.
256
257 execute( $workflow )
258
259 Subclasses must implement -- this will perform the actual work. It's
260 not required that you return anything, but if the action may be used in
261 a Workflow::State object that has multiple resulting states you should
262 return a simple scalar for a return value.
263
264 add_fields
265
266 Method to add fields to the workflow. The method takes an array of
267 fields.
268
270 Workflow
271
272 Workflow::Factory
273
275 Copyright (c) 2003-2004 Chris Winters. All rights reserved.
276
277 This library is free software; you can redistribute it and/or modify it
278 under the same terms as Perl itself.
279
281 Chris Winters <chris@cwinters.com>
282
283
284
285perl v5.32.0 2020-07-28 Workflow::Action(3)