mirror of
https://github.com/flarum/core.git
synced 2025-07-16 06:16:23 +02:00
Add Update Checker
This commit is contained in:
@ -9,6 +9,7 @@ namespace SychO\PackageManager;
|
||||
use Flarum\Extend;
|
||||
use Flarum\Foundation\Paths;
|
||||
use Flarum\Frontend\Document;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use SychO\PackageManager\Exception\ComposerCommandFailedExceptionHandler;
|
||||
use SychO\PackageManager\Exception\ComposerRequireFailedException;
|
||||
|
||||
@ -16,7 +17,8 @@ return [
|
||||
(new Extend\Routes('api'))
|
||||
->post('/package-manager/extensions', 'package-manager.extensions.require', Api\Controller\RequireExtensionController::class)
|
||||
->patch('/package-manager/extensions/{id}', 'package-manager.extensions.update', Api\Controller\UpdateExtensionController::class)
|
||||
->delete('/package-manager/extensions/{id}', 'package-manager.extensions.remove', Api\Controller\RemoveExtensionController::class),
|
||||
->delete('/package-manager/extensions/{id}', 'package-manager.extensions.remove', Api\Controller\RemoveExtensionController::class)
|
||||
->post('/package-manager/check-for-updates', 'package-manager.check-for-updates', Api\Controller\CheckForUpdatesController::class),
|
||||
|
||||
(new Extend\Frontend('admin'))
|
||||
->css(__DIR__ . '/less/admin.less')
|
||||
@ -28,6 +30,8 @@ return [
|
||||
&& is_writable($paths->storage.'/.composer')
|
||||
&& is_writable($paths->base.'/composer.json')
|
||||
&& is_writable($paths->base.'/composer.lock');
|
||||
|
||||
$document->payload['lastUpdateCheck'] = json_decode(resolve(SettingsRepositoryInterface::class)->get('sycho-package-manager.last_update_check', '{}'), true);
|
||||
}),
|
||||
|
||||
new Extend\Locales(__DIR__ . '/locale'),
|
||||
|
168
extensions/package-manager/js/dist/admin.js
vendored
168
extensions/package-manager/js/dist/admin.js
vendored
@ -313,7 +313,7 @@ var Installer = /*#__PURE__*/function (_Component) {
|
||||
});
|
||||
}
|
||||
}).then(function (response) {
|
||||
var extensionId = response.data.attributes.id;
|
||||
var extensionId = response.id;
|
||||
flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.alerts.show({
|
||||
type: 'success'
|
||||
}, flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.translator.trans('sycho-package-manager.admin.extensions.successful_install', {
|
||||
@ -332,6 +332,144 @@ var Installer = /*#__PURE__*/function (_Component) {
|
||||
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "./src/admin/components/Updater.tsx":
|
||||
/*!******************************************!*\
|
||||
!*** ./src/admin/components/Updater.tsx ***!
|
||||
\******************************************/
|
||||
/*! exports provided: default */
|
||||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Updater; });
|
||||
/* harmony import */ var _babel_runtime_helpers_esm_inheritsLoose__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/esm/inheritsLoose */ "./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js");
|
||||
/* harmony import */ var flarum_admin_app__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! flarum/admin/app */ "flarum/admin/app");
|
||||
/* harmony import */ var flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(flarum_admin_app__WEBPACK_IMPORTED_MODULE_1__);
|
||||
/* harmony import */ var flarum_common_Component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! flarum/common/Component */ "flarum/common/Component");
|
||||
/* harmony import */ var flarum_common_Component__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(flarum_common_Component__WEBPACK_IMPORTED_MODULE_2__);
|
||||
/* harmony import */ var flarum_common_helpers_icon__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! flarum/common/helpers/icon */ "flarum/common/helpers/icon");
|
||||
/* harmony import */ var flarum_common_helpers_icon__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(flarum_common_helpers_icon__WEBPACK_IMPORTED_MODULE_3__);
|
||||
/* harmony import */ var flarum_common_components_Button__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! flarum/common/components/Button */ "flarum/common/components/Button");
|
||||
/* harmony import */ var flarum_common_components_Button__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(flarum_common_components_Button__WEBPACK_IMPORTED_MODULE_4__);
|
||||
/* harmony import */ var flarum_common_helpers_humanTime__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! flarum/common/helpers/humanTime */ "flarum/common/helpers/humanTime");
|
||||
/* harmony import */ var flarum_common_helpers_humanTime__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(flarum_common_helpers_humanTime__WEBPACK_IMPORTED_MODULE_5__);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var Updater = /*#__PURE__*/function (_Component) {
|
||||
Object(_babel_runtime_helpers_esm_inheritsLoose__WEBPACK_IMPORTED_MODULE_0__["default"])(Updater, _Component);
|
||||
|
||||
function Updater() {
|
||||
var _this;
|
||||
|
||||
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
||||
args[_key] = arguments[_key];
|
||||
}
|
||||
|
||||
_this = _Component.call.apply(_Component, [this].concat(args)) || this;
|
||||
_this.isLoading = false;
|
||||
_this.lastUpdateCheck = flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.data.lastUpdateCheck || {};
|
||||
return _this;
|
||||
}
|
||||
|
||||
var _proto = Updater.prototype;
|
||||
|
||||
_proto.oninit = function oninit(vnode) {
|
||||
_Component.prototype.oninit.call(this, vnode);
|
||||
};
|
||||
|
||||
_proto.view = function view() {
|
||||
var _this$lastUpdateCheck;
|
||||
|
||||
var extensions = this.getExtensionUpdates(); // @TODO catch `flarum/core` updates and display them differently, since it is the CORE and not an extension.
|
||||
|
||||
return m("div", {
|
||||
className: "Form-group"
|
||||
}, m("label", null, flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.translator.trans('sycho-package-manager.admin.updater.updater_title')), m("p", {
|
||||
className: "helpText"
|
||||
}, flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.translator.trans('sycho-package-manager.admin.updater.updater_help')), m("p", {
|
||||
className: "PackageManager-lastUpdatedAt"
|
||||
}, m("span", {
|
||||
className: "PackageManager-lastUpdatedAt-label"
|
||||
}, flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.translator.trans('sycho-package-manager.admin.updater.last_update_checked_at')), m("span", {
|
||||
className: "PackageManager-lastUpdatedAt-value"
|
||||
}, flarum_common_helpers_humanTime__WEBPACK_IMPORTED_MODULE_5___default()((_this$lastUpdateCheck = this.lastUpdateCheck) == null ? void 0 : _this$lastUpdateCheck.checkedAt))), m(flarum_common_components_Button__WEBPACK_IMPORTED_MODULE_4___default.a, {
|
||||
className: "Button",
|
||||
icon: "fas fa-sync-alt",
|
||||
onclick: this.checkForUpdates.bind(this),
|
||||
loading: this.isLoading
|
||||
}, flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.translator.trans('sycho-package-manager.admin.updater.check_for_updates')), extensions.length ? m("div", {
|
||||
className: "PackageManager-extensions"
|
||||
}, m("div", {
|
||||
className: "PackageManager-extensions-grid"
|
||||
}, extensions.map(function (extension) {
|
||||
return m("div", {
|
||||
className: "PackageManager-extension"
|
||||
}, m("div", {
|
||||
className: "PackageManager-extension-icon ExtensionIcon",
|
||||
style: extension.icon
|
||||
}, extension.icon ? flarum_common_helpers_icon__WEBPACK_IMPORTED_MODULE_3___default()(extension.icon.name) : ''), m("div", {
|
||||
className: "PackageManager-extension-info"
|
||||
}, m("div", {
|
||||
className: "PackageManager-extension-name"
|
||||
}, extension.extra['flarum-extension'].title), m("div", {
|
||||
className: "PackageManager-extension-version"
|
||||
}, m("span", {
|
||||
className: "PackageManager-extension-version-current"
|
||||
}, extension.version), m("span", {
|
||||
className: "PackageManager-extension-version-latest Label"
|
||||
}, extension.newPackageUpdate.latest))), m("div", {
|
||||
className: "PackageManager-extension-controls"
|
||||
}, m(flarum_common_components_Button__WEBPACK_IMPORTED_MODULE_4___default.a, {
|
||||
icon: "fas fa-arrow-alt-circle-up",
|
||||
className: "Button Button--icon Button--flat"
|
||||
})));
|
||||
}))) : null);
|
||||
};
|
||||
|
||||
_proto.getExtensionUpdates = function getExtensionUpdates() {
|
||||
var _this$lastUpdateCheck2, _this$lastUpdateCheck3, _this$lastUpdateCheck4;
|
||||
|
||||
var updates = (_this$lastUpdateCheck2 = this.lastUpdateCheck) == null ? void 0 : (_this$lastUpdateCheck3 = _this$lastUpdateCheck2.updates) == null ? void 0 : (_this$lastUpdateCheck4 = _this$lastUpdateCheck3.installed) == null ? void 0 : _this$lastUpdateCheck4.filter(function (composerPackage) {
|
||||
var extension = flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.data.extensions[composerPackage.name.replace('/', '-').replace(/(flarum-ext-)|(flarum-)/, '')];
|
||||
var safeToUpdate = composerPackage['latest-status'] === 'semver-safe-update';
|
||||
|
||||
if (extension && safeToUpdate) {
|
||||
extension.newPackageUpdate = composerPackage;
|
||||
}
|
||||
|
||||
return extension && safeToUpdate;
|
||||
});
|
||||
return Object.values(flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.data.extensions).filter(function (extension) {
|
||||
return extension.newPackageUpdate;
|
||||
});
|
||||
};
|
||||
|
||||
_proto.checkForUpdates = function checkForUpdates() {
|
||||
var _this2 = this;
|
||||
|
||||
this.isLoading = true;
|
||||
flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.request({
|
||||
method: 'POST',
|
||||
url: flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.forum.attribute('apiUrl') + "/package-manager/check-for-updates"
|
||||
}).then(function (response) {
|
||||
_this2.isLoading = false;
|
||||
_this2.lastUpdateCheck = response;
|
||||
m.redraw();
|
||||
});
|
||||
};
|
||||
|
||||
return Updater;
|
||||
}(flarum_common_Component__WEBPACK_IMPORTED_MODULE_2___default.a);
|
||||
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "./src/admin/index.js":
|
||||
@ -356,6 +494,8 @@ __webpack_require__.r(__webpack_exports__);
|
||||
/* harmony import */ var flarum_admin_components_LoadingModal__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! flarum/admin/components/LoadingModal */ "flarum/admin/components/LoadingModal");
|
||||
/* harmony import */ var flarum_admin_components_LoadingModal__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(flarum_admin_components_LoadingModal__WEBPACK_IMPORTED_MODULE_5__);
|
||||
/* harmony import */ var _components_Installer__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./components/Installer */ "./src/admin/components/Installer.tsx");
|
||||
/* harmony import */ var _components_Updater__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./components/Updater */ "./src/admin/components/Updater.tsx");
|
||||
|
||||
|
||||
|
||||
|
||||
@ -377,6 +517,10 @@ flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.initializers.add('sycho-
|
||||
if (app.data.isRequiredDirectoriesWritable) {
|
||||
return m(_components_Installer__WEBPACK_IMPORTED_MODULE_6__["default"], null);
|
||||
}
|
||||
}).registerSetting(function () {
|
||||
if (app.data.isRequiredDirectoriesWritable) {
|
||||
return m(_components_Updater__WEBPACK_IMPORTED_MODULE_7__["default"], null);
|
||||
}
|
||||
});
|
||||
Object(flarum_common_extend__WEBPACK_IMPORTED_MODULE_0__["extend"])(flarum_admin_components_ExtensionPage__WEBPACK_IMPORTED_MODULE_3___default.a.prototype, 'topItems', function (items) {
|
||||
var _this = this;
|
||||
@ -492,6 +636,28 @@ module.exports = flarum.core.compat['common/extend'];
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "flarum/common/helpers/humanTime":
|
||||
/*!*****************************************************************!*\
|
||||
!*** external "flarum.core.compat['common/helpers/humanTime']" ***!
|
||||
\*****************************************************************/
|
||||
/*! no static exports found */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
module.exports = flarum.core.compat['common/helpers/humanTime'];
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "flarum/common/helpers/icon":
|
||||
/*!************************************************************!*\
|
||||
!*** external "flarum.core.compat['common/helpers/icon']" ***!
|
||||
\************************************************************/
|
||||
/*! no static exports found */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
module.exports = flarum.core.compat['common/helpers/icon'];
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "flarum/common/utils/Stream":
|
||||
/*!************************************************************!*\
|
||||
!*** external "flarum.core.compat['common/utils/Stream']" ***!
|
||||
|
File diff suppressed because one or more lines are too long
@ -59,7 +59,7 @@ export default class Installer extends Component {
|
||||
app.modal.show(ComposerFailureModal, { error });
|
||||
},
|
||||
}).then((response) => {
|
||||
const extensionId = response.data.attributes.id;
|
||||
const extensionId = response.id;
|
||||
app.alerts.show({ type: 'success' }, app.translator.trans('sycho-package-manager.admin.extensions.successful_install', { extension: extensionId }));
|
||||
window.location.href = `${app.forum.attribute('adminUrl')}#/extension/${extensionId}`;
|
||||
window.location.reload();
|
||||
|
102
extensions/package-manager/js/src/admin/components/Updater.tsx
Normal file
102
extensions/package-manager/js/src/admin/components/Updater.tsx
Normal file
@ -0,0 +1,102 @@
|
||||
import app from 'flarum/admin/app';
|
||||
import Component from 'flarum/common/Component';
|
||||
import icon from "flarum/common/helpers/icon";
|
||||
import Button from "flarum/common/components/Button";
|
||||
import humanTime from "flarum/common/helpers/humanTime";
|
||||
|
||||
type UpdatedPackage = {
|
||||
name: string;
|
||||
version: string;
|
||||
latest: string;
|
||||
"latest-status": string;
|
||||
description: string;
|
||||
};
|
||||
|
||||
type ComposerUpdates = {
|
||||
installed: UpdatedPackage[];
|
||||
};
|
||||
|
||||
type LastUpdateCheck = {
|
||||
checkedAt: Date;
|
||||
updates: ComposerUpdates;
|
||||
};
|
||||
|
||||
export default class Updater extends Component {
|
||||
isLoading: boolean = false;
|
||||
lastUpdateCheck: LastUpdateCheck = app.data.lastUpdateCheck || {};
|
||||
|
||||
oninit(vnode) {
|
||||
super.oninit(vnode);
|
||||
}
|
||||
|
||||
view() {
|
||||
const extensions: any = this.getExtensionUpdates();
|
||||
|
||||
// @TODO catch `flarum/core` updates and display them differently, since it is the CORE and not an extension.
|
||||
|
||||
return (
|
||||
<div className="Form-group">
|
||||
<label>{app.translator.trans('sycho-package-manager.admin.updater.updater_title')}</label>
|
||||
<p className="helpText">{app.translator.trans('sycho-package-manager.admin.updater.updater_help')}</p>
|
||||
<p className="PackageManager-lastUpdatedAt">
|
||||
<span className="PackageManager-lastUpdatedAt-label">{app.translator.trans('sycho-package-manager.admin.updater.last_update_checked_at')}</span>
|
||||
<span className="PackageManager-lastUpdatedAt-value">{humanTime(this.lastUpdateCheck?.checkedAt)}</span>
|
||||
</p>
|
||||
<Button className="Button" icon="fas fa-sync-alt" onclick={this.checkForUpdates.bind(this)} loading={this.isLoading}>
|
||||
{app.translator.trans('sycho-package-manager.admin.updater.check_for_updates')}
|
||||
</Button>
|
||||
{extensions.length ? (
|
||||
<div className="PackageManager-extensions">
|
||||
<div className="PackageManager-extensions-grid">
|
||||
{extensions.map((extension: any) => (
|
||||
<div className="PackageManager-extension">
|
||||
<div className="PackageManager-extension-icon ExtensionIcon" style={extension.icon}>
|
||||
{extension.icon ? icon(extension.icon.name) : ''}
|
||||
</div>
|
||||
<div className="PackageManager-extension-info">
|
||||
<div className="PackageManager-extension-name">{extension.extra['flarum-extension'].title}</div>
|
||||
<div className="PackageManager-extension-version">
|
||||
<span className="PackageManager-extension-version-current">{extension.version}</span>
|
||||
<span className="PackageManager-extension-version-latest Label">{extension.newPackageUpdate.latest}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="PackageManager-extension-controls">
|
||||
<Button icon="fas fa-arrow-alt-circle-up" className="Button Button--icon Button--flat" />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
getExtensionUpdates() {
|
||||
const updates = this.lastUpdateCheck?.updates?.installed?.filter((composerPackage: UpdatedPackage) => {
|
||||
const extension = app.data.extensions[composerPackage.name.replace('/', '-').replace(/(flarum-ext-)|(flarum-)/, '')];
|
||||
const safeToUpdate = composerPackage['latest-status'] === 'semver-safe-update';
|
||||
|
||||
if (extension && safeToUpdate) {
|
||||
extension.newPackageUpdate = composerPackage;
|
||||
}
|
||||
|
||||
return extension && safeToUpdate;
|
||||
});
|
||||
|
||||
return Object.values(app.data.extensions).filter((extension: any) => extension.newPackageUpdate);
|
||||
}
|
||||
|
||||
checkForUpdates() {
|
||||
this.isLoading = true;
|
||||
|
||||
app.request({
|
||||
method: 'POST',
|
||||
url: `${app.forum.attribute('apiUrl')}/package-manager/check-for-updates`,
|
||||
}).then((response) => {
|
||||
this.isLoading = false;
|
||||
this.lastUpdateCheck = response as LastUpdateCheck;
|
||||
m.redraw();
|
||||
});
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import ExtensionPage from 'flarum/admin/components/ExtensionPage';
|
||||
import Button from 'flarum/common/components/Button';
|
||||
import LoadingModal from 'flarum/admin/components/LoadingModal';
|
||||
import Installer from "./components/Installer";
|
||||
import Updater from "./components/Updater";
|
||||
|
||||
app.initializers.add('sycho-package-manager', (app) => {
|
||||
app.extensionData
|
||||
@ -24,6 +25,13 @@ app.initializers.add('sycho-package-manager', (app) => {
|
||||
<Installer />
|
||||
);
|
||||
}
|
||||
})
|
||||
.registerSetting(() => {
|
||||
if (app.data.isRequiredDirectoriesWritable) {
|
||||
return (
|
||||
<Updater />
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
extend(ExtensionPage.prototype, 'topItems', function (items) {
|
||||
|
@ -8,3 +8,60 @@
|
||||
.ComposerFailureModal-output {
|
||||
white-space: break-spaces;
|
||||
}
|
||||
|
||||
.sycho-package-manager-Page .ExtensionPage-settings .Form-group:last-child {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.PackageManager-lastUpdatedAt {
|
||||
color: @control-color;
|
||||
|
||||
&-label {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.PackageManager-extensions {
|
||||
&-grid {
|
||||
--gap: 12px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, calc(~"100% / 3 - var(--gap)"));
|
||||
gap: var(--gap);
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.PackageManager-extension {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
background-color: @control-bg;
|
||||
padding: 8px;
|
||||
border-radius: @border-radius;
|
||||
|
||||
&-controls {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
&-icon {
|
||||
--size: 40px;
|
||||
}
|
||||
|
||||
&-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&-version {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
&-latest {
|
||||
background: @alert-success-bg;
|
||||
color: @alert-success-color;
|
||||
border-radius: 30px;
|
||||
padding: 0 6px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,3 +15,9 @@ sycho-package-manager:
|
||||
|
||||
file_permissions: >
|
||||
The package manager requires read and write permissions on the following files and directories: composer.json, composer.lock, vendor, storage/.composer
|
||||
|
||||
updater:
|
||||
check_for_updates: Check for updates
|
||||
last_update_checked_at: "Last Update Check: "
|
||||
updater_title: Updates
|
||||
updater_help: Runs a check for new extension and Flarum updates.
|
||||
|
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
namespace SychO\PackageManager\Api\Controller;
|
||||
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Illuminate\Contracts\Bus\Dispatcher;
|
||||
use Illuminate\Support\Arr;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use SychO\PackageManager\Command\CheckForUpdates;
|
||||
|
||||
class CheckForUpdatesController implements RequestHandlerInterface
|
||||
{
|
||||
/**
|
||||
* @var Dispatcher
|
||||
*/
|
||||
protected $bus;
|
||||
|
||||
public function __construct(Dispatcher $bus)
|
||||
{
|
||||
$this->bus = $bus;
|
||||
}
|
||||
|
||||
public function handle(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
$actor = RequestUtil::getActor($request);
|
||||
|
||||
$lastUpdateCheck = $this->bus->dispatch(
|
||||
new CheckForUpdates($actor)
|
||||
);
|
||||
|
||||
return new JsonResponse($lastUpdateCheck);
|
||||
}
|
||||
}
|
22
extensions/package-manager/src/Command/CheckForUpdates.php
Normal file
22
extensions/package-manager/src/Command/CheckForUpdates.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
namespace SychO\PackageManager\Command;
|
||||
|
||||
use Flarum\User\User;
|
||||
|
||||
class CheckForUpdates
|
||||
{
|
||||
/**
|
||||
* @var \Flarum\User\User
|
||||
*/
|
||||
public $actor;
|
||||
|
||||
public function __construct(User $actor)
|
||||
{
|
||||
$this->actor = $actor;
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
namespace SychO\PackageManager\Command;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Composer\Console\Application;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Output\BufferedOutput;
|
||||
|
||||
class CheckForUpdatesHandler
|
||||
{
|
||||
/**
|
||||
* @var Application
|
||||
*/
|
||||
protected $composer;
|
||||
|
||||
/**
|
||||
* @var SettingsRepositoryInterface
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* @param Application $composer
|
||||
* @param SettingsRepositoryInterface $settings
|
||||
*/
|
||||
public function __construct(Application $composer, SettingsRepositoryInterface $settings)
|
||||
{
|
||||
$this->composer = $composer;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Flarum\User\Exception\PermissionDeniedException
|
||||
*/
|
||||
public function handle(CheckForUpdates $command)
|
||||
{
|
||||
$actor = $command->actor;
|
||||
|
||||
$actor->assertAdmin();
|
||||
|
||||
$output = new BufferedOutput();
|
||||
$input = new ArrayInput([
|
||||
'command' => 'outdated',
|
||||
'-D' => true,
|
||||
'--format' => 'json',
|
||||
]);
|
||||
|
||||
$this->composer->run($input, $output);
|
||||
|
||||
$lastUpdateCheck = [
|
||||
'checkedAt' => Carbon::now(),
|
||||
'updates' => json_decode($output->fetch(), true),
|
||||
];
|
||||
|
||||
$this->settings->set('sycho-package-manager.last_update_check', json_encode($lastUpdateCheck));
|
||||
|
||||
return $lastUpdateCheck;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user