From 93689e390666d24c2aceaf74b577330a68820d9a Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Fri, 4 Apr 2025 12:35:33 +0200 Subject: [PATCH] $fhcApi on plugins: error => warning --- public/js/plugin/OldFhcApi.js | 369 ++++++++++++++++++++++++++++++++++ public/js/plugins/Phrasen.js | 2 + 2 files changed, 371 insertions(+) create mode 100644 public/js/plugin/OldFhcApi.js diff --git a/public/js/plugin/OldFhcApi.js b/public/js/plugin/OldFhcApi.js new file mode 100644 index 000000000..3a5a0fb34 --- /dev/null +++ b/public/js/plugin/OldFhcApi.js @@ -0,0 +1,369 @@ +/** TODO(chris): + * when deleting this file be sure to + * remove line 1 & 90 from ../plugins/Phrasen.js + */ +import FhcApiFactory from '../api/fhcapifactory.js'; + + +export default { + install: (app, options) => { + if (app.config.globalProperties.$fhcApi) { + /* Depricated Code start */ + if (options?.factory) { + console.warn("$fhcApi is DEPRICATED!"); + app.config.globalProperties.$fhcApi.factory.addEndpoints(options.factory); + } + /* Depricated Code end */ + return; + } + + function _get_config(form, uri, data, config) { + if (typeof form == 'string' && config === undefined) { + [uri, data, config] = [form, uri, data]; + form = undefined; + } else if (form) { + if (typeof form != 'object') + throw new TypeError('Parameter 1 of _get_config must be an object or a string'); + if (uri === undefined && data === undefined && config === undefined) { + config = form; + form = undefined; + } + } + if (form) { + // NOTE(chris): check if form is fhc-form + if (!form.clearValidation || !form.setFeedback) + throw new TypeError("'form' is not a Form Component"); + + form = { + clearValidation: form.clearValidation, + setFeedback: form.setFeedback + }; + + if (config) + config.form = form; + else + config = {form}; + } + + return [uri, data, config]; + } + + function _clean_return_value(response) { + const result = response.data; + delete response.data; + if (!result.meta) + result.meta = {response}; + else + result.meta.response = response; + return result; + } + const baseURL = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + "/"; + const fhcApiAxios = axios.create({ + timeout: 500000, + baseURL: FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + "/" + }); + + fhcApiAxios.interceptors.request.use(config => { + if (config.method != 'post' || !config.data) + return config; + + if (config.data instanceof FormData) + return config; + + if (!Object.values(config.data).every(item => { + if (item instanceof FileList) + return false; + if (Array.isArray(item)) + return item.every(i => !(i instanceof File)); + return true; + })) { + const newData = Object.entries(config.data).reduce((nd, [key, item]) => { + if (item instanceof FileList) { + for (const file of item) + nd.FormData.append(key + (item.length > 1 ? '[]' : ''), file); + } else if (Array.isArray(item)) { + if (item.every(i => !(i instanceof File))) { + nd.jsondata[key] = item; + } else { + item.forEach(file => nd.FormData.append(key + (item.length > 1 ? '[]' : ''), file)); + } + } else { + nd.jsondata[key] = item; + } + return nd; + }, { + FormData: new FormData(), + jsondata: {} + }); + newData.FormData.append('_jsondata', JSON.stringify(newData.jsondata)); + config.data = newData.FormData; + } + + return config; + }); + + fhcApiAxios.interceptors.response.use(response => { + if (response.config?.errorHandling == 'off' + || response.config?.errorHandling === false + || response.config?.errorHandling == 'fail') + return _clean_return_value(response); + + // NOTE(chris): loop through errors + if (response.data.errors) + response.data.errors = response.data.errors.filter( + err => (response.config[err.type + 'ErrorHandler'] || app.config.globalProperties.$fhcApi._defaultErrorHandlers[err.type])(err, response.config) + ); + + return _clean_return_value(response); + }, error => { + if (error.code == 'ERR_CANCELED') + return Promise.reject({...{handled: true}, ...error}); + + if (error.config?.errorHandling == 'off' + || error.config?.errorHandling === false + || error.config?.errorHandling == 'success') + return Promise.reject(error); + + if (error.response) { + if (error.response.status == 404) { + app.config.globalProperties.$fhcAlert.alertDefault('error', error.message, error.request.responseURL, true); + return Promise.reject({...{handled: true}, ...error}); + } + + // NOTE(chris): loop through errors + error.response.data.errors = error.response.data.errors.filter( + err => (error.config[err.type + 'ErrorHandler'] || app.config.globalProperties.$fhcApi._defaultErrorHandlers[err.type])(err, error.config) + ); + if (!error.response.data.errors.length) + return Promise.reject({...{handled: true}, ...error}); + } else if (error.request) { + app.config.globalProperties.$fhcAlert.alertDefault('error', error.message, error.request.responseURL); + return Promise.reject({...{handled: true}, ...error}); + } else { + app.config.globalProperties.$fhcAlert.alertError(error.message); + return Promise.reject({...{handled: true}, ...error}); + } + + return Promise.reject(error); + }); + + app.config.globalProperties.$fhcApi = { + getUri(url) { + console.warn('$fhcApi.getUri is DEPRICATED! Use $api.getUri instead.'); + return fhcApiAxios.getUri({url}); + }, + get(form, uri, params, config) { + console.warn('$fhcApi.get is DEPRICATED! Use $api.get instead.'); + [uri, params, config] = _get_config(form, uri, params, config); + if (params) { + if (config) + config.params = params; + else + config = {params}; + } + return fhcApiAxios.get(uri, config); + }, + post(form, uri, data, config) { + console.warn('$fhcApi.post is DEPRICATED! Use $api.post instead.'); + [uri, data, config] = _get_config(form, uri, data, config); + return fhcApiAxios.post(uri, data, config); + }, + _defaultErrorHandlers: { + validation(error, config) { + const $fhcAlert = app.config.globalProperties.$fhcAlert; + + if (config?.form) { + config.form.clearValidation(); + config.form.setFeedback(false, error.messages); + return false; + } + if (Array.isArray(error.messages)) { + error.messages.forEach($fhcAlert.alertError); + return false; + } else if (typeof error.messages == 'object') { + if (config?.errorHeader) + Object.values(error.messages).forEach( + value => $fhcAlert.alertDefault( + 'error', + Array.isArray(config.errorHeader) ? app.config.globalProperties.$p.t.apply(null, config.errorHeader) : config.errorHeader, + value, + true + ) + ); + else + Object.entries(error.messages).forEach( + ([key, value]) => $fhcAlert.alertDefault('error', key, value, true) + ); + return false; + } + return true; + }, + general(error, config) { + const $fhcAlert = app.config.globalProperties.$fhcAlert; + + if (config?.form) + config.form.setFeedback(false, error.message); + else if (config?.errorHeader) + $fhcAlert.alertDefault( + 'error', + Array.isArray(config.errorHeader) ? app.config.globalProperties.$p.t.apply(null, config.errorHeader) : config.errorHeader, + error.message, + true + ); + else + $fhcAlert.alertError(error.message); + }, + php(error) { + const $fhcAlert = app.config.globalProperties.$fhcAlert; + + var message = ''; + message += 'Message: ' + error.message + '\n\n'; + message += 'Filename: ' + error.filename + '\n'; + message += 'Line Number: ' + error.line + '\n'; + if (error.backtrace && error.backtrace.length) { + message += '\nBacktrace: '; + error.backtrace.forEach(err => { + message += '\n\tFile: ' + err.file + '\n'; + message += '\tLine: ' + err.line + '\n'; + message += '\tFunction: ' + err.function + '\n'; + }); + } + switch (error.severity) { + case 'Warning': + case 'Core Warning': + case 'Compile Warning': + case 'User Warning': + $fhcAlert.alertDefault('warn', 'PHP ' + error.severity, message, true); + break; + case 'Notice': + case 'User Notice': + case 'Runtime Notice': + $fhcAlert.alertDefault('info', 'PHP ' + error.severity, message, true); + break; + default: + message = 'Type: PHP ' + error.severity + '\n\n' + message; + $fhcAlert.alertSystemError(message); + break; + } + }, + exception(error) { + const $fhcAlert = app.config.globalProperties.$fhcAlert; + + var message = ''; + message += 'Type: ' + error.class + '\n\n'; + message += 'Message: ' + error.message + '\n\n'; + message += 'Filename: ' + error.filename + '\n'; + message += 'Line Number: ' + error.line + '\n'; + if (error.backtrace && error.backtrace.length) { + message += '\nBacktrace: '; + error.backtrace.forEach(err => { + message += '\n\tFile: ' + err.file + '\n'; + message += '\tLine: ' + err.line + '\n'; + message += '\tFunction: ' + err.function + '\n'; + }); + } + $fhcAlert.alertSystemError(message); + }, + db(error) { + const $fhcAlert = app.config.globalProperties.$fhcAlert; + + var message = ''; + if (error.heading !== undefined) + message += error.heading + '\n\n'; + if (error.code !== undefined) + message += 'Code: ' + error.code + '\n\n'; + if (error.sql !== undefined) + message += 'SQL: ' + error.sql + '\n\n'; + if (error.message !== undefined) + message += 'Message: ' + error.message + '\n\n'; + else if (error.messages !== undefined) + message += 'Messages: ' + error.messages.join('\n\t') + '\n\n'; + if (error.filename !== undefined) + message += 'Filename: ' + error.filename + '\n'; + if (error.line !== undefined) + message += 'Line Number: ' + error.line + '\n'; + + $fhcAlert.alertSystemError(message); + }, + auth(error, config) { + const $fhcAlert = app.config.globalProperties.$fhcAlert; + + var message = ''; + message += 'Controller name: ' + error.controller + '\n'; + message += 'Method name: ' + error.method + '\n'; + message += 'Required permissions: ' + error.required_permissions; + if (config?.errorHeader) + $fhcAlert.alertDefault( + 'error', + Array.isArray(config.errorHeader) ? app.config.globalProperties.$p.t.apply(null, config.errorHeader) : config.errorHeader, + error.message, + true + ); + else + $fhcAlert.alertDefault('error', error.message, message); + } + } + }; + + /* Depricated Code start */ + class FhcApiFactoryWrapper { + constructor(factorypart, root) { + if (root === undefined) { + this.$fhcApi = { + getUri(url) { + console.warn('$fhcApi.factory is DEPRICATED!'); + return app.config.globalProperties.$fhcApi.getUri(url); + }, + get(form, uri, params, config) { + console.warn('$fhcApi.factory is DEPRICATED!'); + return app.config.globalProperties.$fhcApi.get(form, uri, params, config); + }, + post(form, uri, data, config) { + console.warn('$fhcApi.factory is DEPRICATED!'); + return app.config.globalProperties.$fhcApi.post(form, uri, data, config); + } + }; + Object.defineProperty(this.$fhcApi, 'factory', { + get() { + console.warn('$fhcApi.factory is DEPRICATED!'); + return app.config.globalProperties.$fhcApi.factory; + } + }); + app.config.globalProperties.$fhcApi.factory = this; + } else { + Object.defineProperty(this, '$fhcApi', { + get() { + return (root || this).$fhcApi; + } + }) + } + + this.addEndpoints(factorypart, true) + } + + addEndpoints(factorypart, noWarn) { + Object.keys(factorypart).forEach(key => { + Object.defineProperty(this, key, { + get() { + if (typeof factorypart[key] == 'function') + return factorypart[key].bind(this); + return new FhcApiFactoryWrapper(factorypart[key], this.$fhcApi.factory); + } + }); + }); + if (!noWarn) console.warn('$fhcApi.factory.addEndpoints() is DEPRICATED!'); + } + } + + const factory = new FhcApiFactoryWrapper(FhcApiFactory); + if (options?.factory) { + console.warn("$fhcApi is DEPRICATED!"); + factory.addEndpoints(options.factory); + } + + app.config.globalProperties.$fhcApi.factory = factory; + /* Depricated Code end */ + + app.provide('$fhcApi', app.config.globalProperties.$fhcApi); + } +}; \ No newline at end of file diff --git a/public/js/plugins/Phrasen.js b/public/js/plugins/Phrasen.js index 5ec223255..70f4fb64f 100644 --- a/public/js/plugins/Phrasen.js +++ b/public/js/plugins/Phrasen.js @@ -1,3 +1,4 @@ +import OldFhcApi from '../plugin/OldFhcApi.js'; // TODO(chris): remove at some point import PluginsApi from './Api.js'; import ApiPhrasen from '../api/factory/phrasen.js'; @@ -86,6 +87,7 @@ const phrasen = { export default { install(app, options) { + app.use(OldFhcApi); // TODO(chris): remove at some point app.use(PluginsApi); app.config.globalProperties.$p = { t: phrasen.t,