Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
smart_date-3433115
Manage
Activity
Members
Labels
Plan
Custom issue tracker
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Model registry
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Issue forks
smart_date-3433115
Commits
64ccec89
Commit
64ccec89
authored
1 year ago
by
Martin Anderson-Clutz
Browse files
Options
Downloads
Patches
Plain Diff
Issue
#3304395
by mandclu: Far-future dates cause WSOD, "Numeric value out of range"
parent
1e0097ab
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
smart_date.post_update.php
+143
-0
143 additions, 0 deletions
smart_date.post_update.php
src/Plugin/Field/FieldType/SmartDateItem.php
+2
-0
2 additions, 0 deletions
src/Plugin/Field/FieldType/SmartDateItem.php
with
145 additions
and
0 deletions
smart_date.post_update.php
+
143
−
0
View file @
64ccec89
...
...
@@ -7,6 +7,10 @@
use
Drupal\Core\Config\FileStorage
;
use
Drupal\Core\Entity\Entity\EntityViewDisplay
;
use
Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException
;
use
Drupal\Core\Entity\Schema\DynamicallyFieldableEntityStorageSchemaInterface
;
use
Drupal\Core\Entity\Sql\SqlContentEntityStorage
;
use
Drupal\smart_date
\Plugin\Field\FieldType\SmartDateItem
;
/**
* Clear caches to ensure schema changes are read.
...
...
@@ -61,3 +65,142 @@ function smart_date_post_update_translatable_config() {
$storage
->
create
(
$source
->
read
(
'smart_date.smart_date_format.time_only'
))
->
save
();
}
/**
* Increase the storage size to resolve the 2038 problem.
*/
function
smart_date_post_update_increase_column_storage
(
&
$sandbox
)
:
void
{
if
(
!
isset
(
$sandbox
[
'items'
]))
{
$items
=
_smart_date_update_get_smart_date_fields
();
$sandbox
[
'items'
]
=
$items
;
$sandbox
[
'current'
]
=
0
;
$sandbox
[
'num_processed'
]
=
0
;
$sandbox
[
'max'
]
=
count
(
$items
);
}
[
$entity_type_id
,
$field_name
]
=
$sandbox
[
'items'
][
$sandbox
[
'current'
]];
if
(
$entity_type_id
&&
$field_name
)
{
_smart_date_update_process_smart_date_field
(
$entity_type_id
,
$field_name
);
}
$sandbox
[
'current'
]
++
;
$sandbox
[
'#finished'
]
=
empty
(
$sandbox
[
'max'
])
?
1
:
(
$sandbox
[
'current'
]
/
$sandbox
[
'max'
]);
}
/**
* Gets a list fields that use the SmartDateItem class.
*
* @return string[]
* An array with two elements, an entity type ID and a field name.
*/
function
_smart_date_update_get_smart_date_fields
():
array
{
$items
=
[];
// Get all the field definitions.
$field_definitions
=
\Drupal
::
service
(
'plugin.manager.field.field_type'
)
->
getDefinitions
();
// Get all the field types that use the SmartDateItem class.
$field_types
=
array_keys
(
array_filter
(
$field_definitions
,
function
(
$definition
)
{
return
is_a
(
$definition
[
'class'
],
SmartDateItem
::
class
,
TRUE
);
}));
/** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager */
$entity_field_manager
=
\Drupal
::
service
(
'entity_field.manager'
);
// Build a list of all the Smart Date fields.
foreach
(
$field_types
as
$field_type
)
{
$entity_field_map
=
$entity_field_manager
->
getFieldMapByFieldType
(
$field_type
);
foreach
(
$entity_field_map
as
$entity_type_id
=>
$fields
)
{
$storage
=
\Drupal
::
entityTypeManager
()
->
getStorage
(
$entity_type_id
);
if
(
$storage
instanceof
SqlContentEntityStorage
)
{
foreach
(
array_keys
(
$fields
)
as
$field_name
)
{
$items
[]
=
[
$entity_type_id
,
$field_name
];
}
$storage
->
resetCache
();
}
}
}
return
$items
;
}
/**
* Update a Smart Date field to remove Y2038 limitation.
*
* @param string $entity_type_id
* The entity type ID.
* @param string $field_name
* The name of the field that needs to be updated.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\Sql\SqlContentEntityStorageException
*/
function
_smart_date_update_process_smart_date_field
(
string
$entity_type_id
,
string
$field_name
):
void
{
/** @var \Drupal\Core\Logger\LoggerChannel $logger */
$logger
=
\Drupal
::
logger
(
'update'
);
$storage_definitions
=
\Drupal
::
service
(
'entity_field.manager'
)
->
getFieldStorageDefinitions
(
$entity_type_id
);
$entity_type_manager
=
\Drupal
::
entityTypeManager
();
$entity_type_manager
->
useCaches
(
FALSE
);
$entity_storage
=
$entity_type_manager
->
getStorage
(
$entity_type_id
);
// Get the table mappings for this field.
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
$table_mapping
=
$entity_storage
->
getTableMapping
(
$storage_definitions
);
// Field type column names map to real table column names.
$columns
=
$table_mapping
->
getColumnNames
(
$field_name
);
$column_names
=
[];
if
(
$columns
[
'value'
])
{
$column_names
[
'value'
]
=
$columns
[
'value'
];
}
if
(
$columns
[
'end_value'
])
{
$column_names
[
'end_value'
]
=
$columns
[
'end_value'
];
}
// We are allowed to change 'value' and 'end_value' columns, so if those do
// not exist due contrib or custom alters leave everything unchanged.
if
(
!
$column_names
)
{
$logger
->
notice
(
"Smart Date timestamps for entity '
$entity_type_id
' field '
$field_name
' not updated because database columns were not found."
);
return
;
}
// Get the original storage definition for this field.
$last_installed_schema_repository
=
\Drupal
::
service
(
'entity.last_installed_schema.repository'
);
$original_storage_definitions
=
$last_installed_schema_repository
->
getLastInstalledFieldStorageDefinitions
(
$entity_type_id
);
$original_storage_definition
=
$original_storage_definitions
[
$field_name
];
// Get the current storage definition for this field.
$storage_definition
=
$storage_definitions
[
$field_name
];
$storage
=
$entity_type_manager
->
getStorage
(
$storage_definition
->
getTargetEntityTypeId
());
if
(
!
(
$storage
instanceof
DynamicallyFieldableEntityStorageSchemaInterface
&&
$storage
->
requiresFieldStorageSchemaChanges
(
$storage_definition
,
$original_storage_definition
)))
{
$logger
->
notice
(
"Timestamp for entity '
$entity_type_id
' field '
$field_name
' not updated because field size is already 'big'."
);
return
;
}
$schema
=
\Drupal
::
database
()
->
schema
();
$field_schema
=
$original_storage_definitions
[
$field_name
]
->
getSchema
()
??
$storage_definition
->
getSchema
();
$specification
=
$field_schema
[
'columns'
][
'value'
];
$specification
[
'size'
]
=
'big'
;
foreach
(
$column_names
as
$column_name
)
{
// Update the table specification for the timestamp field, setting the size
// to 'big'.
foreach
(
$table_mapping
->
getAllFieldTableNames
(
$field_name
)
as
$table
)
{
$schema
->
changeField
(
$table
,
$column_name
,
$column_name
,
$specification
);
}
}
// Update the tracked entity table schema, setting the size to 'big'.
/** @var \Drupal\Core\Entity\EntityDefinitionUpdateManager $mgr */
try
{
\Drupal
::
service
(
'entity.definition_update_manager'
)
->
updateFieldStorageDefinition
(
$storage_definition
);
}
catch
(
FieldStorageDefinitionUpdateForbiddenException
$e
)
{
}
$logger
->
notice
(
"Successfully updated entity '
$entity_type_id
' field '
$field_name
' to remove year 2038 limitation."
);
}
This diff is collapsed.
Click to expand it.
src/Plugin/Field/FieldType/SmartDateItem.php
+
2
−
0
View file @
64ccec89
...
...
@@ -90,10 +90,12 @@ class SmartDateItem extends TimestampItem {
'value'
=>
[
'description'
=>
'The start time value.'
,
'type'
=>
'int'
,
'size'
=>
'big'
,
],
'end_value'
=>
[
'description'
=>
'The end time value.'
,
'type'
=>
'int'
,
'size'
=>
'big'
,
],
'duration'
=>
[
'description'
=>
'The difference between start and end times, in minutes.'
,
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment