farm-2.x-dev/modules/core/api/farm_api.install
modules/core/api/farm_api.install
<?php /** * @file * Install, update and uninstall functions for the farm_api module. */ use Drupal\consumers\Entity\Consumer; /** * Implements hook_install(). */ function farm_api_install() { // Allow JSON:API write operations. \Drupal::configFactory()->getEditable('jsonapi.settings')->set('read_only', FALSE)->save(); // Change the base JSON:API path to /api. \Drupal::configFactory()->getEditable('jsonapi_extras.settings')->set('path_prefix', 'api')->save(); // Load the simple_oauth module settings. $simple_oauth_settings = \Drupal::configFactory()->getEditable('simple_oauth.settings'); // Increase access token expiration time to 1 hour. $simple_oauth_settings->set('access_token_expiration', 3600); // Explicitly set the public/private key path. $simple_oauth_settings->set('public_key', '../keys/public.key'); $simple_oauth_settings->set('private_key', '../keys/private.key'); // Save simple_oauth settings. $simple_oauth_settings->save(); // Generate key files for simple_oauth module. // Code adapted from the contenta_jsonapi profile install tasks: // https://github.com/contentacms/contenta_jsonapi/blob/8.x-3.x/contenta_jsonapi.profile // Build all the dependencies manually to avoid having to rely on the // container to be ready. $dir_name = 'keys'; /** @var \Drupal\simple_oauth\Service\KeyGeneratorService $key_gen */ $key_gen = \Drupal::service('simple_oauth.key.generator'); /** @var \Drupal\simple_oauth\Service\Filesystem\FileSystemChecker $file_system_checker */ $file_system_checker = \Drupal::service('simple_oauth.filesystem_checker'); /** @var \Drupal\Core\File\FileSystem $file_system */ $file_system = \Drupal::service('file_system'); // Save keys in the "keys" directory outside of the webroot. $relative_path = DRUPAL_ROOT . '/../' . $dir_name; if (!$file_system_checker->isDirectory($relative_path)) { $file_system->mkdir($relative_path); } $keys_path = $file_system->realpath($relative_path); $pub_filename = sprintf('%s/public.key', $keys_path); $pri_filename = sprintf('%s/private.key', $keys_path); // Attempt to create keys if they don't exist. if (!$file_system_checker->fileExist($pub_filename) || !$file_system_checker->fileExist($pri_filename)) { try { $key_gen->generateKeys($keys_path); } catch (\Exception $e) { watchdog_exception('farm_api', $e); } } // Delete the "Default Consumer" created by the consumers module. $default_consumer = \Drupal::entityTypeManager()->getStorage('consumer') ->loadByProperties(['label' => 'Default Consumer']); if (!empty($default_consumer)) { $default_consumer = reset($default_consumer); $default_consumer->delete(); } // Create a "Farm default" consumer. $base_url = \Drupal::service('router.request_context')->getCompleteBaseUrl(); $farm_consumer = Consumer::create([ 'label' => 'Farm default', 'client_id' => 'farm', 'redirect' => $base_url, 'is_default' => TRUE, 'owner_id' => '', 'secret' => NULL, 'confidential' => FALSE, 'third_party' => FALSE, 'grant_user_access' => TRUE, 'limit_user_access' => TRUE, 'limit_requested_access' => FALSE, ]); $farm_consumer->save(); } /** * Implements hook_uninstall(). */ function farm_api_uninstall() { // Load the default farm consumer. $consumers = \Drupal::entityTypeManager()->getStorage('consumer') ->loadByProperties(['client_id' => 'farm']); // If found, delete the consumer. if (!empty($consumers)) { $farm_consumer = reset($consumers); $farm_consumer->delete(); } } /** * Implements hook_update_dependencies(). */ function farm_api_update_dependencies() { // The Consumers module added a client_id base field in version 1.14, which // replaces our custom client_id field. We need to migrate the client IDs // from our old field to the new field, which requires running our own // update hooks before and after those of the Consumers module. $dependencies['consumers'][8108] = [ 'farm_api' => 9000, ]; $dependencies['farm_api'][9001] = [ 'consumers' => 8109, ]; return $dependencies; } /** * Save client_id values and uninstall farmOS client_id field. */ function farm_api_update_9000(&$sandbox) { // This update hook must run before consumers_update_8108(). // @see farm_api_update_dependencies(). // Get all client_id values from the database. $client_ids = []; $result = \Drupal::database()->query('SELECT entity_id, client_id_value FROM {consumer__client_id}')->fetchAll(); foreach ($result as $record) { $client_ids[$record->entity_id] = $record->client_id_value; } // Save the client_id values to Drupal state. if (!empty($client_ids)) { \Drupal::state()->set('farm_api_consumer_client_ids', $client_ids); } // Uninstall the client_id field. /** @var \Drupal\entity\BundleFieldDefinition $definition */ $definition = \Drupal::service('farm_field.factory')->bundleFieldDefinition(['type' => 'string']); $definition->setTargetEntityTypeId('consumer'); $definition->setName('client_id'); \Drupal::entityDefinitionUpdateManager()->uninstallFieldStorageDefinition($definition); } /** * Restore client_id values saved from farmOS client_id field. */ function farm_api_update_9001(&$sandbox) { // This update hook must run after consumers_update_8109(). // @see farm_api_update_dependencies(). // Load saved client_id values from old client_id field. $client_ids = \Drupal::state()->get('farm_api_consumer_client_ids', []); if (empty($client_ids)) { return; } // Save client_id values to new client_id field. // Use SQL update instead of entity save so tokens do not become invalidated. $database = \Drupal::database(); foreach ($client_ids as $consumer_id => $client_id) { $database->update('consumer_field_data') ->fields(['client_id' => $client_id]) ->condition('id', $consumer_id) ->execute(); } }