You are here

pwa_webpush.install in Progressive Web App 7.2

File

modules/pwa_webpush/pwa_webpush.install
View source
<?php

/**
 * @file
 */

/**
 * Implements hook_requirements().
 */
function pwa_webpush_requirements($phase) {
  $requirements = [];
  $t = get_t();

  // Include composer dependencies here to make it available everywhere.
  if (!class_exists('\\Minishlink\\WebPush\\WebPush')) {
    $folders = [
      // The vendor repository will be at the PWA module root.
      __DIR__ . '/../..',
      DRUPAL_ROOT,
      DRUPAL_ROOT . '/..',
    ];
    foreach ($folders as $folder) {
      if (file_exists($folder . '/vendor/autoload.php')) {
        require $folder . '/vendor/autoload.php';
        break;
      }
    }
  }

  // Make sure the PHP library is available to be able to use the module.
  $php_library = class_exists('\\Minishlink\\WebPush\\WebPush');
  if (!$php_library) {
    $requirements['pwa_webpush_library'] = [
      'title' => $t('WebPush PHP library'),
      'severity' => REQUIREMENT_WARNING,
      'description' => $t('PWA WebPush requires the <a href="@library_url">minishlink/web-push</a> library to be installed. Users can register for push notification but it is not possible to send push notifications from the website.', [
        '@library_url' => 'https://github.com/web-push-libs/web-push-php',
      ]),
    ];
  }
  if ($phase !== 'runtime') {
    return $requirements;
  }
  if ($php_library) {
    $version = FALSE;

    // Try to find the version of the library by looking into the
    // 'installed.json' file create by composer.
    if (class_exists('\\Composer\\Autoload\\ClassLoader')) {
      $reflector = new \ReflectionClass('\\Composer\\Autoload\\ClassLoader');
      $composer_path = pathinfo($reflector
        ->getFileName(), PATHINFO_DIRNAME);
      $installed = drupal_json_decode(file_get_contents($composer_path . '/installed.json'));
      foreach ($installed as $package) {
        if ($package['name'] === 'minishlink/web-push') {
          $version = $package['version'];
          break;
        }
      }
    }
    $requirements['pwa_webpush_library'] = [
      'title' => $t('WebPush PHP library'),
      'value' => $version,
      'severity' => REQUIREMENT_OK,
    ];
  }
  $requirements['pwa_webpush_vapid_key'] = [
    'title' => $t('WebPush VAPID Private Key'),
  ];

  // Make sure that the keys are not stored in the database.
  $result = db_query("SELECT value FROM {variable} WHERE name = 'pwa_webpush_vapid_private'")
    ->fetchField();
  if ($result) {

    // Check that the value in the Database is not overwritten in the settings.
    $db_key = unserialize($result);
    $key_is_in_db = variable_get('pwa_webpush_vapid_private') === $db_key;
    if ($key_is_in_db) {
      $requirements['pwa_webpush_vapid_key'] += [
        'severity' => REQUIREMENT_ERROR,
        'description' => $t('The private key is stored in the database. Move the private key in the settings file and remove the corresponding row in the variable table.'),
      ];
    }
    else {
      $requirements['pwa_webpush_vapid_key'] += [
        'severity' => REQUIREMENT_WARNING,
        'description' => $t('An outdated private key is stored in the database, delete the <code>pwa_webpush_vapid_private</code> row from the <code>variable</code> table.'),
      ];
    }
  }
  else {
    $requirements['pwa_webpush_vapid_key'] += [
      'severity' => REQUIREMENT_OK,
      'description' => $t('The VAPID private key is not stored in the DB. Make sure the key is not saved alongside the source code.'),
    ];
  }
  return $requirements;
}

/**
 * Implements hook_schema()
 *
 * @return array
 */
function pwa_webpush_schema() {
  $schema = [];
  $schema['pwa_webpush_subscription'] = [
    'description' => 'Stores browser push notification subscriptions',
    'fields' => [
      'sid' => [
        'type' => 'serial',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'description' => 'Primary Key: Unique subscription ID.',
      ],
      'uid' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => "User's {users}.uid.",
      ],
      'created' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'The Unix timestamp when the subscription was created.',
      ],
      'last_used' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'The Unix timestamp when the subscription was last used successfully.',
      ],
      'expired' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'The Unix timestamp when the subscription expired.',
      ],
      'endpoint_sha256' => [
        'type' => 'varchar',
        'length' => 64,
        'not null' => TRUE,
        'description' => 'sha256 of the enpoint URL',
      ],
      'json' => [
        'type' => 'text',
        'size' => 'normal',
        'not null' => TRUE,
        'description' => 'JSON serialization of the subscription sent by the browser',
      ],
    ],
    'unique keys' => [
      'keys' => [
        'endpoint_sha256',
      ],
    ],
    'primary key' => [
      'sid',
    ],
    'foreign keys' => [
      'user' => [
        'table' => 'users',
        'columns' => [
          'uid' => 'uid',
        ],
      ],
    ],
    'indexes' => [
      'current_status' => [
        'uid',
        'expired',
        'created',
        'last_used',
      ],
    ],
  ];
  return $schema;
}

/**
 * Implements hook_install().
 */
function pwa_webpush_install() {
  user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, [
    'access pwa webpush',
  ]);
  user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, [
    'access pwa webpush',
  ]);

  // Set default settings.
  $vapid_settings = [
    'pwa_webpush_vapid_subject' => 'mailto:' . variable_get('site_mail', ''),
  ];

  // Include composer dependencies here to make it available everywhere.
  if (!class_exists('\\Minishlink\\WebPush\\WebPush')) {
    $folders = [
      // The vendor repository will be at the PWA module root.
      __DIR__ . '/../..',
      DRUPAL_ROOT,
      DRUPAL_ROOT . '/..',
    ];
    foreach ($folders as $folder) {
      if (file_exists($folder . '/vendor/autoload.php')) {
        require $folder . '/vendor/autoload.php';
        break;
      }
    }
  }
  if (class_exists('\\Minishlink\\WebPush\\VAPID')) {
    $keys = \Minishlink\WebPush\VAPID::createVapidKeys();
    $vapid_settings['pwa_webpush_vapid_public'] = $keys['publicKey'];
    $vapid_settings['pwa_webpush_vapid_private'] = $keys['privateKey'];
  }
  foreach ($vapid_settings as $key => $default) {

    // Only set variables if they do not exist.
    if (empty(variable_get($key, ''))) {
      variable_set($key, $default);
    }
  }
}

/**
 * Implements hook_uninstall().
 */
function pwa_webpush_uninstall() {

  // Remove variables.
  db_delete('variable')
    ->condition('name', 'pwa_webpush_%', 'LIKE')
    ->execute();
  cache_clear_all('variables', 'cache_bootstrap');
}