Skip to content

Commit

Permalink
Merge pull request #9 from NativePHP/custom-php-ini-settings
Browse files Browse the repository at this point in the history
Custom php ini settings
  • Loading branch information
mpociot committed Jul 31, 2023
2 parents dfea07a + 0b9387e commit 8c077cb
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 51 deletions.
12 changes: 10 additions & 2 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ class NativePHP {
catch (e) {
console.error(e);
}
let phpIniSettings = {};
try {
let { stdout } = yield (0, server_1.retrievePhpIniSettings)();
phpIniSettings = JSON.parse(stdout);
}
catch (e) {
console.error(e);
}
utils_1.electronApp.setAppUserModelId(nativePHPConfig === null || nativePHPConfig === void 0 ? void 0 : nativePHPConfig.app_id);
const deepLinkProtocol = nativePHPConfig === null || nativePHPConfig === void 0 ? void 0 : nativePHPConfig.deeplink_scheme;
if (deepLinkProtocol) {
Expand All @@ -103,7 +111,7 @@ class NativePHP {
}
const apiPort = yield (0, server_1.startAPI)();
console.log('API server started on port', apiPort.port);
phpProcesses = yield (0, server_1.servePhpApp)(apiPort.port);
phpProcesses = yield (0, server_1.servePhpApp)(apiPort.port, phpIniSettings);
websocketProcess = (0, server_1.serveWebsockets)();
yield (0, utils_2.notifyLaravel)('booted');
if (((_a = nativePHPConfig === null || nativePHPConfig === void 0 ? void 0 : nativePHPConfig.updater) === null || _a === void 0 ? void 0 : _a.enabled) === true) {
Expand All @@ -114,7 +122,7 @@ class NativePHP {
setTimeout(() => {
schedulerInterval = setInterval(() => {
console.log("Running scheduler...");
(0, server_1.runScheduler)(apiPort.port);
(0, server_1.runScheduler)(apiPort.port, phpIniSettings);
}, 60 * 1000);
}, delay);
app.on('activate', function (event, hasVisibleWindows) {
Expand Down
17 changes: 9 additions & 8 deletions dist/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,34 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.retrieveNativePHPConfig = exports.serveWebsockets = exports.startAPI = exports.startQueue = exports.runScheduler = exports.servePhpApp = void 0;
exports.retrievePhpIniSettings = exports.retrieveNativePHPConfig = exports.serveWebsockets = exports.startAPI = exports.startQueue = exports.runScheduler = exports.servePhpApp = void 0;
const websockets_1 = __importDefault(require("./websockets"));
exports.serveWebsockets = websockets_1.default;
const api_1 = __importDefault(require("./api"));
const php_1 = require("./php");
Object.defineProperty(exports, "retrieveNativePHPConfig", { enumerable: true, get: function () { return php_1.retrieveNativePHPConfig; } });
Object.defineProperty(exports, "retrievePhpIniSettings", { enumerable: true, get: function () { return php_1.retrievePhpIniSettings; } });
const utils_1 = require("./utils");
const state_1 = __importDefault(require("./state"));
function servePhpApp(apiPort) {
function servePhpApp(apiPort, phpIniSettings) {
return __awaiter(this, void 0, void 0, function* () {
const processes = [];
const result = yield (0, php_1.serveApp)(state_1.default.randomSecret, apiPort);
const result = yield (0, php_1.serveApp)(state_1.default.randomSecret, apiPort, phpIniSettings);
processes.push(result.process);
processes.push((0, php_1.startQueueWorker)(state_1.default.randomSecret, apiPort));
processes.push((0, php_1.startQueueWorker)(state_1.default.randomSecret, apiPort, phpIniSettings));
state_1.default.phpPort = result.port;
yield (0, utils_1.appendCookie)();
return processes;
});
}
exports.servePhpApp = servePhpApp;
function runScheduler(apiPort) {
(0, php_1.startScheduler)(state_1.default.randomSecret, apiPort);
function runScheduler(apiPort, phpIniSettings) {
(0, php_1.startScheduler)(state_1.default.randomSecret, apiPort, phpIniSettings);
}
exports.runScheduler = runScheduler;
function startQueue(apiPort) {
function startQueue(apiPort, phpIniSettings) {
if (!process.env.NATIVE_PHP_SKIP_QUEUE) {
return (0, php_1.startQueueWorker)(state_1.default.randomSecret, apiPort);
return (0, php_1.startQueueWorker)(state_1.default.randomSecret, apiPort, phpIniSettings);
}
}
exports.startQueue = startQueue;
Expand Down
46 changes: 34 additions & 12 deletions dist/server/php.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.retrieveNativePHPConfig = exports.getAppPath = exports.serveApp = exports.startScheduler = exports.startQueueWorker = void 0;
exports.retrievePhpIniSettings = exports.retrieveNativePHPConfig = exports.getAppPath = exports.serveApp = exports.startScheduler = exports.startQueueWorker = void 0;
const fs_1 = require("fs");
const fs_extra_1 = require("fs-extra");
const electron_store_1 = __importDefault(require("electron-store"));
Expand All @@ -35,6 +35,20 @@ function getPhpPort() {
});
});
}
function retrievePhpIniSettings() {
return __awaiter(this, void 0, void 0, function* () {
const env = {
NATIVEPHP_STORAGE_PATH: storagePath,
NATIVEPHP_DATABASE_PATH: databaseFile,
};
const phpOptions = {
cwd: appPath,
env
};
return yield (0, util_1.promisify)(child_process_1.execFile)(state_1.default.php, ['artisan', 'native:php-ini'], phpOptions);
});
}
exports.retrievePhpIniSettings = retrievePhpIniSettings;
function retrieveNativePHPConfig() {
return __awaiter(this, void 0, void 0, function* () {
const env = {
Expand All @@ -49,8 +63,16 @@ function retrieveNativePHPConfig() {
});
}
exports.retrieveNativePHPConfig = retrieveNativePHPConfig;
function callPhp(args, options) {
args.unshift('-d', 'memory_limit=512M', '-d', 'curl.cainfo=' + state_1.default.caCert, '-d', 'openssl.cafile=' + state_1.default.caCert);
function callPhp(args, options, phpIniSettings = {}) {
let defaultIniSettings = {
'memory_limit': '512M',
'curl.cainfo': state_1.default.caCert,
'openssl.cafile': state_1.default.caCert
};
let iniSettings = Object.assign(defaultIniSettings, phpIniSettings);
Object.keys(iniSettings).forEach(key => {
args.unshift('-d', `${key}=${iniSettings[key]}`);
});
return (0, child_process_1.spawn)(state_1.default.php, args, {
cwd: options.cwd,
env: Object.assign(Object.assign({}, process.env), options.env),
Expand Down Expand Up @@ -85,7 +107,7 @@ function ensureAppFoldersAreAvailable() {
(0, fs_1.writeFileSync)(databaseFile, '');
}
}
function startQueueWorker(secret, apiPort) {
function startQueueWorker(secret, apiPort, phpIniSettings = {}) {
const env = {
APP_ENV: process.env.NODE_ENV === 'development' ? 'local' : 'production',
APP_DEBUG: process.env.NODE_ENV === 'development' ? 'true' : 'false',
Expand All @@ -99,10 +121,10 @@ function startQueueWorker(secret, apiPort) {
cwd: appPath,
env
};
return callPhp(['artisan', 'queue:work'], phpOptions);
return callPhp(['artisan', 'queue:work'], phpOptions, phpIniSettings);
}
exports.startQueueWorker = startQueueWorker;
function startScheduler(secret, apiPort) {
function startScheduler(secret, apiPort, phpIniSettings = {}) {
const env = {
APP_ENV: process.env.NODE_ENV === 'development' ? 'local' : 'production',
APP_DEBUG: process.env.NODE_ENV === 'development' ? 'true' : 'false',
Expand All @@ -116,13 +138,13 @@ function startScheduler(secret, apiPort) {
cwd: appPath,
env
};
return callPhp(['artisan', 'schedule:run'], phpOptions);
return callPhp(['artisan', 'schedule:run'], phpOptions, phpIniSettings);
}
exports.startScheduler = startScheduler;
function serveApp(secret, apiPort) {
function serveApp(secret, apiPort, phpIniSettings) {
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
const appPath = getAppPath();
console.log('Starting PHP server...', `${state_1.default.php} artisan serve`, appPath);
console.log('Starting PHP server...', `${state_1.default.php} artisan serve`, appPath, phpIniSettings);
ensureAppFoldersAreAvailable();
console.log('Making sure app folders are available');
const env = {
Expand All @@ -139,10 +161,10 @@ function serveApp(secret, apiPort) {
env
};
const store = new electron_store_1.default();
callPhp(['artisan', 'storage:link', '--force'], phpOptions);
callPhp(['artisan', 'storage:link', '--force'], phpOptions, phpIniSettings);
if (store.get('migrated_version') !== electron_1.app.getVersion() && process.env.NODE_ENV !== 'development') {
console.log('Migrating database...');
callPhp(['artisan', 'migrate', '--force'], phpOptions);
callPhp(['artisan', 'migrate', '--force'], phpOptions, phpIniSettings);
store.set('migrated_version', electron_1.app.getVersion());
}
if (process.env.NODE_ENV === 'development') {
Expand All @@ -154,7 +176,7 @@ function serveApp(secret, apiPort) {
const phpServer = callPhp(['-S', `127.0.0.1:${phpPort}`, serverPath], {
cwd: (0, path_1.join)(appPath, 'public'),
env
});
}, phpIniSettings);
const portRegex = /Development Server \(.*:([0-9]+)\) started/gm;
phpServer.stdout.on('data', (data) => {
const match = portRegex.exec(data.toString());
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nativephp/electron-plugin",
"version": "0.2.0",
"version": "0.3.0",
"description": "NativePHP Electron support",
"license": "MIT",
"main": "dist/index.js",
Expand Down
14 changes: 11 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type CrossProcessExports from 'electron'
import { autoUpdater } from "electron-updater"
import state from './server/state'
import {electronApp, optimizer, is} from '@electron-toolkit/utils'
import {startAPI, runScheduler, servePhpApp, serveWebsockets, retrieveNativePHPConfig} from './server'
import {startAPI, runScheduler, servePhpApp, serveWebsockets, retrieveNativePHPConfig, retrievePhpIniSettings} from './server'
import {notifyLaravel} from "./server/utils";
import { app, BrowserWindow } from "electron";
import { resolve } from "path";
Expand Down Expand Up @@ -97,6 +97,14 @@ class NativePHP {
console.error(e);
}

let phpIniSettings = {};
try {
let {stdout} = await retrievePhpIniSettings()
phpIniSettings = JSON.parse(stdout);
} catch (e) {
console.error(e);
}

// @ts-ignore
electronApp.setAppUserModelId(nativePHPConfig?.app_id)

Expand All @@ -116,7 +124,7 @@ class NativePHP {
const apiPort = await startAPI()
console.log('API server started on port', apiPort.port);

phpProcesses = await servePhpApp(apiPort.port)
phpProcesses = await servePhpApp(apiPort.port, phpIniSettings)

websocketProcess = serveWebsockets()

Expand All @@ -133,7 +141,7 @@ class NativePHP {
setTimeout(() => {
schedulerInterval = setInterval(() => {
console.log("Running scheduler...")
runScheduler(apiPort.port);
runScheduler(apiPort.port, phpIniSettings);
}, 60 * 1000);
}, delay);

Expand Down
17 changes: 9 additions & 8 deletions src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,36 @@ import {
startScheduler,
serveApp,
retrieveNativePHPConfig,
retrievePhpIniSettings,
} from "./php";
import { appendCookie } from "./utils";
import state from "./state";

export async function servePhpApp(apiPort: number) {
export async function servePhpApp(apiPort: number, phpIniSettings: object) {
const processes = [];
const result = await serveApp(state.randomSecret, apiPort);
const result = await serveApp(state.randomSecret, apiPort, phpIniSettings);
processes.push(result.process);

processes.push(startQueueWorker(state.randomSecret, apiPort));
processes.push(startQueueWorker(state.randomSecret, apiPort, phpIniSettings));

state.phpPort = result.port;
await appendCookie();

return processes;
}

export function runScheduler(apiPort: number) {
startScheduler(state.randomSecret, apiPort);
export function runScheduler(apiPort: number, phpIniSettings: object) {
startScheduler(state.randomSecret, apiPort, phpIniSettings);
}

export function startQueue(apiPort: number) {
export function startQueue(apiPort: number, phpIniSettings: object) {
if (!process.env.NATIVE_PHP_SKIP_QUEUE) {
return startQueueWorker(state.randomSecret, apiPort);
return startQueueWorker(state.randomSecret, apiPort, phpIniSettings);
}
}

export function startAPI(): Promise<APIProcess> {
return startAPIServer(state.randomSecret);
}

export { serveWebsockets, retrieveNativePHPConfig };
export { serveWebsockets, retrieveNativePHPConfig, retrievePhpIniSettings };
53 changes: 36 additions & 17 deletions src/server/php.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@ async function getPhpPort() {
});
}

async function retrievePhpIniSettings() {
const env = {
NATIVEPHP_STORAGE_PATH: storagePath,
NATIVEPHP_DATABASE_PATH: databaseFile,
};

const phpOptions = {
cwd: appPath,
env
};

return await promisify(execFile)(state.php, ['artisan', 'native:php-ini'], phpOptions);
}

async function retrieveNativePHPConfig() {
const env = {
NATIVEPHP_STORAGE_PATH: storagePath,
Expand All @@ -36,13 +50,18 @@ async function retrieveNativePHPConfig() {
return await promisify(execFile)(state.php, ['artisan', 'native:config'], phpOptions);
}

function callPhp(args, options) {
// Add mandatory php.ini settings
args.unshift(
'-d', 'memory_limit=512M',
'-d', 'curl.cainfo=' + state.caCert,
'-d', 'openssl.cafile=' + state.caCert
);
function callPhp(args, options, phpIniSettings = {}) {
let defaultIniSettings = {
'memory_limit': '512M',
'curl.cainfo': state.caCert,
'openssl.cafile': state.caCert
}

let iniSettings = Object.assign(defaultIniSettings, phpIniSettings);

Object.keys(iniSettings).forEach(key => {
args.unshift('-d', `${key}=${iniSettings[key]}`);
});

return spawn(
state.php,
Expand Down Expand Up @@ -98,7 +117,7 @@ function ensureAppFoldersAreAvailable() {
}
}

function startQueueWorker(secret, apiPort) {
function startQueueWorker(secret, apiPort, phpIniSettings = {}) {
const env = {
APP_ENV: process.env.NODE_ENV === 'development' ? 'local' : 'production',
APP_DEBUG: process.env.NODE_ENV === 'development' ? 'true' : 'false',
Expand All @@ -114,10 +133,10 @@ function startQueueWorker(secret, apiPort) {
env
};

return callPhp(['artisan', 'queue:work'], phpOptions);
return callPhp(['artisan', 'queue:work'], phpOptions, phpIniSettings);
}

function startScheduler(secret, apiPort) {
function startScheduler(secret, apiPort, phpIniSettings = {}) {
const env = {
APP_ENV: process.env.NODE_ENV === 'development' ? 'local' : 'production',
APP_DEBUG: process.env.NODE_ENV === 'development' ? 'true' : 'false',
Expand All @@ -133,14 +152,14 @@ function startScheduler(secret, apiPort) {
env
};

return callPhp(['artisan', 'schedule:run'], phpOptions);
return callPhp(['artisan', 'schedule:run'], phpOptions, phpIniSettings);
}

function serveApp(secret, apiPort): Promise<ProcessResult> {
function serveApp(secret, apiPort, phpIniSettings): Promise<ProcessResult> {
return new Promise(async (resolve, reject) => {
const appPath = getAppPath();

console.log('Starting PHP server...', `${state.php} artisan serve`, appPath)
console.log('Starting PHP server...', `${state.php} artisan serve`, appPath, phpIniSettings)

ensureAppFoldersAreAvailable();

Expand All @@ -165,12 +184,12 @@ function serveApp(secret, apiPort): Promise<ProcessResult> {

// Make sure the storage path is linked - as people can move the app around, we
// need to run this every time the app starts
callPhp(['artisan', 'storage:link', '--force'], phpOptions)
callPhp(['artisan', 'storage:link', '--force'], phpOptions, phpIniSettings)

// Migrate the database
if (store.get('migrated_version') !== app.getVersion() && process.env.NODE_ENV !== 'development') {
console.log('Migrating database...')
callPhp(['artisan', 'migrate', '--force'], phpOptions)
callPhp(['artisan', 'migrate', '--force'], phpOptions, phpIniSettings)
store.set('migrated_version', app.getVersion())
}

Expand All @@ -185,7 +204,7 @@ function serveApp(secret, apiPort): Promise<ProcessResult> {
const phpServer = callPhp(['-S', `127.0.0.1:${phpPort}`, serverPath], {
cwd: join(appPath, 'public'),
env
})
}, phpIniSettings)

const portRegex = /Development Server \(.*:([0-9]+)\) started/gm

Expand Down Expand Up @@ -219,4 +238,4 @@ function serveApp(secret, apiPort): Promise<ProcessResult> {
})
}

export {startQueueWorker, startScheduler, serveApp, getAppPath, retrieveNativePHPConfig}
export {startQueueWorker, startScheduler, serveApp, getAppPath, retrieveNativePHPConfig, retrievePhpIniSettings}

0 comments on commit 8c077cb

Please sign in to comment.