From 5055c38f51eae1e9230a4ec1fc93166e383c0f9e Mon Sep 17 00:00:00 2001 From: Stephen Maiorana <1924654+smaiorana@users.noreply.github.com> Date: Fri, 11 Aug 2023 23:32:16 -0400 Subject: [PATCH] Convert services endpoints to config files --- services.admin.inc | 42 ++++++++------- services.install | 98 +++++++++++------------------------ services.module | 125 +++++++++++++++++++-------------------------- 3 files changed, 101 insertions(+), 164 deletions(-) diff --git a/services.admin.inc b/services.admin.inc index 6ea5b53..ec2ae4c 100644 --- a/services.admin.inc +++ b/services.admin.inc @@ -356,11 +356,6 @@ function services_endpoint_edit_form($form, &$form_state, $endpoint = NULL) { '#description' => t('The endpoint name can only consist of lowercase letters, underscores, and numbers.'), ); - $form['eid'] = array( - '#type' => 'value', - '#value' => isset($endpoint->eid) ? $endpoint->eid : '', - ); - $form['endpoint_object'] = array( '#type' => 'value', '#value' => $endpoint, @@ -452,18 +447,19 @@ function services_endpoint_edit_form($form, &$form_state, $endpoint = NULL) { * Validate submission of the preset edit form. */ function services_endpoint_edit_form_validate(&$form, &$form_state) { - // Validate path. - $query = db_select('services_endpoint', 'e'); - $query->addField('e', 'eid'); - $query->condition('path', $form_state['values']['path']); + $endpoint_object = $form_state['values']['endpoint_object']; - if (!empty($form_state['values']['eid']) && is_numeric($form_state['values']['eid'])) { - $query->condition('eid', $form_state['values']['eid'], '!='); - } + // Evaluate the endpoint path if this endpoint is new or the path has changed. + if (!$endpoint_object || $endpoint_object->is_new || $endpoint_object->path != $form_state['values']['path']) { + $names = config_get_names_with_prefix('services.endpoint.'); + foreach ($names as $config_name) { + $config = config($config_name); + $config_path = $config->get('path'); - $res = $query->execute()->fetchField(); - if (!empty($res)) { - form_error($form['path'], t('Endpoint path must be unique.')); + if ($form_state['values']['path'] == $config_path) { + form_error($form['path'], t('Endpoint path must be unique.')); + } + } } } @@ -471,8 +467,8 @@ function services_endpoint_edit_form_validate(&$form, &$form_state) { * Endpoint name check whether this machine name already exists. */ function services_endpoint_machine_name_exists($value) { - $result = db_query('SELECT eid FROM {services_endpoint} WHERE name = :name', array(':name' => $value))->fetchField(); - return !empty($result); + $result = config_get('services.endpoint.' . $value, 'name'); + return ($result == $value); } /** @@ -483,6 +479,11 @@ function services_endpoint_edit_form_submit(&$form, &$form_state) { if (empty($endpoint)) { $endpoint = new stdClass; } + if (!$endpoint->is_new && $endpoint->name && $endpoint->name != $form_state['values']['name']) { + // Endpoint is being renamed. Remove the old config file. + $config_old = config('services.endpoint.' . $endpoint->name); + $config_old->delete(); + } $endpoint->name = $form_state['values']['name']; $endpoint->server = $form_state['values']['server']; @@ -999,11 +1000,8 @@ function services_toggle_enable_page($form, &$form_state, $endpoint) { */ function services_toggle_enable_page_submit($form, &$form_state) { $endpoint = $form_state['endpoint']; - $result = db_update('services_endpoint') - ->fields(array( - 'status' => $endpoint->status ? 0 : 1, - )) - ->execute(); + $status = $endpoint->status ? 0 : 1; + config_set('services.endpoint.' . $endpoint->name, 'status', $status); backdrop_set_message($endpoint->name . ' was updated.'); backdrop_goto('admin/structure/services/list'); } diff --git a/services.install b/services.install index 331ebab..cdcbd98 100644 --- a/services.install +++ b/services.install @@ -10,75 +10,6 @@ function services_schema() { $schema = array(); - $schema['services_endpoint'] = array( - 'description' => 'Stores endpoint information for services', - 'fields' => array( - 'eid' => array( - 'type' => 'serial', - 'description' => 'Primary ID field for the table. Not used for anything except internal lookups.', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'no export' => TRUE, - ), - 'name' => array( - 'description' => 'The name of the endpoint.', - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - ), - 'server' => array( - 'description' => 'The name of the server used in this endpoint.', - 'type' => 'varchar', - 'length' => 32, - 'not null' => TRUE, - ), - 'path' => array( - 'description' => 'The path to the endpoint for this server.', - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - ), - 'authentication' => array( - 'description' => 'The authentication settings for the endpoint.', - 'type' => 'text', - 'size' => 'big', - 'not null' => TRUE, - 'serialize' => TRUE, - 'object default' => array(), - ), - 'server_settings' => array( - 'description' => 'The server settings for the endpoint.', - 'type' => 'blob', - 'size' => 'big', - 'not null' => TRUE, - 'serialize' => TRUE - ), - 'resources' => array( - 'description' => 'Information about the resources exposed in this endpoint.', - 'type' => 'text', - 'size' => 'big', - 'not null' => TRUE, - 'serialize' => TRUE, - 'object default' => array(), - ), - 'status' => array( - 'description' => 'Set the endpoint enabled or disabled.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 1 - ), - 'debug' => array( - 'description' => 'Set the endpoint in debug mode.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0 - ), - ), - 'primary key' => array('eid'), - 'unique keys' => array( - 'name' => array('name'), - ), - ); $schema['services_user'] = array( 'description' => 'Stores users created/updated by services.', 'fields' => array( @@ -227,3 +158,32 @@ function services_uninstall() { variable_del('services_debug'); variable_del('services_auth_module'); } + +/** + * Move services endpoints into config files. + */ +function services_update_1000() { + if (!db_table_exists('services_endpoint')) { + return; + } + + $services_endpoints = db_query("SELECT * FROM {services_endpoint}")->fetchAll(); + foreach ($services_endpoints as $services_endpoint) { + $data = array( + 'name' => $services_endpoint->name, + 'server' => $services_endpoint->server, + 'path' => $services_endpoint->path, + 'authentication' => unserialize($services_endpoint->authentication), + 'server_settings' => unserialize($services_endpoint->server_settings), + 'resources' => unserialize($services_endpoint->resources), + 'status' => $services_endpoint->status, + 'debug' => $services_endpoint->debug, + ); + + $config = config('services.endpoint.' . $services_endpoint->name); + $config->setData($data); + $config->save(); + } + + db_drop_table('services_endpoint'); +} diff --git a/services.module b/services.module index 657b6e3..fc2f2ef 100644 --- a/services.module +++ b/services.module @@ -174,6 +174,22 @@ function services_security_update_reset_users_with_password_one_op($progress, $l } } +/** + * Implements hook_config_info(). + */ +function services_config_info() { + $prefixes['services.endpoint'] = array( + 'name_key' => 'name', + 'label_key' => 'name', + 'group' => t('Services endpoints'), + ); + $prefixes['services.settings'] = array( + 'label' => t('Services settings'), + 'group' => t('Configuration'), + ); + return $prefixes; +} + /** * Implements hook_perm(). */ @@ -436,29 +452,22 @@ function services_endpoint_callback($endpoint_name) { backdrop_not_found(); } - - /** - * Create a new endpoint with defaults appropriately set from schema. + * Create a new endpoint with defaults appropriately set. * * @return stdClass * An endpoint initialized with the default values. */ function services_endpoint_new() { - $schema = backdrop_get_schema('services_endpoint'); - $object = new stdClass; - foreach ($schema['fields'] as $field => $info) { - if (isset($info['object default'])) { - $object->$field = $info['object default']; - } - else if (isset($info['default'])) { - $object->$field = $info['default']; - } - else { - $object->$field = NULL; - } - } + $object->name = NULL; + $object->server = NULL; + $object->path = NULL; + $object->authentication = array(); + $object->server_settings = array(); + $object->resources = array(); + $object->status = 1; + $object->debug = 0; return $object; } @@ -495,22 +504,17 @@ function services_endpoint_load_all() { * @return void */ function services_endpoint_save($endpoint) { - // Set a default of an array if the value is not present. - foreach (array('server_settings', 'resources', 'authentication') as $endpoint_field) { - if (empty($endpoint->{$endpoint_field})) { - $endpoint->{$endpoint_field} = array(); + // Create a new endpoint object to ensure we save only the fields we need. + $endpoint_data = services_endpoint_new(); + foreach (array_keys(get_object_vars($endpoint_data)) as $endpoint_field) { + if (!empty($endpoint->{$endpoint_field})) { + $endpoint_data->{$endpoint_field} = $endpoint->{$endpoint_field}; } } - if (!empty($endpoint->is_new)) { - // New record. - $update = array(); - } - else { - // Existing record. - $update = array('name'); - } - backdrop_write_record('services_endpoint', $endpoint, $update); + $config = config('services.endpoint.' . $endpoint->name); + $config->setData((array) $endpoint_data); + $config->save(); backdrop_static_reset('services_load_endpoint_object'); menu_rebuild(); @@ -523,9 +527,8 @@ function services_endpoint_save($endpoint) { * @return void */ function services_endpoint_delete($endpoint) { - db_delete('services_endpoint') - ->condition('name', $endpoint->name) - ->execute(); + $config = config('services.endpoint.' . $endpoint->name); + $config->delete(); backdrop_static_reset('services_load_endpoint_object'); menu_rebuild(); @@ -1172,21 +1175,16 @@ function _services_session_token() { backdrop_exit(); } +/** + * Fetches an array of endpoint objects (or a single object if requested). + * + * @param $name + * Optional. The name of the endpoint to retrieve. + * + * @return array + */ function services_load_endpoint_object($name = NULL) { - $table = 'services_endpoint'; - $cache = &backdrop_static(__FUNCTION__); - $cache_table_exists = &backdrop_static(__FUNCTION__ . '_table_exists', array()); - - if (!$cache_table_exists) { - $cache_table_exists = db_table_exists($table); - } - - $schema = backdrop_get_schema($table, TRUE); - - if (empty($schema) || !$cache_table_exists) { - return array(); - } // If fetching all we are finished. if (!$name && $cache) { @@ -1198,37 +1196,18 @@ function services_load_endpoint_object($name = NULL) { return $cache[$name]; } - // Build the query - $query = db_select($table, 'q')->fields('q'); - - if ($name) { - $query->condition('name', array($name), 'IN'); + $config_names = config_get_names_with_prefix('services.endpoint.'); + foreach ($config_names as $config_name) { + $config = config($config_name); + $data = (object) $config->getData(); + $cache[$data->name] = $data; } - $result = $query->execute(); - - // Unpack the results of the query onto objects and cache them. - foreach ($result as $data) { - $object = new stdClass; - $object->name = $data->name; - $object->table = $table; - $object->type = t('Normal'); - foreach ($data as $field_name => $field) { - if (!empty($schema['fields'][$field_name]['serialize'])) { - $object->{$field_name} = unserialize($field); - } - else { - $object->{$field_name} = $field; - } - - } - unset($object->eid); - unset($object->table); - $cache[$object->name] = $object; + // Return an individual object if requested. + if (!empty($name)) { + return isset($cache[$name]) ? $cache[$name] : array(); } - - if ($cache && !$name) { - $cached_database = TRUE; + elseif ($cache) { return $cache; }