mirror of
https://github.com/flarum/core.git
synced 2025-07-17 06:41:21 +02:00
File permissions alert and clear command failure message.
This commit is contained in:
@@ -8,7 +8,9 @@ namespace SychO\PackageManager;
|
|||||||
|
|
||||||
use Flarum\Extend;
|
use Flarum\Extend;
|
||||||
use Flarum\Foundation\Paths;
|
use Flarum\Foundation\Paths;
|
||||||
use Illuminate\Console\Scheduling\Event;
|
use Flarum\Frontend\Document;
|
||||||
|
use SychO\PackageManager\Exception\ComposerCommandFailedExceptionHandler;
|
||||||
|
use SychO\PackageManager\Exception\ComposerRequireFailedException;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
(new Extend\Routes('api'))
|
(new Extend\Routes('api'))
|
||||||
@@ -18,10 +20,21 @@ return [
|
|||||||
|
|
||||||
(new Extend\Frontend('admin'))
|
(new Extend\Frontend('admin'))
|
||||||
->css(__DIR__ . '/less/admin.less')
|
->css(__DIR__ . '/less/admin.less')
|
||||||
->js(__DIR__ . '/js/dist/admin.js'),
|
->js(__DIR__ . '/js/dist/admin.js')
|
||||||
|
->content(function (Document $document) {
|
||||||
|
$paths = resolve(Paths::class);
|
||||||
|
|
||||||
|
$document->payload['isRequiredDirectoriesWritable'] = is_writable($paths->vendor)
|
||||||
|
&& is_writable($paths->storage.'/.composer')
|
||||||
|
&& is_writable($paths->base.'/composer.json')
|
||||||
|
&& is_writable($paths->base.'/composer.lock');
|
||||||
|
}),
|
||||||
|
|
||||||
new Extend\Locales(__DIR__ . '/locale'),
|
new Extend\Locales(__DIR__ . '/locale'),
|
||||||
|
|
||||||
(new Extend\ServiceProvider)
|
(new Extend\ServiceProvider)
|
||||||
->register(PackageManagerServiceProvider::class),
|
->register(PackageManagerServiceProvider::class),
|
||||||
|
|
||||||
|
(new Extend\ErrorHandling)
|
||||||
|
->handler(ComposerRequireFailedException::class, ComposerCommandFailedExceptionHandler::class),
|
||||||
];
|
];
|
||||||
|
133
extensions/package-manager/js/dist/admin.js
vendored
133
extensions/package-manager/js/dist/admin.js
vendored
@@ -140,6 +140,68 @@ function _setPrototypeOf(o, p) {
|
|||||||
return _setPrototypeOf(o, p);
|
return _setPrototypeOf(o, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "./src/admin/components/ComposerFailureModal.tsx":
|
||||||
|
/*!*******************************************************!*\
|
||||||
|
!*** ./src/admin/components/ComposerFailureModal.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 ComposerFailureModal; });
|
||||||
|
/* 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_components_Modal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! flarum/common/components/Modal */ "flarum/common/components/Modal");
|
||||||
|
/* harmony import */ var flarum_common_components_Modal__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(flarum_common_components_Modal__WEBPACK_IMPORTED_MODULE_2__);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var ComposerFailureModal = /*#__PURE__*/function (_Modal) {
|
||||||
|
Object(_babel_runtime_helpers_esm_inheritsLoose__WEBPACK_IMPORTED_MODULE_0__["default"])(ComposerFailureModal, _Modal);
|
||||||
|
|
||||||
|
function ComposerFailureModal() {
|
||||||
|
return _Modal.apply(this, arguments) || this;
|
||||||
|
}
|
||||||
|
|
||||||
|
var _proto = ComposerFailureModal.prototype;
|
||||||
|
|
||||||
|
_proto.oninit = function oninit(vnode) {
|
||||||
|
_Modal.prototype.oninit.call(this, vnode);
|
||||||
|
|
||||||
|
if (this.attrs.error.guessed_cause) {
|
||||||
|
this.alertAttrs = {
|
||||||
|
type: 'error',
|
||||||
|
content: flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.translator.trans("sycho-package-manager.admin.failure_modal.guessed_cause." + this.attrs.error.guessed_cause)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_proto.className = function className() {
|
||||||
|
return 'Modal--large ComposerFailureModal';
|
||||||
|
};
|
||||||
|
|
||||||
|
_proto.title = function title() {
|
||||||
|
return flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.translator.trans('sycho-package-manager.admin.failure_modal.title');
|
||||||
|
};
|
||||||
|
|
||||||
|
_proto.content = function content() {
|
||||||
|
return m("div", {
|
||||||
|
className: "Modal-body"
|
||||||
|
}, m("details", null, m("summary", null, flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.translator.trans('sycho-package-manager.admin.failure_modal.show_composer_output')), m("pre", {
|
||||||
|
className: "ComposerFailureModal-output"
|
||||||
|
}, this.attrs.error.output)));
|
||||||
|
};
|
||||||
|
|
||||||
|
return ComposerFailureModal;
|
||||||
|
}(flarum_common_components_Modal__WEBPACK_IMPORTED_MODULE_2___default.a);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ "./src/admin/components/Installer.tsx":
|
/***/ "./src/admin/components/Installer.tsx":
|
||||||
@@ -163,6 +225,8 @@ __webpack_require__.r(__webpack_exports__);
|
|||||||
/* harmony import */ var flarum_common_utils_Stream__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(flarum_common_utils_Stream__WEBPACK_IMPORTED_MODULE_4__);
|
/* harmony import */ var flarum_common_utils_Stream__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(flarum_common_utils_Stream__WEBPACK_IMPORTED_MODULE_4__);
|
||||||
/* 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__ = __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 flarum_admin_components_LoadingModal__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(flarum_admin_components_LoadingModal__WEBPACK_IMPORTED_MODULE_5__);
|
||||||
|
/* harmony import */ var _ComposerFailureModal__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ComposerFailureModal */ "./src/admin/components/ComposerFailureModal.tsx");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -236,6 +300,17 @@ var Installer = /*#__PURE__*/function (_Component) {
|
|||||||
url: flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.forum.attribute('apiUrl') + "/package-manager/extensions",
|
url: flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.forum.attribute('apiUrl') + "/package-manager/extensions",
|
||||||
body: {
|
body: {
|
||||||
data: this.data()
|
data: this.data()
|
||||||
|
},
|
||||||
|
errorHandler: function errorHandler(e) {
|
||||||
|
var error = e.response.errors[0];
|
||||||
|
|
||||||
|
if (error.code !== 'composer_command_failure') {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.modal.show(_ComposerFailureModal__WEBPACK_IMPORTED_MODULE_6__["default"], {
|
||||||
|
error: error
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}).then(function (response) {
|
}).then(function (response) {
|
||||||
var extensionId = response.data.attributes.id;
|
var extensionId = response.data.attributes.id;
|
||||||
@@ -272,13 +347,16 @@ __webpack_require__.r(__webpack_exports__);
|
|||||||
/* harmony import */ var flarum_common_extend__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(flarum_common_extend__WEBPACK_IMPORTED_MODULE_0__);
|
/* harmony import */ var flarum_common_extend__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(flarum_common_extend__WEBPACK_IMPORTED_MODULE_0__);
|
||||||
/* 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__ = __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_admin_app__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(flarum_admin_app__WEBPACK_IMPORTED_MODULE_1__);
|
||||||
/* harmony import */ var flarum_admin_components_ExtensionPage__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! flarum/admin/components/ExtensionPage */ "flarum/admin/components/ExtensionPage");
|
/* harmony import */ var flarum_common_components_Alert__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! flarum/common/components/Alert */ "flarum/common/components/Alert");
|
||||||
/* harmony import */ var flarum_admin_components_ExtensionPage__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(flarum_admin_components_ExtensionPage__WEBPACK_IMPORTED_MODULE_2__);
|
/* harmony import */ var flarum_common_components_Alert__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(flarum_common_components_Alert__WEBPACK_IMPORTED_MODULE_2__);
|
||||||
/* harmony import */ var flarum_common_components_Button__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! flarum/common/components/Button */ "flarum/common/components/Button");
|
/* harmony import */ var flarum_admin_components_ExtensionPage__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! flarum/admin/components/ExtensionPage */ "flarum/admin/components/ExtensionPage");
|
||||||
/* harmony import */ var flarum_common_components_Button__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(flarum_common_components_Button__WEBPACK_IMPORTED_MODULE_3__);
|
/* harmony import */ var flarum_admin_components_ExtensionPage__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(flarum_admin_components_ExtensionPage__WEBPACK_IMPORTED_MODULE_3__);
|
||||||
/* harmony import */ var flarum_admin_components_LoadingModal__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! flarum/admin/components/LoadingModal */ "flarum/admin/components/LoadingModal");
|
/* 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_admin_components_LoadingModal__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(flarum_admin_components_LoadingModal__WEBPACK_IMPORTED_MODULE_4__);
|
/* 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 _components_Installer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./components/Installer */ "./src/admin/components/Installer.tsx");
|
/* 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");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -287,16 +365,27 @@ __webpack_require__.r(__webpack_exports__);
|
|||||||
|
|
||||||
flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.initializers.add('sycho-package-manager', function (app) {
|
flarum_admin_app__WEBPACK_IMPORTED_MODULE_1___default.a.initializers.add('sycho-package-manager', function (app) {
|
||||||
app.extensionData["for"]('sycho-package-manager').registerSetting(function () {
|
app.extensionData["for"]('sycho-package-manager').registerSetting(function () {
|
||||||
return m(_components_Installer__WEBPACK_IMPORTED_MODULE_5__["default"], null);
|
if (!app.data.isRequiredDirectoriesWritable) {
|
||||||
|
return m("div", {
|
||||||
|
className: "Form-group"
|
||||||
|
}, m(flarum_common_components_Alert__WEBPACK_IMPORTED_MODULE_2___default.a, {
|
||||||
|
type: "warning",
|
||||||
|
dismissible: false
|
||||||
|
}, app.translator.trans('sycho-package-manager.admin.file_permissions')));
|
||||||
|
}
|
||||||
|
}).registerSetting(function () {
|
||||||
|
if (app.data.isRequiredDirectoriesWritable) {
|
||||||
|
return m(_components_Installer__WEBPACK_IMPORTED_MODULE_6__["default"], null);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
Object(flarum_common_extend__WEBPACK_IMPORTED_MODULE_0__["extend"])(flarum_admin_components_ExtensionPage__WEBPACK_IMPORTED_MODULE_2___default.a.prototype, 'topItems', function (items) {
|
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;
|
var _this = this;
|
||||||
|
|
||||||
items.add('remove', m(flarum_common_components_Button__WEBPACK_IMPORTED_MODULE_3___default.a, {
|
items.add('remove', m(flarum_common_components_Button__WEBPACK_IMPORTED_MODULE_4___default.a, {
|
||||||
className: "Button Button--danger",
|
className: "Button Button--danger",
|
||||||
icon: "fas fa-times",
|
icon: "fas fa-times",
|
||||||
onclick: function onclick() {
|
onclick: function onclick() {
|
||||||
app.modal.show(flarum_admin_components_LoadingModal__WEBPACK_IMPORTED_MODULE_4___default.a);
|
app.modal.show(flarum_admin_components_LoadingModal__WEBPACK_IMPORTED_MODULE_5___default.a);
|
||||||
app.request({
|
app.request({
|
||||||
url: app.forum.attribute('apiUrl') + "/package-manager/extensions/" + _this.extension.id,
|
url: app.forum.attribute('apiUrl') + "/package-manager/extensions/" + _this.extension.id,
|
||||||
method: 'DELETE'
|
method: 'DELETE'
|
||||||
@@ -359,6 +448,17 @@ module.exports = flarum.core.compat['common/Component'];
|
|||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "flarum/common/components/Alert":
|
||||||
|
/*!****************************************************************!*\
|
||||||
|
!*** external "flarum.core.compat['common/components/Alert']" ***!
|
||||||
|
\****************************************************************/
|
||||||
|
/*! no static exports found */
|
||||||
|
/***/ (function(module, exports) {
|
||||||
|
|
||||||
|
module.exports = flarum.core.compat['common/components/Alert'];
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
/***/ "flarum/common/components/Button":
|
/***/ "flarum/common/components/Button":
|
||||||
/*!*****************************************************************!*\
|
/*!*****************************************************************!*\
|
||||||
!*** external "flarum.core.compat['common/components/Button']" ***!
|
!*** external "flarum.core.compat['common/components/Button']" ***!
|
||||||
@@ -370,6 +470,17 @@ module.exports = flarum.core.compat['common/components/Button'];
|
|||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "flarum/common/components/Modal":
|
||||||
|
/*!****************************************************************!*\
|
||||||
|
!*** external "flarum.core.compat['common/components/Modal']" ***!
|
||||||
|
\****************************************************************/
|
||||||
|
/*! no static exports found */
|
||||||
|
/***/ (function(module, exports) {
|
||||||
|
|
||||||
|
module.exports = flarum.core.compat['common/components/Modal'];
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
/***/ "flarum/common/extend":
|
/***/ "flarum/common/extend":
|
||||||
/*!******************************************************!*\
|
/*!******************************************************!*\
|
||||||
!*** external "flarum.core.compat['common/extend']" ***!
|
!*** external "flarum.core.compat['common/extend']" ***!
|
||||||
|
File diff suppressed because one or more lines are too long
@@ -0,0 +1,41 @@
|
|||||||
|
import app from 'flarum/admin/app';
|
||||||
|
import Modal from 'flarum/common/components/Modal';
|
||||||
|
import { ComponentAttrs } from "flarum/common/Component";
|
||||||
|
import Alert from "flarum/common/components/Alert";
|
||||||
|
import Mithril from "mithril";
|
||||||
|
|
||||||
|
interface Attrs extends ComponentAttrs {
|
||||||
|
output: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class ComposerFailureModal<T extends Attrs = Attrs> extends Modal<T> {
|
||||||
|
oninit(vnode: Mithril.Vnode<T, this>) {
|
||||||
|
super.oninit(vnode);
|
||||||
|
|
||||||
|
if (this.attrs.error.guessed_cause) {
|
||||||
|
this.alertAttrs = {
|
||||||
|
type: 'error',
|
||||||
|
content: app.translator.trans(`sycho-package-manager.admin.failure_modal.guessed_cause.${this.attrs.error.guessed_cause}`),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
className() {
|
||||||
|
return 'Modal--large ComposerFailureModal';
|
||||||
|
}
|
||||||
|
|
||||||
|
title() {
|
||||||
|
return app.translator.trans('sycho-package-manager.admin.failure_modal.title');
|
||||||
|
}
|
||||||
|
|
||||||
|
content() {
|
||||||
|
return (
|
||||||
|
<div className="Modal-body">
|
||||||
|
<details>
|
||||||
|
<summary>{app.translator.trans('sycho-package-manager.admin.failure_modal.show_composer_output')}</summary>
|
||||||
|
<pre className="ComposerFailureModal-output">{this.attrs.error.output}</pre>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@@ -4,6 +4,7 @@ import Component from 'flarum/common/Component';
|
|||||||
import Button from "flarum/common/components/Button";
|
import Button from "flarum/common/components/Button";
|
||||||
import Stream from "flarum/common/utils/Stream";
|
import Stream from "flarum/common/utils/Stream";
|
||||||
import LoadingModal from "flarum/admin/components/LoadingModal";
|
import LoadingModal from "flarum/admin/components/LoadingModal";
|
||||||
|
import ComposerFailureModal from "./ComposerFailureModal";
|
||||||
|
|
||||||
export default class Installer extends Component {
|
export default class Installer extends Component {
|
||||||
packageName!: Stream<string>;
|
packageName!: Stream<string>;
|
||||||
@@ -48,6 +49,15 @@ export default class Installer extends Component {
|
|||||||
body: {
|
body: {
|
||||||
data: this.data()
|
data: this.data()
|
||||||
},
|
},
|
||||||
|
errorHandler: (e: any) => {
|
||||||
|
const error = e.response.errors[0];
|
||||||
|
|
||||||
|
if (error.code !== 'composer_command_failure') {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
app.modal.show(ComposerFailureModal, { error });
|
||||||
|
},
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
const extensionId = response.data.attributes.id;
|
const extensionId = response.data.attributes.id;
|
||||||
app.alerts.show({ type: 'success' }, app.translator.trans('sycho-package-manager.admin.extensions.successful_install', { extension: extensionId }));
|
app.alerts.show({ type: 'success' }, app.translator.trans('sycho-package-manager.admin.extensions.successful_install', { extension: extensionId }));
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import { extend } from 'flarum/common/extend';
|
import { extend } from 'flarum/common/extend';
|
||||||
import app from 'flarum/admin/app';
|
import app from 'flarum/admin/app';
|
||||||
|
import Alert from 'flarum/common/components/Alert';
|
||||||
import ExtensionPage from 'flarum/admin/components/ExtensionPage';
|
import ExtensionPage from 'flarum/admin/components/ExtensionPage';
|
||||||
import Button from 'flarum/common/components/Button';
|
import Button from 'flarum/common/components/Button';
|
||||||
import LoadingModal from 'flarum/admin/components/LoadingModal';
|
import LoadingModal from 'flarum/admin/components/LoadingModal';
|
||||||
@@ -9,9 +10,20 @@ app.initializers.add('sycho-package-manager', (app) => {
|
|||||||
app.extensionData
|
app.extensionData
|
||||||
.for('sycho-package-manager')
|
.for('sycho-package-manager')
|
||||||
.registerSetting(() => {
|
.registerSetting(() => {
|
||||||
|
if (!app.data.isRequiredDirectoriesWritable) {
|
||||||
|
return (
|
||||||
|
<div className="Form-group">
|
||||||
|
<Alert type="warning" dismissible={false}>{app.translator.trans('sycho-package-manager.admin.file_permissions')}</Alert>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.registerSetting(() => {
|
||||||
|
if (app.data.isRequiredDirectoriesWritable) {
|
||||||
return (
|
return (
|
||||||
<Installer />
|
<Installer />
|
||||||
);
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
extend(ExtensionPage.prototype, 'topItems', function (items) {
|
extend(ExtensionPage.prototype, 'topItems', function (items) {
|
||||||
|
@@ -4,3 +4,7 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ComposerFailureModal-output {
|
||||||
|
white-space: break-spaces;
|
||||||
|
}
|
||||||
|
@@ -7,3 +7,11 @@ sycho-package-manager:
|
|||||||
successful_install: "{extension} was installed successfully, redirecting.."
|
successful_install: "{extension} was installed successfully, redirecting.."
|
||||||
successful_remove: Extension removed successfully.
|
successful_remove: Extension removed successfully.
|
||||||
|
|
||||||
|
failure_modal:
|
||||||
|
title: Operation Failed
|
||||||
|
guessed_cause:
|
||||||
|
extension_incompatible_with_instance: The extension is most likely incompatible with your current Flarum instance.
|
||||||
|
show_composer_output: Show Advanced Details
|
||||||
|
|
||||||
|
file_permissions: >
|
||||||
|
The package manager requires read and write permissions on the following files and directories: composer.json, composer.lock, vendor, storage/.composer
|
||||||
|
@@ -3,6 +3,9 @@
|
|||||||
namespace SychO\PackageManager\Api\Controller;
|
namespace SychO\PackageManager\Api\Controller;
|
||||||
|
|
||||||
use Flarum\Bus\Dispatcher;
|
use Flarum\Bus\Dispatcher;
|
||||||
|
use Laminas\Diactoros\Response\JsonResponse;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
use SychO\PackageManager\Api\Serializer\ExtensionSerializer;
|
use SychO\PackageManager\Api\Serializer\ExtensionSerializer;
|
||||||
use SychO\PackageManager\Command\RequireExtension;
|
use SychO\PackageManager\Command\RequireExtension;
|
||||||
use SychO\PackageManager\Extension\ExtensionUtils;
|
use SychO\PackageManager\Extension\ExtensionUtils;
|
||||||
@@ -12,10 +15,8 @@ use Illuminate\Support\Arr;
|
|||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
class RequireExtensionController extends AbstractCreateController
|
class RequireExtensionController implements RequestHandlerInterface
|
||||||
{
|
{
|
||||||
public $serializer = ExtensionSerializer::class;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Dispatcher
|
* @var Dispatcher
|
||||||
*/
|
*/
|
||||||
@@ -26,13 +27,15 @@ class RequireExtensionController extends AbstractCreateController
|
|||||||
$this->bus = $bus;
|
$this->bus = $bus;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function data(ServerRequestInterface $request, Document $document)
|
public function handle(ServerRequestInterface $request): ResponseInterface
|
||||||
{
|
{
|
||||||
$actor = RequestUtil::getActor($request);
|
$actor = RequestUtil::getActor($request);
|
||||||
$package = Arr::get($request->getParsedBody(), 'data.package');
|
$package = Arr::get($request->getParsedBody(), 'data.package');
|
||||||
|
|
||||||
return $this->bus->dispatch(
|
$data = $this->bus->dispatch(
|
||||||
new RequireExtension($actor, $package)
|
new RequireExtension($actor, $package)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return new JsonResponse($data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,6 +4,7 @@ namespace SychO\PackageManager\Command;
|
|||||||
|
|
||||||
use Composer\Console\Application;
|
use Composer\Console\Application;
|
||||||
use Flarum\Extension\ExtensionManager;
|
use Flarum\Extension\ExtensionManager;
|
||||||
|
use SychO\PackageManager\Exception\ComposerRequireFailedException;
|
||||||
use SychO\PackageManager\Extension\ExtensionUtils;
|
use SychO\PackageManager\Extension\ExtensionUtils;
|
||||||
use SychO\PackageManager\RequirePackageValidator;
|
use SychO\PackageManager\RequirePackageValidator;
|
||||||
use Symfony\Component\Console\Input\ArrayInput;
|
use Symfony\Component\Console\Input\ArrayInput;
|
||||||
@@ -56,7 +57,11 @@ class RequireExtensionHandler
|
|||||||
'packages' => [$command->package],
|
'packages' => [$command->package],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->composer->run($input, $output);
|
$exitCode = $this->composer->run($input, $output);
|
||||||
|
|
||||||
|
if ($exitCode !== 0) {
|
||||||
|
throw new ComposerRequireFailedException($command->package, $output->fetch());
|
||||||
|
}
|
||||||
|
|
||||||
return ['id' => $extensionId];
|
return ['id' => $extensionId];
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace SychO\PackageManager\Exception;
|
||||||
|
|
||||||
|
use Flarum\Foundation\ErrorHandling\HandledError;
|
||||||
|
|
||||||
|
class ComposerCommandFailedExceptionHandler
|
||||||
|
{
|
||||||
|
protected const INCOMPATIBLE_REGEX = '/ +- {PACKAGE_NAME} v[0-9.]+ requires flarum\/core/m';
|
||||||
|
|
||||||
|
public function handle(ComposerRequireFailedException $e): HandledError
|
||||||
|
{
|
||||||
|
return (new HandledError(
|
||||||
|
$e,
|
||||||
|
'composer_command_failure',
|
||||||
|
409
|
||||||
|
))->withDetails($this->errorDetails($e));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function errorDetails(ComposerRequireFailedException $e): array
|
||||||
|
{
|
||||||
|
$details = [
|
||||||
|
'output' => $e->getMessage(),
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($guessedCause = $this->guessCause($e)) {
|
||||||
|
$details['guessed_cause'] = $guessedCause;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [$details];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function guessCause(ComposerRequireFailedException $e): ?string
|
||||||
|
{
|
||||||
|
error_log(str_replace('{PACKAGE_NAME}', preg_quote($e->packageName, '/'), self::INCOMPATIBLE_REGEX));
|
||||||
|
$hasMatches = preg_match(str_replace('{PACKAGE_NAME}', preg_quote($e->packageName, '/'), self::INCOMPATIBLE_REGEX), $e->getMessage(), $matches);
|
||||||
|
|
||||||
|
if ($hasMatches) {
|
||||||
|
return 'extension_incompatible_with_instance';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace SychO\PackageManager\Exception;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class ComposerRequireFailedException extends Exception
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $packageName;
|
||||||
|
|
||||||
|
public function __construct(string $packageName, string $output)
|
||||||
|
{
|
||||||
|
$this->packageName = $packageName;
|
||||||
|
|
||||||
|
parent::__construct($output);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user