foldershare-8.x-1.2/src/Utilities/ConfigurationUtilities.php
src/Utilities/ConfigurationUtilities.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 | <?php namespace Drupal\foldershare\Utilities; use Drupal\Core\Config\InstallStorage; use Drupal\Core\Config\ExtensionInstallStorage; /** * Defines static utility functions for working with configurations. * * The functions in this class support loading and reverting core and * entity configurations. * * <B>Warning:</B> This class is strictly internal to the FolderShare * module. The class's existance, name, and content may change from * release to release without any promise of backwards compatability. * * @ingroup foldershare */ final class ConfigurationUtilities { /*-------------------------------------------------------------------- * * Functions. * *-------------------------------------------------------------------*/ /** * Loads a configuration for an entity type and configuration name. * * The named configuration for the indicated entity type is found on * disk (in any module), loaded, and returned as a raw nested array * of values. * * Returning the array, rather than a created entity, avoids unnecessarily * creating new entities when the caller only needs to see particular * values within a configuration, or compare it with another configuration. * * @param string $entityTypeId * The ID (name) of the entity type. * @param string $configName * The name of the desired configuration for the entity type. * * @return array * Returns a nested associative array containing the keys and values * of the configuration. The structure of the array varies with the * type of configuration. A NULL is returned if the configuration * could not be found. An empty array is returned if the configuration * is found, but it is empty. * * @see ::revertConfiguration() */ public static function loadConfiguration( string $entityTypeId , string $configName ) { // Validate // -------- // The entity type ID and configuration name both must be non-empty. if ( empty ( $entityTypeId ) === TRUE || empty ( $configName ) === TRUE) { // Empty entity type ID or configuration name. return NULL; } // Setup // ----- // Get some values we need. $entityTypeManager = \Drupal::entityTypeManager(); try { $entityDefinition = $entityTypeManager ->getDefinition( $entityTypeId ); } catch (\Exception $e ) { // Unrecognized entity type. return NULL; } // Create the fully-qualified configuration name formed by adding a // configuration prefix for the entity type. $fullName = $entityDefinition ->getConfigPrefix() . '.' . $configName ; // Load file // --------- // Read the configuration from a file. Start by checking the install // configuration. If not found there, check the optional configuration. $configStorage = \Drupal::service( 'config.storage' ); $installStorage = new ExtensionInstallStorage( $configStorage , InstallStorage::CONFIG_INSTALL_DIRECTORY); $config = $installStorage ->read( $fullName ); if ( empty ( $config ) === TRUE) { $optionalStorage = new ExtensionInstallStorage( $configStorage , InstallStorage::CONFIG_OPTIONAL_DIRECTORY); $config = $optionalStorage ->read( $fullName ); if ( empty ( $config ) === TRUE) { // Cannot find the configuration file. return NULL; } } return $config ; } /** * Reverts an entity or core configuration by reloading it from a module. * * This method supports core and entity configurations. Core configurations * have a single site-wide instance, while entity configurations are * entity instances with an ID and values for entity fields. For instance, * core configurations are used to describe an entity type's forms and * and displays, while entity configurations are used to describe each * of the views configurations that might have been created by a site. * * This method looks at the $baseName. If it is 'core', the method loads * a core configuration. Otherwise it assumes the name is for an entity * type and the method loads a configuration and saves it as either a new * entity type instance, or to replace an existing instance. * * This method looks for either type of configuration in the 'install' or * 'optional' folders across all installed modules. If not found, * FALSE is returned. If found, the configuration is loaded as above. * * For entity configurations, this method looks for the entity type * definition. If not found, FALSE is returned. * * @param string $baseName * The base name of the configuration. For entity type's, this is the * entity type ID. For core configurations, this is 'core'. * @param string $configName * The name of the desired configuration. * * @return bool * Returns TRUE if the configuration was reverted. FALSE is returned * if the configuration file could not be found. For entity configurations, * FALSE is returned if the entity type could not be found. * * @see ::loadConfiguration() */ public static function revertConfiguration( string $baseName , string $configName ) { // The base name and configuration name both must be non-empty. if ( empty ( $baseName ) === TRUE || empty ( $configName ) === TRUE) { return FALSE; } // Revert a core or entity configuration. if ( $baseName === 'core' ) { // Core configurations SOMETIMES prefix with 'core'. Try that first. if (self::revertCoreConfiguration( 'core.' . $configName ) === TRUE) { return TRUE; } // Other core configurations do not prefix with 'core'. Try that. return self::revertCoreConfiguration( $configName ); } return self::revertEntityConfiguration( $baseName , $configName ); } /** * Reverts a core configuration by reloading it from a module. * * Core configurations have a single site-wide instance. The form and * display configurations for an entity type's fields, for instance, * are core configurations. * * This method looks for a core configuration in the 'install' or * 'optional' folders across all installed modules. If not found, * FALSE is returned. If found, the configuration is loaded and used * to replace the current core configuration. * * @param string $configName * The name of the desired core configuration. * * @return bool * Returns TRUE if the configuration was reverted. FALSE is returned * if the configuration file could not be found. * * @see ::revertConfiguration() */ private static function revertCoreConfiguration(string $configName ) { // // Load file // --------- // The configuration file exists in several locations: // - The current cached configuration used each time Drupal boots. // - The original configuration loaded when the module was installed. // - The original optional configuration that might load on module install. // // We specifically want to replace the current cached configuration, // so that isn't the one to load here. // // We'd prefer to get the installed configuration, but it will not exist // if the configuration we're asked to load is for an optional feature // that was only added if other non-required modules were installed. // In that case, we need to switch from the non-existant installed // configuration to the optional configuration and load that. // // Get the configuration storage service. $configStorage = \Drupal::service( 'config.storage' ); // Try to load the install configuration, if any. $installStorage = new ExtensionInstallStorage( $configStorage , InstallStorage::CONFIG_INSTALL_DIRECTORY); $config = $installStorage ->read( $configName ); if ( empty ( $config ) === TRUE) { // The install configuration did not exist. Try to load the optional // configuration, if any. $optionalStorage = new ExtensionInstallStorage( $configStorage , InstallStorage::CONFIG_OPTIONAL_DIRECTORY); $config = $optionalStorage ->read( $configName ); if ( empty ( $config ) === TRUE) { // Neither the install or optional configuration directories found // the configuration we're after. Nothing more we can do. return FALSE; } } // // Revert // ------ // To revert to the newly loaded configuration, we need to get the // current cached ('sync') configuration and replace it. $configStorage ->write( $configName , $config ); return TRUE; } /** * Reverts an entity configuration by reloading it from a module. * * Entity configurations are entity instances with an ID and values for * entity fields. For instance, since a "view" is an entity instance, * the configuration of a specific view is an entity configuration. * These are individually stored in cache and in a module's configuration * folder. * * This method looks for an entity configuration in the 'install' or * 'optional' folders across all installed modules. If not found, * FALSE is returned. If found, the configuration is loaded and used * to create a new entity or replace an existing entity with the same * ID as that found in the configuration file. If the entity type cannot * be found, FALSE is returned. * * @param string $entityTypeId * The ID (name) of the entity type. * @param string $configName * The name of the desired entity configuration. * * @return bool * Returns TRUE if the configuration was reverted. FALSE is returned * if the entity type cannot be found, or if the configuration file * cannot be found. * * @see ::revertConfiguration() */ private static function revertEntityConfiguration( string $entityTypeId , string $configName ) { // Get entity info // --------------- // The incoming $entityTypeId names an entity type that has its // own storage manager and an entity type definition that we need // in order to build the full name of a configuration. try { // Get the entity's storage and definition. $entityTypeManager = \Drupal::entityTypeManager(); $entityStorage = $entityTypeManager ->getStorage( $entityTypeId ); $entityDefinition = $entityTypeManager ->getDefinition( $entityTypeId ); } catch (\Exception $e ) { // Unrecognized entity type! return FALSE; } // // Create name // ----------- // The full name of the configuration uses the given $configName, // prefixed with an entity type-specific prefix obtained from // the entity type definition. $fullName = $entityDefinition ->getConfigPrefix() . '.' . $configName ; // // Load file // --------- // The configuration file exists in several locations: // - The current cached configuration used each time Drupal boots. // - The original configuration loaded when the module was installed. // - The original optional configuration that might load on module install. // // We specifically want to replace the current cached configuration, // so that isn't the one to load here. // // We'd prefer to get the installed configuration, but it will not exist // if the configuration we're asked to load is for an optional feature // that was only added if other non-required modules were installed. // In that case, we need to switch from the non-existant installed // configuration to the optional configuration and load that. // // Get the configuration storage service. $configStorage = \Drupal::service( 'config.storage' ); // Try to load the install configuration, if any. $installStorage = new ExtensionInstallStorage( $configStorage , InstallStorage::CONFIG_INSTALL_DIRECTORY); $config = $installStorage ->read( $fullName ); if ( empty ( $config ) === TRUE) { // The install configuration did not exist. Try to load the optional // configuration, if any. $optionalStorage = new ExtensionInstallStorage( $configStorage , InstallStorage::CONFIG_OPTIONAL_DIRECTORY); $config = $optionalStorage ->read( $fullName ); if ( empty ( $config ) === TRUE) { // Neither the install or optional configuration directories found // the configuration we're after. Nothing more we can do. return FALSE; } } // // Load entity // ----------- // Entity configurations handled by this method are associated with // an entity, unsurprisingly. We need to load that entity as it is now // so that we can replace its fields with those loaded from the // configuration above. // // The entity might not exist if someone deleted it. This could happen // if a site administrator deleted a 'view' that this method is now // being called to restore. $idKey = $entityDefinition ->getKey( 'id' ); $id = $config [ $idKey ]; $currentEntity = $entityStorage ->load( $id ); // // Revert // ------ // If there is already an entity, update it with the loaded configuration. // And if there is not an entity, create a new one using the loaded // configuration. if ( $currentEntity === NULL) { // Create a new entity. $newEntity = $entityStorage ->createFromStorageRecord( $config ); } else { // Update the existing entity. $newEntity = $entityStorage ->updateFromStorageRecord( $currentEntity , $config ); } // Save the new or updated entity. $newEntity ->trustData(); $newEntity ->save(); return TRUE; } } |