owncloud/core

View on GitHub
apps/updatenotification/lib/Notification/BackgroundJob.php

Summary

Maintainability
A
1 hr
Test Coverage
<?php
/**
 * @author Joas Schilling <coding@schilljs.com>
 *
 * @copyright Copyright (c) 2018, ownCloud GmbH
 * @license AGPL-3.0
 *
 * This code is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License, version 3,
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */

namespace OCA\UpdateNotification\Notification;

use OC\BackgroundJob\TimedJob;
use OC\Updater\VersionCheck;
use OCP\App\IAppManager;
use OCP\Http\Client\IClientService;
use OCP\IConfig;
use OCP\IGroup;
use OCP\IGroupManager;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\Notification\IManager;

class BackgroundJob extends TimedJob {
    /** @var IConfig */
    protected $config;

    /** @var IManager */
    protected $notificationManager;

    /** @var IGroupManager */
    protected $groupManager;

    /** @var IAppManager */
    protected $appManager;

    /** @var IClientService */
    protected $client;

    /** @var IURLGenerator */
    protected $urlGenerator;

    /** @var IUser[] */
    protected $users;

    /**
     * NotificationBackgroundJob constructor.
     *
     * @param IConfig $config
     * @param IManager $notificationManager
     * @param IGroupManager $groupManager
     * @param IAppManager $appManager
     * @param IClientService $client
     * @param IURLGenerator $urlGenerator
     */
    public function __construct(IConfig $config, IManager $notificationManager, IGroupManager $groupManager, IAppManager $appManager, IClientService $client, IURLGenerator $urlGenerator) {
        // Run once a day
        $this->setInterval(60 * 60 * 24);

        $this->config = $config;
        $this->notificationManager = $notificationManager;
        $this->groupManager = $groupManager;
        $this->appManager = $appManager;
        $this->client = $client;
        $this->urlGenerator = $urlGenerator;
    }

    protected function run($argument) {
        $this->checkCoreUpdate();
    }

    /**
     * Check for ownCloud update
     */
    protected function checkCoreUpdate() {
        if (\in_array($this->getChannel(), ['daily', 'git'])) {
            // "These aren't the update channels you're looking for." - Ben Obi-Wan Kenobi
            return;
        }

        $updater = $this->createVersionCheck();

        $status = $updater->check();
        if (isset($status['version'])) {
            $url = $this->urlGenerator->linkToRoute('settings.SettingsPage.getAdmin') . '#updater';
            $this->createNotifications('core', $status['version'], $url);
        }
    }

    /**
     * Create notifications for this app version
     *
     * @param string $app
     * @param string $version
     * @param string $url
     */
    protected function createNotifications($app, $version, $url) {
        $lastNotification = $this->config->getAppValue('updatenotification', $app, false);
        if ($lastNotification === $version) {
            // We already notified about this update
            return;
        } elseif ($lastNotification !== false) {
            // Delete old updates
            $this->deleteOutdatedNotifications($app, $lastNotification);
        }

        $notification = $this->notificationManager->createNotification();
        $notification->setApp('updatenotification')
            ->setDateTime(new \DateTime())
            ->setObject($app, $version)
            ->setSubject('update_available')
            ->setLink($url);

        foreach ($this->getUsersToNotify() as $uid) {
            $notification->setUser($uid);
            $this->notificationManager->notify($notification);
        }

        $this->config->setAppValue('updatenotification', $app, $version);
    }

    /**
     * @return string[]
     */
    protected function getUsersToNotify() {
        if ($this->users !== null) {
            return $this->users;
        }

        $notifyGroups = \json_decode($this->config->getAppValue('updatenotification', 'notify_groups', '["admin"]'), true);
        $this->users = [];
        foreach ($notifyGroups as $group) {
            $groupToNotify = $this->groupManager->get($group);
            if ($groupToNotify instanceof IGroup) {
                foreach ($groupToNotify->getUsers() as $user) {
                    $this->users[$user->getUID()] = true;
                }
            }
        }

        $this->users = \array_keys($this->users);

        return $this->users;
    }

    /**
     * Delete notifications for old updates
     *
     * @param string $app
     * @param string $version
     */
    protected function deleteOutdatedNotifications($app, $version) {
        $notification = $this->notificationManager->createNotification();
        $notification->setApp('updatenotification')
            ->setObject($app, $version);
        $this->notificationManager->markProcessed($notification);
    }

    /**
     * @return VersionCheck
     */
    protected function createVersionCheck() {
        return new VersionCheck(
            $this->client,
            $this->config
        );
    }

    /**
     * @return string
     */
    protected function getChannel() {
        return \OC_Util::getChannel();
    }
}