annotate core/modules/node/node.install @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /**
Chris@0 4 * @file
Chris@0 5 * Install, update and uninstall functions for the node module.
Chris@0 6 */
Chris@0 7
Chris@18 8 use Drupal\Core\Url;
Chris@0 9 use Drupal\Core\Database\Database;
Chris@0 10 use Drupal\Core\Field\BaseFieldDefinition;
Chris@0 11 use Drupal\user\RoleInterface;
Chris@0 12
Chris@0 13 /**
Chris@0 14 * Implements hook_requirements().
Chris@0 15 */
Chris@0 16 function node_requirements($phase) {
Chris@0 17 $requirements = [];
Chris@0 18 if ($phase === 'runtime') {
Chris@0 19 // Only show rebuild button if there are either 0, or 2 or more, rows
Chris@0 20 // in the {node_access} table, or if there are modules that
Chris@0 21 // implement hook_node_grants().
Chris@0 22 $grant_count = \Drupal::entityManager()->getAccessControlHandler('node')->countGrants();
Chris@0 23 if ($grant_count != 1 || count(\Drupal::moduleHandler()->getImplementations('node_grants')) > 0) {
Chris@0 24 $value = \Drupal::translation()->formatPlural($grant_count, 'One permission in use', '@count permissions in use', ['@count' => $grant_count]);
Chris@0 25 }
Chris@0 26 else {
Chris@0 27 $value = t('Disabled');
Chris@0 28 }
Chris@0 29
Chris@0 30 $requirements['node_access'] = [
Chris@0 31 'title' => t('Node Access Permissions'),
Chris@0 32 'value' => $value,
Chris@0 33 'description' => t('If the site is experiencing problems with permissions to content, you may have to rebuild the permissions cache. Rebuilding will remove all privileges to content and replace them with permissions based on the current modules and settings. Rebuilding may take some time if there is a lot of content or complex permission settings. After rebuilding has completed, content will automatically use the new permissions. <a href=":rebuild">Rebuild permissions</a>', [
Chris@18 34 ':rebuild' => Url::fromRoute('node.configure_rebuild_confirm')->toString(),
Chris@0 35 ]),
Chris@0 36 ];
Chris@0 37 }
Chris@0 38 return $requirements;
Chris@0 39 }
Chris@0 40
Chris@0 41 /**
Chris@0 42 * Implements hook_schema().
Chris@0 43 */
Chris@0 44 function node_schema() {
Chris@0 45 $schema['node_access'] = [
Chris@0 46 'description' => 'Identifies which realm/grant pairs a user must possess in order to view, update, or delete specific nodes.',
Chris@0 47 'fields' => [
Chris@0 48 'nid' => [
Chris@0 49 'description' => 'The {node}.nid this record affects.',
Chris@0 50 'type' => 'int',
Chris@0 51 'unsigned' => TRUE,
Chris@0 52 'not null' => TRUE,
Chris@0 53 'default' => 0,
Chris@0 54 ],
Chris@0 55 'langcode' => [
Chris@0 56 'description' => 'The {language}.langcode of this node.',
Chris@0 57 'type' => 'varchar_ascii',
Chris@0 58 'length' => 12,
Chris@0 59 'not null' => TRUE,
Chris@0 60 'default' => '',
Chris@0 61 ],
Chris@0 62 'fallback' => [
Chris@0 63 'description' => 'Boolean indicating whether this record should be used as a fallback if a language condition is not provided.',
Chris@0 64 'type' => 'int',
Chris@0 65 'unsigned' => TRUE,
Chris@0 66 'not null' => TRUE,
Chris@0 67 'default' => 1,
Chris@0 68 'size' => 'tiny',
Chris@0 69 ],
Chris@0 70 'gid' => [
Chris@0 71 'description' => "The grant ID a user must possess in the specified realm to gain this row's privileges on the node.",
Chris@0 72 'type' => 'int',
Chris@0 73 'unsigned' => TRUE,
Chris@0 74 'not null' => TRUE,
Chris@0 75 'default' => 0,
Chris@0 76 ],
Chris@0 77 'realm' => [
Chris@0 78 'description' => 'The realm in which the user must possess the grant ID. Modules can define one or more realms by implementing hook_node_grants().',
Chris@0 79 'type' => 'varchar_ascii',
Chris@0 80 'length' => 255,
Chris@0 81 'not null' => TRUE,
Chris@0 82 'default' => '',
Chris@0 83 ],
Chris@0 84 'grant_view' => [
Chris@0 85 'description' => 'Boolean indicating whether a user with the realm/grant pair can view this node.',
Chris@0 86 'type' => 'int',
Chris@0 87 'unsigned' => TRUE,
Chris@0 88 'not null' => TRUE,
Chris@0 89 'default' => 0,
Chris@0 90 'size' => 'tiny',
Chris@0 91 ],
Chris@0 92 'grant_update' => [
Chris@0 93 'description' => 'Boolean indicating whether a user with the realm/grant pair can edit this node.',
Chris@0 94 'type' => 'int',
Chris@0 95 'unsigned' => TRUE,
Chris@0 96 'not null' => TRUE,
Chris@0 97 'default' => 0,
Chris@0 98 'size' => 'tiny',
Chris@0 99 ],
Chris@0 100 'grant_delete' => [
Chris@0 101 'description' => 'Boolean indicating whether a user with the realm/grant pair can delete this node.',
Chris@0 102 'type' => 'int',
Chris@0 103 'unsigned' => TRUE,
Chris@0 104 'not null' => TRUE,
Chris@0 105 'default' => 0,
Chris@0 106 'size' => 'tiny',
Chris@0 107 ],
Chris@0 108 ],
Chris@0 109 'primary key' => ['nid', 'gid', 'realm', 'langcode'],
Chris@0 110 'foreign keys' => [
Chris@0 111 'affected_node' => [
Chris@0 112 'table' => 'node',
Chris@0 113 'columns' => ['nid' => 'nid'],
Chris@0 114 ],
Chris@0 115 ],
Chris@0 116 ];
Chris@0 117
Chris@0 118 return $schema;
Chris@0 119 }
Chris@0 120
Chris@0 121 /**
Chris@0 122 * Implements hook_install().
Chris@0 123 */
Chris@0 124 function node_install() {
Chris@0 125 // Enable default permissions for system roles.
Chris@0 126 // IMPORTANT: Modules SHOULD NOT automatically grant any user role access
Chris@0 127 // permissions in hook_install().
Chris@0 128 // However, the 'access content' permission is a very special case, since
Chris@0 129 // there is hardly a point in installing the Node module without granting
Chris@0 130 // these permissions. Doing so also allows tests to continue to operate as
Chris@0 131 // expected without first having to manually grant these default permissions.
Chris@0 132 if (\Drupal::moduleHandler()->moduleExists('user')) {
Chris@0 133 user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, ['access content']);
Chris@0 134 user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, ['access content']);
Chris@0 135 }
Chris@0 136
Chris@0 137 // Populate the node access table.
Chris@18 138 Database::getConnection()->insert('node_access')
Chris@0 139 ->fields([
Chris@0 140 'nid' => 0,
Chris@0 141 'gid' => 0,
Chris@0 142 'realm' => 'all',
Chris@0 143 'grant_view' => 1,
Chris@0 144 'grant_update' => 0,
Chris@0 145 'grant_delete' => 0,
Chris@0 146 ])
Chris@0 147 ->execute();
Chris@0 148 }
Chris@0 149
Chris@0 150 /**
Chris@0 151 * Implements hook_uninstall().
Chris@0 152 */
Chris@0 153 function node_uninstall() {
Chris@0 154 // Delete remaining general module variables.
Chris@0 155 \Drupal::state()->delete('node.node_access_needs_rebuild');
Chris@0 156 }
Chris@0 157
Chris@0 158 /**
Chris@0 159 * Add 'revision_translation_affected' field to 'node' entities.
Chris@0 160 */
Chris@0 161 function node_update_8001() {
Chris@0 162 // Install the definition that this field had in
Chris@0 163 // \Drupal\node\Entity\Node::baseFieldDefinitions()
Chris@0 164 // at the time that this update function was written. If/when code is
Chris@0 165 // deployed that changes that definition, the corresponding module must
Chris@0 166 // implement an update function that invokes
Chris@0 167 // \Drupal::entityDefinitionUpdateManager()->updateFieldStorageDefinition()
Chris@0 168 // with the new definition.
Chris@0 169 $storage_definition = BaseFieldDefinition::create('boolean')
Chris@0 170 ->setLabel(t('Revision translation affected'))
Chris@0 171 ->setDescription(t('Indicates if the last edit of a translation belongs to current revision.'))
Chris@0 172 ->setReadOnly(TRUE)
Chris@0 173 ->setRevisionable(TRUE)
Chris@0 174 ->setTranslatable(TRUE);
Chris@0 175
Chris@0 176 \Drupal::entityDefinitionUpdateManager()
Chris@0 177 ->installFieldStorageDefinition('revision_translation_affected', 'node', 'node', $storage_definition);
Chris@0 178 }
Chris@0 179
Chris@0 180 /**
Chris@0 181 * Remove obsolete indexes from the node schema.
Chris@0 182 */
Chris@0 183 function node_update_8002() {
Chris@0 184 // The "node__default_langcode" and "node_field__langcode" indexes were
Chris@0 185 // removed from \Drupal\node\NodeStorageSchema in
Chris@0 186 // https://www.drupal.org/node/2261669, but this update function wasn't
Chris@0 187 // added until https://www.drupal.org/node/2542748. Regenerate the related
Chris@0 188 // schemas to ensure they match the currently expected status.
Chris@0 189 $manager = \Drupal::entityDefinitionUpdateManager();
Chris@0 190 // Regenerate entity type indexes, this should drop "node__default_langcode".
Chris@0 191 $manager->updateEntityType($manager->getEntityType('node'));
Chris@0 192 // Regenerate "langcode" indexes, this should drop "node_field__langcode".
Chris@0 193 $manager->updateFieldStorageDefinition($manager->getFieldStorageDefinition('langcode', 'node'));
Chris@0 194 }
Chris@0 195
Chris@0 196 /**
Chris@0 197 * Promote 'status' and 'uid' fields to entity keys.
Chris@0 198 */
Chris@0 199 function node_update_8003() {
Chris@0 200 // The 'status' and 'uid' fields were added to the 'entity_keys' annotation
Chris@0 201 // of \Drupal\node\Entity\Node in https://www.drupal.org/node/2498919, but
Chris@0 202 // this update function wasn't added until
Chris@0 203 // https://www.drupal.org/node/2542748.
Chris@0 204 $manager = \Drupal::entityDefinitionUpdateManager();
Chris@0 205 $entity_type = $manager->getEntityType('node');
Chris@0 206 $entity_keys = $entity_type->getKeys();
Chris@0 207 $entity_keys['status'] = 'status';
Chris@0 208 $entity_keys['uid'] = 'uid';
Chris@0 209 $entity_type->set('entity_keys', $entity_keys);
Chris@0 210 $manager->updateEntityType($entity_type);
Chris@0 211
Chris@0 212 // @todo The above should be enough, since that is the only definition that
Chris@0 213 // changed. But \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema varies
Chris@0 214 // field schema by whether a field is an entity key, so invoke
Chris@0 215 // EntityDefinitionUpdateManagerInterface::updateFieldStorageDefinition()
Chris@0 216 // with an unmodified field storage definition to trigger the necessary
Chris@0 217 // changes. SqlContentEntityStorageSchema::onEntityTypeUpdate() should be
Chris@0 218 // fixed to automatically handle this.
Chris@0 219 // See https://www.drupal.org/node/2554245.
Chris@0 220 foreach (['status', 'uid'] as $field_name) {
Chris@0 221 $manager->updateFieldStorageDefinition($manager->getFieldStorageDefinition($field_name, 'node'));
Chris@0 222 }
Chris@0 223 }
Chris@0 224
Chris@0 225 /**
Chris@0 226 * Change {node_access}.fallback from an int to a tinyint as it is a boolean.
Chris@0 227 */
Chris@0 228 function node_update_8300() {
Chris@0 229 Database::getConnection()->schema()->changeField('node_access', 'fallback', 'fallback', [
Chris@0 230 'description' => 'Boolean indicating whether this record should be used as a fallback if a language condition is not provided.',
Chris@0 231 'type' => 'int',
Chris@0 232 'unsigned' => TRUE,
Chris@0 233 'not null' => TRUE,
Chris@0 234 'default' => 1,
Chris@0 235 'size' => 'tiny',
Chris@0 236 ]);
Chris@0 237 }
Chris@0 238
Chris@0 239 /**
Chris@0 240 * Set the 'published' entity key.
Chris@0 241 */
Chris@0 242 function node_update_8301() {
Chris@0 243 $definition_update_manager = \Drupal::entityDefinitionUpdateManager();
Chris@0 244 $entity_type = $definition_update_manager->getEntityType('node');
Chris@0 245 $keys = $entity_type->getKeys();
Chris@0 246 $keys['published'] = 'status';
Chris@0 247 $entity_type->set('entity_keys', $keys);
Chris@0 248 $definition_update_manager->updateEntityType($entity_type);
Chris@0 249 }
Chris@0 250
Chris@0 251 /**
Chris@0 252 * Fix realm column description on the node_access table.
Chris@0 253 */
Chris@0 254 function node_update_8400() {
Chris@0 255 $schema = drupal_get_module_schema('node', 'node_access');
Chris@0 256 $schema['fields']['realm']['description'] = 'The realm in which the user must possess the grant ID. Modules can define one or more realms by implementing hook_node_grants().';
Chris@0 257 Database::getConnection()->schema()->changeField('node_access', 'realm', 'realm', $schema['fields']['realm']);
Chris@0 258 }
Chris@12 259
Chris@12 260 /**
Chris@12 261 * Run a node access rebuild, if required.
Chris@12 262 */
Chris@12 263 function node_update_8401() {
Chris@12 264 // Get the list of node access modules.
Chris@12 265 $modules = \Drupal::moduleHandler()->getImplementations('node_grants');
Chris@12 266 // If multilingual usage, then rebuild node access.
Chris@12 267 if (count($modules) > 0 && \Drupal::languageManager()->isMultilingual()) {
Chris@12 268 node_access_needs_rebuild(TRUE);
Chris@12 269 }
Chris@12 270 }
Chris@18 271
Chris@18 272 /**
Chris@18 273 * Set the 'owner' entity key and update the field.
Chris@18 274 */
Chris@18 275 function node_update_8700() {
Chris@18 276 $definition_update_manager = \Drupal::entityDefinitionUpdateManager();
Chris@18 277 $entity_type = $definition_update_manager->getEntityType('node');
Chris@18 278 $keys = $entity_type->getKeys();
Chris@18 279 $keys['owner'] = 'uid';
Chris@18 280 $entity_type->set('entity_keys', $keys);
Chris@18 281 $definition_update_manager->updateEntityType($entity_type);
Chris@18 282 $definition_update_manager->updateFieldStorageDefinition($definition_update_manager->getFieldStorageDefinition('uid', 'node'));
Chris@18 283 }