View source
<?php
function pwa_requirements($phase) {
$requirements = [];
if ($phase !== 'runtime') {
return $requirements;
}
$t = get_t();
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' || isset($_SERVER["REQUEST_SCHEME"]) && $_SERVER["REQUEST_SCHEME"] === 'https') {
$requirements['pwa'] = array(
'title' => $t('Progressive Web App'),
'value' => $t('HTTPS on'),
'severity' => REQUIREMENT_OK,
'description' => $t('Please make sure the certificate of %domain is valid for offline functionality to work.', [
'%domain' => $_SERVER['HTTP_HOST'],
]),
'weight' => 1,
);
}
elseif (in_array($_SERVER['HTTP_HOST'], [
'localhost',
'127.0.0.1',
])) {
$requirements['pwa'] = array(
'title' => $t('Progressive Web App'),
'value' => 'localhost',
'severity' => REQUIREMENT_WARNING,
'description' => $t('You will need to configure HTTPS on your production site for the Progressive Web App to function.'),
'weight' => 1,
);
}
else {
$requirements['pwa'] = array(
'title' => $t('Progressive Web App'),
'value' => $t('HTTPS off'),
'severity' => REQUIREMENT_ERROR,
'description' => $t('HTTPS needs to be configured to enable your Progressive Web App. Without a secure connection, the Service Worker will not install itself.'),
'weight' => 1,
);
}
if (empty(variable_get('pwa_description', ''))) {
$requirements['pwa_description'] = array(
'title' => $t('PWA manifest'),
'value' => $t('description'),
'severity' => REQUIREMENT_WARNING,
'description' => $t('The <a href="@manifest_url">manifest description</a> is required for the PWA to be <a href="@windows_pwa_url">automatically included</a> in the Microsoft Store.', [
'@manifest_url' => url('/admin/config/pwa/settings', [
'fragment' => 'edit-pwa-description',
]),
'@windows_pwa_url' => 'https://docs.microsoft.com/en-us/microsoft-edge/progressive-web-apps-edgehtml/microsoft-store#criteria-for-automatic-submission',
]),
'weight' => 2,
);
}
$manifest = pwa_file_data('manifest');
if (empty($manifest['icons'])) {
$requirements['pwa_icons'] = array(
'title' => $t('PWA manifest icons'),
'value' => $t('No icons'),
'severity' => REQUIREMENT_ERROR,
'description' => $t('There are no icons declared in the manifest file. The PWA will not be installable.'),
'weight' => 2,
);
}
else {
$has_192 = FALSE;
$has_512 = FALSE;
$has_monochrome = FALSE;
foreach ($manifest['icons'] as $icon) {
if ($icon['sizes'] === '192x192' && stripos($icon['purpose'], 'maskable') !== FALSE) {
$has_192 = TRUE;
}
if ($icon['sizes'] === '512x512' && stripos($icon['purpose'], 'maskable') !== FALSE) {
$has_512 = TRUE;
}
if ($icon['sizes'] === '16x16' && $icon['purpose'] === 'monochrome' && stripos($icon['type'], 'svg') !== FALSE) {
$has_monochrome = TRUE;
}
}
if (!$has_192 || !$has_512) {
$requirements['pwa_icons'] = array(
'title' => $t('PWA manifest icons'),
'value' => $t('Missing %icons sizes', [
'%icons' => trim(implode(' ', [
$has_192 ? '' : '192x192',
$has_512 ? '' : '512x512',
])),
]),
'severity' => REQUIREMENT_ERROR,
'description' => $t('Icons with these measurements are required to allow an optimal experience and a full lighthouse score.'),
'weight' => 2,
);
}
if (variable_get('pwa_apple_meta_enable') && !$has_monochrome) {
$requirements['pwa_icons_apple'] = array(
'title' => $t('PWA Safari pinned tab icon'),
'value' => $t('Missing 16x16 monochrome'),
'severity' => REQUIREMENT_WARNING,
'description' => $t('A SVG icon with the purpose "monochrome" is missing to ensure integration with <a href="@monochrome_url">safari pinned tabs</a>. This will be used by the PWA module to add the appropriate meta tag on the page.', [
'@monochrome_url' => 'https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/pinnedTabs/pinnedTabs.html',
]),
'weight' => 2,
);
}
}
return $requirements;
}
function _init_variables() {
variable_set('pwa_sw_cache_exclude', PWA_SW_CACHE_EXCLUDE);
variable_set('pwa_sw_precache_page', '');
variable_set('pwa_sw_precache_asset', '');
variable_set('pwa_sw_patterns_page', '');
variable_set('pwa_sw_patterns_asset', '');
variable_set('pwa_sw_asset_config', PWA_SW_ASSETS);
}
function pwa_install() {
_init_variables();
user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, [
'access pwa',
]);
user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, [
'access pwa',
]);
}
function pwa_uninstall() {
db_delete('variable')
->condition('name', 'pwa_%', 'LIKE')
->execute();
cache_clear_all('variables', 'cache_bootstrap');
}
function pwa_update_7201() {
$exclude = variable_get('pwa_sw_cache_exclude', FALSE);
_init_variables();
$mapping = [
'pwa_sw_cache_urls' => 'pwa_sw_precache_page',
'pwa_sw_cache_url_patterns' => 'pwa_sw_cache_patterns_page',
];
foreach ($mapping as $before => $after) {
$value = _pwa_config_value_split($before, '');
variable_del($before);
foreach ($value as $index => $path) {
if ($path == '/' || $path == '/offline') {
unset($value[$index]);
}
}
variable_set($after, implode("\n", array_filter($value)));
}
if ($exclude) {
variable_set('pwa_sw_cache_exclude', $exclude);
}
variable_del('pwa_filecache_manifest');
if (variable_get('pwa_theme_color', '') == '#ffffff') {
variable_set('pwa_theme_color', '#53B0EB');
}
if (variable_get('pwa_background_color', '') == '#ffffff') {
variable_set('pwa_background_color', '#F6F6F2');
}
if (variable_get('pwa_start_url', '') == '/') {
variable_set('pwa_start_url', '/?source=pwa');
}
file_unmanaged_delete('public://pwa/manifest.json');
file_unmanaged_delete('private://pwa/manifest.json');
return 'Variables renamed.';
}
function pwa_update_7202() {
$roles = db_query('SELECT rid FROM {role}')
->fetchCol();
$permissions = user_role_permissions($roles);
foreach ($permissions as $rid => $perms) {
if (array_key_exists('administer pwa', $perms)) {
user_role_change_permissions($rid, [
'administer pwa' => FALSE,
'administer pwa manifest' => TRUE,
'administer pwa serviceworker' => TRUE,
]);
}
}
return 'PWA administrative permissions updated.';
}
function pwa_update_7203() {
variable_del('pwa_sw_registration_event');
return 'Variable removed.';
}
function pwa_update_7204() {
variable_set('pwa_sw_asset_config', PWA_SW_ASSETS);
variable_del('pwa_sw_type_asset');
$values = _pwa_config_value_split('pwa_sw_cache_exclude', PWA_SW_CACHE_EXCLUDE);
foreach ($values as &$value) {
$value = '^' . ($value[0] === '/' ? '' : '/') . $value;
}
variable_set('pwa_sw_cache_exclude', implode("\n", $values));
return 'Default cache configuration for assets installed.';
}