@@ -20,20 +20,17 @@ class Service extends Model {
2020 public function __construct (mixed $ id = null , mixed $ parent_id = null , mixed $ data = [], mixed ...$ options ) {
2121 # Set Model attributes
2222 $ this ->internal_callable = 'get_services ' ;
23+ $ this ->auto_create_id = false ; // We don't create services with create(), we just control existing ones
2324 $ this ->many = true ;
2425
2526 # Set Model Fields
26- $ this ->name = new StringField (
27- required: true ,
28- choices_callable: 'get_service_name_choices ' ,
29- help_text: 'The internal name of the service. ' ,
30- );
3127 $ this ->action = new StringField (
3228 required: true ,
3329 choices: ['start ' , 'stop ' , 'restart ' ],
3430 write_only: true ,
3531 help_text: 'The action to perform against this service. ' ,
3632 );
33+ $ this ->name = new StringField (read_only: true , help_text: 'The internal name of the service. ' );
3734 $ this ->description = new StringField (read_only: true , help_text: 'The full descriptive name of the service. ' );
3835 $ this ->enabled = new BooleanField (
3936 read_only: true ,
@@ -57,59 +54,52 @@ class Service extends Model {
5754 * @return array An array of available pfSense services and their current statuses.
5855 */
5956 public static function get_services (): array {
60- # Variables
61- $ services = get_services ();
62-
63- # Loop through each service and set the proper values
64- foreach ($ services as $ id => $ service ) {
65- # Ensure the $enabled and $status values are always present
66- $ services [$ id ]['enabled ' ] = is_service_enabled ($ service ['name ' ]);
67- $ services [$ id ]['status ' ] = is_service_running ($ service ['name ' ]);
68- }
69-
70- return $ services ;
71- }
72-
73- /**
74- * Obtains all internal service choices for the `name` field.
75- * @return array An array of available service names.
76- */
77- public function get_service_name_choices (): array {
78- $ choices = [];
79- foreach ($ this ->get_services () as $ service ) {
80- $ choices [] = $ service ['name ' ];
81- }
82- return $ choices ;
83- }
84-
85- /**
86- * Gets the representation ID for a given service name.
87- * @param string $name The internal service to obtain the ID for.
88- * @return int The representation ID of the service with this name.
89- */
90- public function get_id_by_name (string $ name ): int {
91- return $ this ->query (['name ' => $ name ])->first ()->id ;
57+ return get_services ();
9258 }
9359
9460 /**
9561 * Starts or stops a specified service.
9662 */
97- public function _create () {
63+ public function _create (): void {
64+ # Obtain the extras for this service. Provides additional info required for some services to be controlled.
65+ $ extras = $ this ->_format_extra_data ($ this ->get_services ()[$ this ->id ]);
66+
9867 # Trigger the requested service action
9968 switch ($ this ->action ->value ) {
10069 case 'start ' :
101- service_control_start (name: $ this ->name ->value , extras: [] );
70+ service_control_start (name: $ this ->name ->value , extras: $ extras );
10271 break ;
10372 case 'stop ' :
104- service_control_stop (name: $ this ->name ->value , extras: [] );
73+ service_control_stop (name: $ this ->name ->value , extras: $ extras );
10574 break ;
10675 case 'restart ' :
107- service_control_restart (name: $ this ->name ->value , extras: [] );
76+ service_control_restart (name: $ this ->name ->value , extras: $ extras );
10877 break ;
10978 }
11079
111- # Populate the current status of the service with this name so this object is up-to-date.
112- $ this ->id = $ this ->get_id_by_name ($ this ->name ->value );
80+ # Recheck the service status after the action has been performed to ensure the correct status is returned
11381 $ this ->from_internal ();
11482 }
83+
84+ /**
85+ * Formats the 'extra' service data required for some services to be restarted to the weird format pfSense
86+ * sometimes expects. In the webConfigurator, this process is obfuscated by AJAX calls and JavaScript so there
87+ * is no direct function to format this data. This function is a workaround to provide the correct data format.
88+ *
89+ * @param array $service The service data to format.
90+ * @return array The formatted service data suitable for the service control functions 'extras' parameter.
91+ */
92+ public function _format_extra_data (array $ service ): array {
93+ # Format OpenVPN service extra data for service control
94+ if ($ service ['name ' ] === 'openvpn ' ) {
95+ # 'mode' changes to 'vpnmode'
96+ $ service ['vpnmode ' ] = $ service ['mode ' ];
97+ unset($ service ['mode ' ]);
98+
99+ # 'vpnid' changes to just 'id'
100+ $ service ['id ' ] = $ service ['vpnid ' ];
101+ }
102+
103+ return $ service ;
104+ }
115105}
0 commit comments