diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..acbc92a --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,25 @@ +{ + "env": { + "node": true + }, + "parserOptions": { + "ecmaVersion": 8 + }, + "rules": { + "no-const-assign": "warn", + "no-this-before-super": "warn", + "no-undef": "warn", + "no-unreachable": "warn", + "no-unused-vars": "warn", + "constructor-super": "warn", + "valid-typeof": "warn", + "semi": "warn", + "keyword-spacing": "warn", + "space-before-function-paren": "warn", + "space-before-blocks": "warn", + "indent": ["warn", 4], + "no-trailing-spaces": "warn", + "comma-style": ["error", "last"], + "eol-last": ["error", "always"] + } +} \ No newline at end of file diff --git a/README.md b/README.md index b68990d..a858eac 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,36 @@ -Emergence -========= +# Emergence [![Join the chat at https://gitter.im/JarvusInnovations/Emergence](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/JarvusInnovations/Emergence?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Emergence is a NodeJS-powered server that provides a web interface for configuring and launching the services that power your website or application. It provides virtualized storage containers for your code and assets that are accessible via WebDAV and API. Each storage container maintains complete version history for all files and can be linked over the web to a parent container that files will be inherited from just-in-time. +## Features -Features ---------- -* Rich web interface provides for all setup and management -* Plugin-based support for system services to be configured and run - * Plugins included for nginx and mysql -* Versioned storage containers - * Inherit remote containers over http - * Copy-on-write - * Accessible remotely via WebDAV and locally via API -* PHP development framework - * Classes automatically loaded from storage container - * Lightweight MVC classes optimized for serial inheritance across sites - * Extendable templating system powered by Dwoo +- Rich web interface provides for all setup and management +- Plugin-based support for system services to be configured and run + - Plugins included for nginx and mysql +- Versioned storage containers + - Inherit remote containers over http + - Copy-on-write + - Accessible remotely via WebDAV and locally via API +- PHP development framework + - Classes automatically loaded from storage container + - Lightweight MVC classes optimized for serial inheritance across sites + - Extendable templating system powered by Dwoo +## Requirements -Requirements -------------- -* NodeJS -* npm - * underscore - * node-static -* mysql -* nginx -* php-fpm - * php 5.3+ - * apc - * mysqli +- NodeJS +- npm +- mysql +- nginx +- php-fpm + - php 5.6+ + - apcu + - mysqli +## Installation -Installation --------------- -See http://emr.ge/docs +See [http://emr.ge/docs](http://emr.ge/docs) - - -Visit http://serverhost:9083 in your browser +Visit [http://serverhost:9083](http://serverhost:9083) in your browser diff --git a/bin/kernel b/bin/kernel index 97bd81d..f4eea7b 100755 --- a/bin/kernel +++ b/bin/kernel @@ -1,19 +1,12 @@ #!/usr/bin/env node +var fs = require('fs'), + sitesLib = require('../kernel-lib/sites.js'), -// requirements -var _ = require('underscore'), - util = require('util'), - url = require('url'), - path = require('path'), - fs = require('fs'), - sitesLib = require('../kernel-lib/sites.js'); + CONFIG; -var CONFIG; - if (fs.existsSync('/emergence/config.json')) { // try to load existing kernel config - CONFIG = JSON.parse(fs.readFileSync('/emergence/config.json', 'ascii')); } else { // try to smart-init a new kernel config @@ -53,8 +46,6 @@ if (fs.existsSync('/emergence/config.json')) { }; - - // detect nginx if (fs.existsSync('/usr/sbin/nginx')) { CONFIG.services.plugins.web = { @@ -138,11 +129,13 @@ if (fs.existsSync('/emergence/config.json')) { }; } + fs.writeFileSync('/emergence/config.json', JSON.stringify(CONFIG, null, 4)); fs.chmodSync('/emergence/config.json', '600'); console.log('Generated and wrote initial config: /emergence/config.json'); } + // create default admin user if (!fs.existsSync('/emergence/admins.htpasswd')) { console.log('Creating default administrative user: admin/admin'); @@ -155,6 +148,7 @@ if (!fs.existsSync('/emergence/admins.htpasswd')) { var eSites = sitesLib.createSites(CONFIG); var eServices = require('../kernel-lib/services.js').createServices(eSites, CONFIG); + // instantiate management server var eManagementServer = require('../kernel-lib/server.js').createServer({ sites: eSites, @@ -163,4 +157,4 @@ var eManagementServer = require('../kernel-lib/server.js').createServer({ // start server -eManagementServer.start(); \ No newline at end of file +eManagementServer.start(); diff --git a/kernel-lib/server.js b/kernel-lib/server.js index 820f386..1d715a8 100644 --- a/kernel-lib/server.js +++ b/kernel-lib/server.js @@ -3,14 +3,19 @@ var http = require('http'), util = require('util'), fs = require('fs'), path = require('path'), - _ = require('underscore'), util = require('util'), url = require('url'), static = require('node-static'), events = require('events'), nodeCleanup = require('node-cleanup'); -exports.Server = function(paths, config) { + +exports.createServer = function (paths, options) { + return new Server(paths, options); +}; + + +function Server (paths, config) { var me = this, options = config.server; @@ -31,10 +36,10 @@ exports.Server = function(paths, config) { nodeCleanup(this.close.bind(this)); }; -util.inherits(exports.Server, events.EventEmitter); +util.inherits(Server, events.EventEmitter); -exports.Server.prototype.start = function() { +Server.prototype.start = function () { // create authenticator this.httpAuth = require('http-auth')({ authRealm: 'Emergence Node Management', @@ -67,30 +72,25 @@ exports.Server.prototype.start = function() { console.log('Management server listening on '+this.webProtocol+'://'+this.options.host+':'+this.options.port); }; -exports.createServer = function(paths, options) { - return new exports.Server(paths, options); -}; - - -exports.Server.prototype.handleWebRequest = function(request, response) { +Server.prototype.handleWebRequest = function (request, response) { var me = this; - me.httpAuth.apply(request, response, function(username) { + me.httpAuth.apply(request, response, function () { me.handleRequest(request, response); }); }; -exports.Server.prototype.handleRequest = function(request, response) { +Server.prototype.handleRequest = function (request, response) { var me = this; request.content = ''; - request.addListener('data', function(chunk) { + request.addListener('data', function (chunk) { request.content += chunk; }); - request.addListener('end', function() { - request.urlInfo = url.parse(request.url) + request.addListener('end', function () { + request.urlInfo = url.parse(request.url); request.path = request.urlInfo.pathname.substr(1).split('/'); console.log(request.method+' '+request.url); @@ -122,7 +122,7 @@ exports.Server.prototype.handleRequest = function(request, response) { }); }; -exports.Server.prototype.close = function(options, error) { +Server.prototype.close = function () { console.log('Shutting down management server...'); if (this.webServer) { @@ -132,4 +132,4 @@ exports.Server.prototype.close = function(options, error) { if (this.socketServer) { this.socketServer.close(); } -}; \ No newline at end of file +}; diff --git a/kernel-lib/services.js b/kernel-lib/services.js index 0853748..db269b3 100644 --- a/kernel-lib/services.js +++ b/kernel-lib/services.js @@ -1,12 +1,17 @@ var _ = require('underscore'), util = require('util'), fs = require('fs'), - path = require('path'), events = require('events'); -exports.ServicesController = function(sites, config) { + +exports.createServices = function (sites, config) { + return new ServicesController(sites, config); +}; + + +function ServicesController (sites, config) { var me = this, - options = config.services; + options = config.services; me.sites = sites; @@ -47,7 +52,7 @@ exports.ServicesController = function(sites, config) { // load service plugins me.services = {}; - _.each(me.options.plugins, function(plugin, name) { + _.each(me.options.plugins, function (plugin, name) { console.log('Loading service: '+name); if (_.isString(plugin)) { @@ -60,7 +65,7 @@ exports.ServicesController = function(sites, config) { }); // auto-start service plugins - _.each(me.services, function(service, name) { + _.each(me.services, function (service, name) { if (service.options.autoStart) { console.log('Autostarting service: '+name); service.start(); @@ -68,10 +73,10 @@ exports.ServicesController = function(sites, config) { }); }; -util.inherits(exports.ServicesController, events.EventEmitter); +util.inherits(ServicesController, events.EventEmitter); -exports.ServicesController.prototype.handleRequest = function(request, response, server) { +ServicesController.prototype.handleRequest = function (request) { var me = this; if (request.path[1]) { @@ -83,7 +88,7 @@ exports.ServicesController.prototype.handleRequest = function(request, response, services: [] }; - _.each(me.services, function(service, name) { + _.each(me.services, function (service) { statusData.services.push(service.getStatus()); }); @@ -93,7 +98,7 @@ exports.ServicesController.prototype.handleRequest = function(request, response, return false; }; -exports.ServicesController.prototype.handleServiceRequest = function(request, response, server) { +ServicesController.prototype.handleServiceRequest = function (request) { var me = this, service = me.services[request.path[1]]; @@ -124,7 +129,3 @@ exports.ServicesController.prototype.handleServiceRequest = function(request, re return false; }; - -exports.createServices = function(sites, config) { - return new exports.ServicesController(sites, config); -}; \ No newline at end of file diff --git a/kernel-lib/services/abstract.js b/kernel-lib/services/abstract.js index e9e3071..5be0a77 100644 --- a/kernel-lib/services/abstract.js +++ b/kernel-lib/services/abstract.js @@ -1,13 +1,12 @@ -var _ = require('underscore') - ,util = require('util') - ,events = require('events'); +var util = require('util'), + events = require('events'); -exports.AbstractService = function(name, controller, options) { +function AbstractService (name, controller, options) { var me = this; // call events constructor - exports.AbstractService.super_.apply(me, arguments); + AbstractService.super_.apply(me, arguments); // initialize options and apply defaults me.name = name; @@ -19,28 +18,30 @@ exports.AbstractService = function(name, controller, options) { me.status = 'offline'; }; -util.inherits(exports.AbstractService, events.EventEmitter); +util.inherits(AbstractService, events.EventEmitter); +module.exports = AbstractService; -exports.AbstractService.prototype.getStatus = function() { + +AbstractService.prototype.getStatus = function () { return { - name: this.name - ,status: this.status + name: this.name, + status: this.status }; -} +}; -exports.AbstractService.prototype.start = function() { +AbstractService.prototype.start = function () { throw new Error('start() not implemented in '+this.name); }; -exports.AbstractService.prototype.stop = function() { +AbstractService.prototype.stop = function () { throw new Error('start() not implemented in '+this.name); }; -exports.AbstractService.prototype.restart = function() { +AbstractService.prototype.restart = function () { if (this.stop()) { return this.start(); } else { return false; } -}; \ No newline at end of file +}; diff --git a/kernel-lib/services/mysql.js b/kernel-lib/services/mysql.js index 7e9bba2..f835738 100644 --- a/kernel-lib/services/mysql.js +++ b/kernel-lib/services/mysql.js @@ -1,6 +1,5 @@ var _ = require('underscore'), fs = require('fs'), - path = require('path'), util = require('util'), spawn = require('child_process').spawn, exec = require('child_process').exec, @@ -8,16 +7,18 @@ var _ = require('underscore'), semver = require('semver'), mysql = require('mysql2'); -exports.createService = function(name, controller, options) { - return new exports.MysqlService(name, controller, options); + +exports.createService = function (name, controller, options) { + return new MysqlService(name, controller, options); }; -exports.MysqlService = function(name, controller, options) { + +function MysqlService (name, controller) { var me = this, versionMatch; // call parent constructor - exports.MysqlService.super_.apply(me, arguments); + MysqlService.super_.apply(me, arguments); // default options me.options.configPath = me.options.configPath || controller.options.configDir + '/my.cnf'; @@ -67,11 +68,10 @@ exports.MysqlService = function(name, controller, options) { controller.sites.on('siteCreated', _.bind(me.onSiteCreated, me)); }; -util.inherits(exports.MysqlService, require('./abstract.js').AbstractService); - +util.inherits(MysqlService, require('./abstract.js')); -exports.MysqlService.prototype.start = function(firstRun) { +MysqlService.prototype.start = function (firstRun) { var me = this; if (me.pid) { @@ -104,11 +104,11 @@ exports.MysqlService.prototype.start = function(firstRun) { exec('chown -R mysql:mysql '+me.options.dataDir); if (semver.lt(me.mysqldVersion, '5.7.6') || me.mysqldIsMaria) { - exec('mysql_install_db --defaults-file='+me.options.configPath, function(error, stdout, stderr) { + exec('mysql_install_db --defaults-file='+me.options.configPath, function () { me.start(true); }); } else { - exec('mysqld --initialize-insecure --user=mysql --datadir='+me.options.dataDir, function(error, stdout, stderr) { + exec('mysqld --initialize-insecure --user=mysql --datadir='+me.options.dataDir, function () { me.start(true); }); } @@ -155,8 +155,7 @@ exports.MysqlService.prototype.start = function(firstRun) { return true; }; - -exports.MysqlService.prototype.stop = function() { +MysqlService.prototype.stop = function () { var me = this; if (!me.pid) { @@ -176,7 +175,7 @@ exports.MysqlService.prototype.stop = function() { return true; }; -exports.MysqlService.prototype.restart = function() { +MysqlService.prototype.restart = function () { var me = this, now; @@ -200,11 +199,11 @@ exports.MysqlService.prototype.restart = function() { return me.start(); }; -exports.MysqlService.prototype.writeConfig = function() { +MysqlService.prototype.writeConfig = function () { fs.writeFileSync(this.options.configPath, this.makeConfig()); }; -exports.MysqlService.prototype.makeConfig = function() { +MysqlService.prototype.makeConfig = function () { var me = this, config = []; @@ -215,7 +214,7 @@ exports.MysqlService.prototype.makeConfig = function() { 'port = 3306', 'socket = '+me.options.socketPath, 'pid-file = '+me.options.pidPath, -// 'log-error = '+me.options.errorLogPath, // disabled due to http://bugs.mysql.com/bug.php?id=65592 -- errors output to STDIN will usually go into emergence-kernel's log + // 'log-error = '+me.options.errorLogPath, // disabled due to http://bugs.mysql.com/bug.php?id=65592 -- errors output to STDIN will usually go into emergence-kernel's log 'basedir = /usr', 'datadir = '+me.options.dataDir, 'skip-external-locking', @@ -226,7 +225,7 @@ exports.MysqlService.prototype.makeConfig = function() { 'read_buffer_size = 256K', 'read_rnd_buffer_size = 512K', 'myisam_sort_buffer_size = 8M', -// 'lc-messages-dir = /usr/local/share/mysql', + // 'lc-messages-dir = /usr/local/share/mysql', 'log-bin = mysqld-bin', 'expire_logs_days = 2', @@ -265,7 +264,7 @@ exports.MysqlService.prototype.makeConfig = function() { return config.join('\n'); }; -exports.MysqlService.prototype.secureInstallation = function() { +MysqlService.prototype.secureInstallation = function () { var me = this, sql = ''; @@ -299,7 +298,7 @@ exports.MysqlService.prototype.secureInstallation = function() { multipleStatements: true }); - connection.query(sql, function(error) { + connection.query(sql, function (error) { connection.end(); if (error) { @@ -310,8 +309,7 @@ exports.MysqlService.prototype.secureInstallation = function() { }); }; - -exports.MysqlService.prototype.onSiteCreated = function(siteData, requestData, callbacks) { +MysqlService.prototype.onSiteCreated = function (siteData, requestData, callbacks) { var me = this, sql = '', dbConfig = { @@ -328,7 +326,7 @@ exports.MysqlService.prototype.onSiteCreated = function(siteData, requestData, c sql += 'GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, LOCK TABLES ON `'+siteData.handle+'`.* TO \''+siteData.handle+'\'@\'localhost\';'; sql += 'FLUSH PRIVILEGES;'; - me.executeSQL(sql, function(error, results) { + me.executeSQL(sql, function (error) { if (error) { console.log(me.name+': failed to setup database `'+siteData.handle+'`: '+error); return; @@ -340,7 +338,7 @@ exports.MysqlService.prototype.onSiteCreated = function(siteData, requestData, c }); // populate tables - me.createSkeletonTables(siteData, function() { + me.createSkeletonTables(siteData, function () { if (callbacks.databaseReady) { callbacks.databaseReady(dbConfig, siteData, requestData); } @@ -348,9 +346,7 @@ exports.MysqlService.prototype.onSiteCreated = function(siteData, requestData, c }); }; - - -exports.MysqlService.prototype.createSkeletonTables = function(siteData, callback) { +MysqlService.prototype.createSkeletonTables = function (siteData, callback) { var me = this, sql = ''; @@ -389,7 +385,7 @@ exports.MysqlService.prototype.createSkeletonTables = function(siteData, callbac sql += ') ENGINE=MyISAM DEFAULT CHARSET=utf8;'; // run tables - me.executeSQL(sql, function(error, results) { + me.executeSQL(sql, function (error) { if (error) { console.log(me.name+': failed to setup skeleton tables on `'+siteData.handle+'`: '+error); return; @@ -401,9 +397,7 @@ exports.MysqlService.prototype.createSkeletonTables = function(siteData, callbac }); }; - - -exports.MysqlService.prototype.executeSQL = function(sql, callback) { +MysqlService.prototype.executeSQL = function (sql, callback) { var connection = mysql.createConnection({ socketPath: this.options.socketPath, user: this.options.managerUser, @@ -411,9 +405,9 @@ exports.MysqlService.prototype.executeSQL = function(sql, callback) { multipleStatements: true }); - connection.query(sql, function(err, results) { + connection.query(sql, function (err, results) { connection.end(); callback(err, results); }); -}; \ No newline at end of file +}; diff --git a/kernel-lib/services/nginx.js b/kernel-lib/services/nginx.js index 5e5d8a5..1428769 100644 --- a/kernel-lib/services/nginx.js +++ b/kernel-lib/services/nginx.js @@ -1,18 +1,19 @@ var _ = require('underscore'), fs = require('fs'), - path = require('path'), util = require('util'), spawn = require('child_process').spawn; -exports.createService = function(name, controller, options) { - return new exports.NginxService(name, controller, options); + +exports.createService = function (name, controller, options) { + return new NginxService(name, controller, options); }; -exports.NginxService = function(name, controller, options) { + +function NginxService (name, controller) { var me = this; // call parent constructor - exports.NginxService.super_.apply(me, arguments); + NginxService.super_.apply(me, arguments); // default options me.options.configPath = me.options.configPath || controller.options.configDir + '/nginx.conf'; @@ -50,11 +51,10 @@ exports.NginxService = function(name, controller, options) { controller.sites.on('siteUpdated', _.bind(me.onSiteCreated, me)); }; -util.inherits(exports.NginxService, require('./abstract.js').AbstractService); +util.inherits(NginxService, require('./abstract.js')); - -exports.NginxService.prototype.start = function() { +NginxService.prototype.start = function () { var me = this; console.log(me.name+': spawning daemon: '+me.options.execPath); @@ -83,7 +83,7 @@ exports.NginxService.prototype.start = function() { me.status = 'online'; } else { console.log(me.name+': failed to find pid after launching, waiting 1000ms and trying again...'); - setTimeout(function() { + setTimeout(function () { if (fs.existsSync(me.options.pidPath)) { me.pid = parseInt(fs.readFileSync(me.options.pidPath, 'ascii')); @@ -115,8 +115,7 @@ exports.NginxService.prototype.start = function() { return true; }; - -exports.NginxService.prototype.stop = function() { +NginxService.prototype.stop = function () { var me = this; if (!me.pid) { @@ -135,8 +134,7 @@ exports.NginxService.prototype.stop = function() { return true; }; - -exports.NginxService.prototype.restart = function() { +NginxService.prototype.restart = function () { var me = this; if (!me.pid) { @@ -157,12 +155,11 @@ exports.NginxService.prototype.restart = function() { return true; }; - -exports.NginxService.prototype.writeConfig = function() { +NginxService.prototype.writeConfig = function () { fs.writeFileSync(this.options.configPath, this.makeConfig()); }; -exports.NginxService.prototype.makeConfig = function() { +NginxService.prototype.makeConfig = function () { var me = this, phpSocketPath = me.controller.services['php'].options.socketPath, phpBootstrapDir = me.controller.services['php'].options.bootstrapDir, @@ -245,7 +242,7 @@ exports.NginxService.prototype.makeConfig = function() { ' fastcgi_buffers 32 64k;', ' server_tokens off;' -/* + /* ' server {', ' server_name _;', @@ -255,7 +252,7 @@ exports.NginxService.prototype.makeConfig = function() { */ ); - _.each(me.controller.sites.sites, function(site, handle) { + _.each(me.controller.sites.sites, function (site, handle) { var hostnames = site.hostnames.slice(), siteDir = me.controller.sites.options.sitesDir+'/'+handle, logsDir = siteDir+'/logs', @@ -309,7 +306,7 @@ exports.NginxService.prototype.makeConfig = function() { sslHostnames = {}; sslHostnames[site.primary_hostname] = site.ssl; - site.hostnames.forEach(function(hostname) { + site.hostnames.forEach(function (hostname) { sslHostnames[hostname] = site.ssl; }); } @@ -341,7 +338,6 @@ exports.NginxService.prototype.makeConfig = function() { return config.join('\n'); }; - -exports.NginxService.prototype.onSiteCreated = function(siteData) { +NginxService.prototype.onSiteCreated = function () { this.restart(); }; diff --git a/kernel-lib/services/php-fpm.js b/kernel-lib/services/php-fpm.js index 9cde0fd..a590552 100644 --- a/kernel-lib/services/php-fpm.js +++ b/kernel-lib/services/php-fpm.js @@ -5,15 +5,17 @@ var _ = require('underscore'), spawn = require('child_process').spawn, phpfpm = require('node-phpfpm'); -exports.createService = function(name, controller, options) { - return new exports.PhpFpmService(name, controller, options); + +exports.createService = function (name, controller, options) { + return new PhpFpmService(name, controller, options); }; -exports.PhpFpmService = function(name, controller, options) { + +function PhpFpmService (name, controller) { var me = this; // call parent constructor - exports.PhpFpmService.super_.apply(me, arguments); + PhpFpmService.super_.apply(me, arguments); // default options me.options.bootstrapDir = me.options.bootstrapDir || path.resolve(__dirname, '../../php-bootstrap'); @@ -48,11 +50,10 @@ exports.PhpFpmService = function(name, controller, options) { controller.sites.on('siteUpdated', _.bind(me.onSiteUpdated, me)); }; -util.inherits(exports.PhpFpmService, require('./abstract.js').AbstractService); +util.inherits(PhpFpmService, require('./abstract.js')); - -exports.PhpFpmService.prototype.start = function() { +PhpFpmService.prototype.start = function () { var me = this; console.log(me.name+': spawning daemon: '+me.options.execPath); @@ -101,10 +102,10 @@ exports.PhpFpmService.prototype.start = function() { this.status = 'online'; return true; -} +}; -exports.PhpFpmService.prototype.stop = function() { +PhpFpmService.prototype.stop = function () { var me = this; if (!me.pid) { @@ -124,7 +125,7 @@ exports.PhpFpmService.prototype.stop = function() { }; -exports.PhpFpmService.prototype.restart = function() { +PhpFpmService.prototype.restart = function () { var me = this; if (!me.pid) { @@ -146,11 +147,11 @@ exports.PhpFpmService.prototype.restart = function() { }; -exports.PhpFpmService.prototype.writeConfig = function() { +PhpFpmService.prototype.writeConfig = function () { fs.writeFileSync(this.options.configPath, this.makeConfig()); }; -exports.PhpFpmService.prototype.makeConfig = function() { +PhpFpmService.prototype.makeConfig = function () { var me = this, config = []; @@ -197,7 +198,7 @@ exports.PhpFpmService.prototype.makeConfig = function() { return config.join('\n'); }; -exports.PhpFpmService.prototype.onSiteUpdated = function(siteData) { +PhpFpmService.prototype.onSiteUpdated = function (siteData) { var me = this, siteRoot = me.controller.sites.options.sitesDir + '/' + siteData.handle, phpClient; @@ -216,7 +217,7 @@ exports.PhpFpmService.prototype.onSiteUpdated = function(siteData) { json: [ { action: 'delete', key: siteRoot } ] - }, function(err, output, phpErrors) { + }, function (err, output, phpErrors) { if (err == 99) console.error('PHPFPM server error'); console.log(output); if (phpErrors) console.error(phpErrors); diff --git a/kernel-lib/sites.js b/kernel-lib/sites.js index 60e2458..57b0810 100644 --- a/kernel-lib/sites.js +++ b/kernel-lib/sites.js @@ -10,13 +10,14 @@ var _ = require('underscore'), phpShellScript = path.resolve(__dirname, '../bin/shell'); -exports.createSites = function(config) { - return new exports.Sites(config); +exports.createSites = function (config) { + return new Sites(config); }; -exports.Sites = function(config) { + +function Sites (config) { var me = this, - options = config.sites; + options = config.sites; // call events constructor events.EventEmitter.call(me); @@ -38,7 +39,7 @@ exports.Sites = function(config) { console.log('Loading sites from '+me.options.sitesDir+'...'); me.sites = {}; - _.each(fs.readdirSync(me.options.sitesDir), function(handle) { + _.each(fs.readdirSync(me.options.sitesDir), function (handle) { try { me.sites[handle] = JSON.parse(fs.readFileSync(me.options.sitesDir+'/'+handle+'/site.json', 'ascii')); me.sites[handle].handle = handle; @@ -50,10 +51,10 @@ exports.Sites = function(config) { }; -util.inherits(exports.Sites, events.EventEmitter); +util.inherits(Sites, events.EventEmitter); -exports.Sites.prototype.handleRequest = function(request, response, server) { +Sites.prototype.handleRequest = function (request, response) { var me = this; if (request.method == 'GET') { @@ -149,11 +150,11 @@ exports.Sites.prototype.handleRequest = function(request, response, server) { phpProc = spawn(phpShellScript, [request.path[1]]); phpProcInitialized = false; - phpProc.stderr.on('data', function(data) { + phpProc.stderr.on('data', function (data) { console.log('php-cli stderr: ' + data); }); - phpProc.stdout.on('data', function(data) { + phpProc.stdout.on('data', function (data) { console.log('php-cli stdout: ' + data); // skip first chunk from PHP process @@ -181,11 +182,11 @@ exports.Sites.prototype.handleRequest = function(request, response, server) { phpProc = spawn(phpShellScript, [request.path[1], '--stdin']); - phpProc.stdout.on('data', function(data) { + phpProc.stdout.on('data', function (data) { console.log('php-cli stdout: ' + data); response.write(data); }); - phpProc.stderr.on('data', function(data) { console.log('php-cli stderr: ' + data); }); + phpProc.stderr.on('data', function (data) { console.log('php-cli stderr: ' + data); }); requestData.AccountLevel = 'Developer'; @@ -229,15 +230,15 @@ exports.Sites.prototype.handleRequest = function(request, response, server) { // notify plugins me.emit('siteCreated', cfgResult.site, requestData, { - databaseReady: function() { + databaseReady: function () { // execute onSiteCreated within site's container console.log('Executing Site::onSiteCreated() via php-cli'); phpProc = spawn(phpShellScript, [cfgResult.site.handle]); - phpProc.stdout.on('data', function(data) { console.log('php-cli stdout: ' + data); }); - phpProc.stderr.on('data', function(data) { console.log('php-cli stderr: ' + data); }); + phpProc.stdout.on('data', function (data) { console.log('php-cli stdout: ' + data); }); + phpProc.stderr.on('data', function (data) { console.log('php-cli stderr: ' + data); }); - function _phpExec(code) { + function _phpExec (code) { //console.log('php> '+code); phpProc.stdin.write(code+'\n'); } @@ -271,8 +272,7 @@ exports.Sites.prototype.handleRequest = function(request, response, server) { return false; }; - -exports.Sites.prototype.writeSiteConfig = function(requestData) { +Sites.prototype.writeSiteConfig = function (requestData) { var me = this, siteData = _.clone(requestData); @@ -342,7 +342,7 @@ exports.Sites.prototype.writeSiteConfig = function(requestData) { return {site: siteData, isNew: isNew}; }; -exports.Sites.prototype.updateSiteConfig = function(handle, changes) { +Sites.prototype.updateSiteConfig = function (handle, changes) { var me = this, siteDir = me.options.sitesDir+'/'+handle, filename = siteDir+'/site.json', @@ -361,8 +361,7 @@ exports.Sites.prototype.updateSiteConfig = function(handle, changes) { } }; - -exports.generatePassword = exports.Sites.prototype.generatePassword = function(length) { +Sites.prototype.generatePassword = function (length) { length = length || 16; var pass = '', @@ -374,3 +373,6 @@ exports.generatePassword = exports.Sites.prototype.generatePassword = function(l return pass; }; + + +exports.generatePassword = Sites.prototype.generatePassword; diff --git a/kernel-www/.eslintrc.json b/kernel-www/.eslintrc.json new file mode 100644 index 0000000..8e49afa --- /dev/null +++ b/kernel-www/.eslintrc.json @@ -0,0 +1,9 @@ +{ + "env": { + "browser": true + }, + "globals": { + "Ext": true, + "eMan": true + } +} \ No newline at end of file diff --git a/kernel-www/app.js b/kernel-www/app.js index f6323d6..5777386 100644 --- a/kernel-www/app.js +++ b/kernel-www/app.js @@ -1,36 +1,36 @@ // enable and configure loader Ext.Loader.setConfig({ - enabled:true - ,paths:{ - Ext: '//extjs.cachefly.net/ext/gpl/5.0.0/src' - } + enabled:true, + paths:{ + Ext: '//extjs.cachefly.net/ext/gpl/5.0.0/src' + } }); Ext.application({ - name: 'eMan' - ,appFolder: 'app' - - ,controllers: ['Viewport', 'Services', 'Sites', 'Log'] - - ,autoCreateViewport: false - - ,launch: function() { - eMan.app = this; - eMan.log = Ext.bind(eMan.app.log, eMan.app); - this.viewport = Ext.create('eMan.view.Viewport'); - this.viewport.setLoading(true); - Ext.Ajax.request({ - url: '/server-config' - ,success: function(response) { - var r = Ext.decode(response.responseText); - eMan.app.serverConfig = r; - eMan.app.viewport.setLoading(false); - } - }); - this.fireEvent('log', 'Emergence Manager ready.'); - } - - ,log: function(message) { - this.fireEvent('log', message); - } + name: 'eMan', + appFolder: 'app', + + controllers: ['Viewport', 'Services', 'Sites', 'Log'], + + autoCreateViewport: false, + + launch: function () { + eMan.app = this; + eMan.log = Ext.bind(eMan.app.log, eMan.app); + this.viewport = Ext.create('eMan.view.Viewport'); + this.viewport.setLoading(true); + Ext.Ajax.request({ + url: '/server-config', + success: function (response) { + var r = Ext.decode(response.responseText); + eMan.app.serverConfig = r; + eMan.app.viewport.setLoading(false); + } + }); + this.fireEvent('log', 'Emergence Manager ready.'); + }, + + log: function (message) { + this.fireEvent('log', message); + } }); diff --git a/kernel-www/app/controller/Log.js b/kernel-www/app/controller/Log.js index 4e2c2c7..c0cb88a 100644 --- a/kernel-www/app/controller/Log.js +++ b/kernel-www/app/controller/Log.js @@ -1,24 +1,23 @@ Ext.define('eMan.controller.Log', { - extend: 'Ext.app.Controller' + extend: 'Ext.app.Controller', - ,views: ['log.Grid'] - ,stores: ['Log'] - ,models: ['LogEntry'] + views: ['log.Grid'], + stores: ['Log'], + models: ['LogEntry'], - ,init: function() { - this.control({ - 'loggrid': { - afterrender: function(grid) { - eMan.app.on('log', function(message, type) { - this.getLogStore().insert(0, { - timestamp: new Date() - ,message: message - }); - }, this); - } - ,scope: this - } - }); - } - -}); \ No newline at end of file + init: function () { + this.control({ + 'loggrid': { + afterrender: function () { + eMan.app.on('log', function (message) { + this.getLogStore().insert(0, { + timestamp: new Date(), + message: message + }); + }, this); + }, + scope: this + } + }); + } +}); diff --git a/kernel-www/app/controller/Services.js b/kernel-www/app/controller/Services.js index 3e57841..672474a 100644 --- a/kernel-www/app/controller/Services.js +++ b/kernel-www/app/controller/Services.js @@ -1,138 +1,138 @@ Ext.define('eMan.controller.Services', { - extend: 'Ext.app.Controller' - - ,views: ['services.Grid'] - ,stores: ['Services'] - ,models: ['Service'] - - ,init: function() { - - this.startServiceBtn = new Ext.create('Ext.menu.Item', { - text: 'Start Service' - ,scope: this - ,handler: this.onStartPress - }); - - this.restartServiceBtn = new Ext.create('Ext.menu.Item', { - text: 'Restart Service' - ,scope: this - ,handler: this.onRestartPress - }); - - this.stopServiceBtn = new Ext.create('Ext.menu.Item', { - text: 'Stop Service' - ,scope: this - ,handler: this.onStopPress - }); - - this.servicesContextMenu = Ext.create('Ext.menu.Menu', { - items: [this.startServiceBtn, this.restartServiceBtn, this.stopServiceBtn] - }); - - this.control({ - 'servicesgrid gridview': { - scope: this - ,cellclick: function(view, cellEl, colIndex, record, rowEl, rowIndex, ev) { - if(colIndex == 1) - this.showServiceMenu(view, cellEl, record); + extend: 'Ext.app.Controller', + + views: ['services.Grid'], + stores: ['Services'], + models: ['Service'], + + init: function () { + + this.startServiceBtn = new Ext.create('Ext.menu.Item', { + text: 'Start Service', + scope: this, + handler: this.onStartPress + }); + + this.restartServiceBtn = new Ext.create('Ext.menu.Item', { + text: 'Restart Service', + scope: this, + handler: this.onRestartPress + }); + + this.stopServiceBtn = new Ext.create('Ext.menu.Item', { + text: 'Stop Service', + scope: this, + handler: this.onStopPress + }); + + this.servicesContextMenu = Ext.create('Ext.menu.Menu', { + items: [this.startServiceBtn, this.restartServiceBtn, this.stopServiceBtn] + }); + + this.control({ + 'servicesgrid gridview': { + scope: this, + cellclick: function (view, cellEl, colIndex, record) { + if (colIndex == 1) + this.showServiceMenu(view, cellEl, record); } - } - ,'servicesgrid tool[type=refresh]': { - scope: this - ,click: function() { - this.getServicesStore().load(); - } - } - }); - } - - ,showServiceMenu: function(view, cellEl, service) { - if(service.get('status') == 'offline') - { - this.startServiceBtn.show(); - this.restartServiceBtn.hide(); - this.stopServiceBtn.hide(); - } - else - { - this.startServiceBtn.hide(); - this.restartServiceBtn.show(); - this.stopServiceBtn.show(); - } - - this.servicesContextMenu.contextRecord = service; - this.servicesContextMenu.showBy(cellEl); - } - - ,onStartPress: function(btn, ev) { - var service = btn.parentMenu.contextRecord; - - eMan.log('Starting service '+service.get('name')+'...'); - service.set('status', 'starting...'); - - Ext.Ajax.request({ - url: '/services/'+service.get('name')+'/!start' - ,method: 'POST' - ,scope: this - ,success: function(response) { - var r = Ext.decode(response.responseText); - - eMan.log((r.success?'Successfully started service ':'Failed to start service')+service.get('name')); - - if(r.status) - { - service.set(r.status); - service.commit(); - } - } - }); - } - - ,onStopPress: function(btn, ev) { - var service = btn.parentMenu.contextRecord; - - eMan.log('Stopping service '+service.get('name')+'...'); - service.set('status', 'stopping...'); - - Ext.Ajax.request({ - url: '/services/'+service.get('name')+'/!stop' - ,method: 'POST' - ,scope: this - ,success: function(response) { - var r = Ext.decode(response.responseText); - - eMan.log((r.success?'Successfully stopped service ':'Failed to stop service ')+service.get('name')); - - if(r.status) - { - service.set(r.status); - service.commit(); - } - } - }); - } - - ,onRestartPress: function(btn, ev) { - var service = btn.parentMenu.contextRecord; - - eMan.log('Restarting service '+service.get('name')+'...'); - service.set('status', 'restarting...'); - - Ext.Ajax.request({ - url: '/services/'+service.get('name')+'/!restart' - ,method: 'POST' - ,scope: this - ,success: function(response) { - var r = Ext.decode(response.responseText); - - eMan.log((r.success?'Successfully restarted service ':'Failed to restart service ')+service.get('name')); - - if(r.status) - { - service.set(r.status); - service.commit(); - } - } - }); - } -}); \ No newline at end of file + }, + 'servicesgrid tool[type=refresh]': { + scope: this, + click: function () { + this.getServicesStore().load(); + } + } + }); + }, + + showServiceMenu: function (view, cellEl, service) { + if (service.get('status') == 'offline') + { + this.startServiceBtn.show(); + this.restartServiceBtn.hide(); + this.stopServiceBtn.hide(); + } + else + { + this.startServiceBtn.hide(); + this.restartServiceBtn.show(); + this.stopServiceBtn.show(); + } + + this.servicesContextMenu.contextRecord = service; + this.servicesContextMenu.showBy(cellEl); + }, + + onStartPress: function (btn) { + var service = btn.parentMenu.contextRecord; + + eMan.log('Starting service '+service.get('name')+'...'); + service.set('status', 'starting...'); + + Ext.Ajax.request({ + url: '/services/'+service.get('name')+'/!start', + method: 'POST', + scope: this, + success: function (response) { + var r = Ext.decode(response.responseText); + + eMan.log((r.success?'Successfully started service ':'Failed to start service')+service.get('name')); + + if (r.status) + { + service.set(r.status); + service.commit(); + } + } + }); + }, + + onStopPress: function (btn) { + var service = btn.parentMenu.contextRecord; + + eMan.log('Stopping service '+service.get('name')+'...'); + service.set('status', 'stopping...'); + + Ext.Ajax.request({ + url: '/services/'+service.get('name')+'/!stop', + method: 'POST', + scope: this, + success: function (response) { + var r = Ext.decode(response.responseText); + + eMan.log((r.success?'Successfully stopped service ':'Failed to stop service ')+service.get('name')); + + if (r.status) + { + service.set(r.status); + service.commit(); + } + } + }); + }, + + onRestartPress: function (btn) { + var service = btn.parentMenu.contextRecord; + + eMan.log('Restarting service '+service.get('name')+'...'); + service.set('status', 'restarting...'); + + Ext.Ajax.request({ + url: '/services/'+service.get('name')+'/!restart', + method: 'POST', + scope: this, + success: function (response) { + var r = Ext.decode(response.responseText); + + eMan.log((r.success?'Successfully restarted service ':'Failed to restart service ')+service.get('name')); + + if (r.status) + { + service.set(r.status); + service.commit(); + } + } + }); + } +}); diff --git a/kernel-www/app/controller/Sites.js b/kernel-www/app/controller/Sites.js index c8206c6..f7c30a5 100644 --- a/kernel-www/app/controller/Sites.js +++ b/kernel-www/app/controller/Sites.js @@ -1,69 +1,69 @@ Ext.define('eMan.controller.Sites', { - extend: 'Ext.app.Controller' - ,requires: ['Ext.Ajax', 'Ext.window.Window'] - - ,views: ['site.Grid', 'site.CreateForm', 'site.DeveloperForm', 'site.Menu'] - ,stores: ['Sites','Skeletons'] - ,models: ['Site'] - - ,refs: [{ - ref: 'siteMenu' - ,selector: 'sitemenu' - ,autoCreate: true - ,xtype: 'sitemenu' - },{ - ref: 'createForm' - ,selector: 'sitecreate' - ,autoCreate: true - ,xtype: 'sitecreate' - },{ - ref: 'developerWindow' - ,selector: 'window#developer-create' - ,autoCreate: true - - ,xtype: 'window' - ,itemId: 'developer' - ,title: 'Create developer user' - ,width: 400 - ,modal: true - ,items: { - xtype: 'developerform' - } - }] - - ,init: function() { - var me = this - ,skeletonsStore = me.getSkeletonsStore(); - - this.control({ - 'sitegrid': { - itemcontextmenu: me.onSiteContextMenu - } - ,'sitegrid button[action=create]': { - click: me.onCreateClick - } - ,'sitemenu menuitem[action=create-inheriting]': { + extend: 'Ext.app.Controller', + requires: ['Ext.Ajax', 'Ext.window.Window'], + + views: ['site.Grid', 'site.CreateForm', 'site.DeveloperForm', 'site.Menu'], + stores: ['Sites','Skeletons'], + models: ['Site'], + + refs: [{ + ref: 'siteMenu', + selector: 'sitemenu', + autoCreate: true, + xtype: 'sitemenu' + },{ + ref: 'createForm', + selector: 'sitecreate', + autoCreate: true, + xtype: 'sitecreate' + },{ + ref: 'developerWindow', + selector: 'window#developer-create', + autoCreate: true, + + xtype: 'window', + itemId: 'developer', + title: 'Create developer user', + width: 400, + modal: true, + items: { + xtype: 'developerform' + } + }], + + init: function () { + var me = this, + skeletonsStore = me.getSkeletonsStore(); + + this.control({ + 'sitegrid': { + itemcontextmenu: me.onSiteContextMenu + }, + 'sitegrid button[action=create]': { + click: me.onCreateClick + }, + 'sitemenu menuitem[action=create-inheriting]': { click: me.onCreateInheritingClick - } - ,'sitemenu menuitem[action=create-developer]': { + }, + 'sitemenu menuitem[action=create-developer]': { click: me.onCreateDeveloperClick + }, + 'sitecreate button[action=save]': { + click: me.createSite + }, + 'sitecreate button[action=cancel]': { + click: me.cancelCreateSite + }, + 'developerform button[action=save]': { + click: 'onDeveloperSaveClick' + }, + 'developerform button[action=cancel]': { + click: 'onDeveloperCancelClick' } - ,'sitecreate button[action=save]': { - click: me.createSite - } - ,'sitecreate button[action=cancel]': { - click: me.cancelCreateSite - } - ,'developerform button[action=save]': { - click: 'onDeveloperSaveClick' - } - ,'developerform button[action=cancel]': { - click: 'onDeveloperCancelClick' - } - }); - - // load and check that at least skeleton-v1 is in the store - skeletonsStore.load(function(records) { + }); + + // load and check that at least skeleton-v1 is in the store + skeletonsStore.load(function (records) { if (!records.length) { skeletonsStore.add({hostname: 'skeleton.emr.ge', key: '8U6kydil36bl3vlJ'}); skeletonsStore.sync(); @@ -71,9 +71,9 @@ Ext.define('eMan.controller.Sites', { // download latest Ext.Ajax.request({ - method: 'GET' - ,url: 'http://emr.ge/skeletons.json' - ,success: function(response) { + method: 'GET', + url: 'http://emr.ge/skeletons.json', + success: function (response) { var data = Ext.decode(response.responseText, true); if (data) { skeletonsStore.loadData(data); @@ -81,142 +81,142 @@ Ext.define('eMan.controller.Sites', { } } }); - }); - } - - ,showCreateForm: function(siteRecord, animateTarget) { - - this.editingSite = siteRecord; - - this.getCreateForm().loadRecord(this.editingSite); - - this.createWindow = Ext.create('Ext.window.Window', { - title: 'Create a new site' - ,width: 400 - ,modal: true - ,layout: 'fit' - ,items: this.getCreateForm() - ,listeners: { - scope: this - ,show: { - fn: function() { - this.getCreateForm().getForm().findField('label').focus(); - } - ,delay: 500 - } - } - }); - - this.createWindow.show(animateTarget); - } - - - ,createSite: function() { - var data = this.getCreateForm().getValues(); - - if(data.user_username || data.user_password || data.user_email || data.user_first || data.user_last) - { - if(!(data.user_username && data.user_password && data.user_email && data.user_first && data.user_last)) - { - Ext.Msg.alert('Incomplete user', 'Please fill out all fields for a first user'); - return false; - } - - data.create_user = { - Username: data.user_username - ,Password: data.user_password - ,Email: data.user_email - ,FirstName: data.user_first - ,LastName: data.user_last - }; - - delete data.user_email; - delete data.user_password; - delete data.user_email; - delete data.user_first; - delete data.user_last; - } - - this.editingSite.set(data); - this.getSitesStore().add(this.editingSite); - this.createWindow.close(); - } - - ,cancelCreateSite: function() { - this.createWindow.close(); - } - - ,onSiteContextMenu: function(tree, record, item, index, ev) { + }); + }, + + showCreateForm: function (siteRecord, animateTarget) { + + this.editingSite = siteRecord; + + this.getCreateForm().loadRecord(this.editingSite); + + this.createWindow = Ext.create('Ext.window.Window', { + title: 'Create a new site', + width: 400, + modal: true, + layout: 'fit', + items: this.getCreateForm(), + listeners: { + scope: this, + show: { + fn: function () { + this.getCreateForm().getForm().findField('label').focus(); + }, + delay: 500 + } + } + }); + + this.createWindow.show(animateTarget); + }, + + + createSite: function () { + var data = this.getCreateForm().getValues(); + + if (data.user_username || data.user_password || data.user_email || data.user_first || data.user_last) + { + if (!(data.user_username && data.user_password && data.user_email && data.user_first && data.user_last)) + { + Ext.Msg.alert('Incomplete user', 'Please fill out all fields for a first user'); + return false; + } + + data.create_user = { + Username: data.user_username, + Password: data.user_password, + Email: data.user_email, + FirstName: data.user_first, + LastName: data.user_last + }; + + delete data.user_email; + delete data.user_password; + delete data.user_email; + delete data.user_first; + delete data.user_last; + } + + this.editingSite.set(data); + this.getSitesStore().add(this.editingSite); + this.createWindow.close(); + }, + + cancelCreateSite: function () { + this.createWindow.close(); + }, + + onSiteContextMenu: function (tree, record, item, index, ev) { ev.stopEvent(); var menu = this.getSiteMenu(); menu.siteRecord = record; menu.showAt(ev.getXY()); - } + }, - ,onCreateClick: function(btn) { - var siteRecord = Ext.create('eMan.model.Site'); - this.showCreateForm(siteRecord, btn.el) - } + onCreateClick: function (btn) { + var siteRecord = Ext.create('eMan.model.Site'); + this.showCreateForm(siteRecord, btn.el); + }, - ,onCreateInheritingClick: function(menuItem) { + onCreateInheritingClick: function (menuItem) { var parentSite = menuItem.parentMenu.siteRecord; - var siteRecord = Ext.create('eMan.model.Site', { - parent_hostname: parentSite.get('primary_hostname') - ,parent_key: parentSite.get('inheritance_key') - }); + var siteRecord = Ext.create('eMan.model.Site', { + parent_hostname: parentSite.get('primary_hostname'), + parent_key: parentSite.get('inheritance_key') + }); - this.showCreateForm(siteRecord, menuItem.el); - } + this.showCreateForm(siteRecord, menuItem.el); + }, - ,onCreateDeveloperClick: function(menuItem) { + onCreateDeveloperClick: function (menuItem) { var developerWindow = this.getDeveloperWindow(), - developerForm = developerWindow.down('developerform'), - site = menuItem.parentMenu.siteRecord; + developerForm = developerWindow.down('developerform'), + site = menuItem.parentMenu.siteRecord; - developerForm.setSite(site); - developerWindow.setTitle(developerWindow.getInitialConfig('title') + ' for ' + site.get('handle')); - developerWindow.show(); - developerForm.getForm().findField('Email').focus(); - } + developerForm.setSite(site); + developerWindow.setTitle(developerWindow.getInitialConfig('title') + ' for ' + site.get('handle')); + developerWindow.show(); + developerForm.getForm().findField('Email').focus(); + }, - ,onDeveloperCancelClick: function() { - var developerWindow = this.getDeveloperWindow(); + onDeveloperCancelClick: function () { + var developerWindow = this.getDeveloperWindow(); - developerWindow.down('developerform').reset(); - developerWindow.close(); - } + developerWindow.down('developerform').reset(); + developerWindow.close(); + }, - ,onDeveloperSaveClick: function() { + onDeveloperSaveClick: function () { var developerWindow = this.getDeveloperWindow(), - developerForm = developerWindow.down('developerform'); - - developerWindow.setLoading('Creating developer…'); - Ext.Ajax.request({ - method: 'POST', - url: '/sites/'+developerForm.getSite().get('handle')+'/developers', - jsonData: developerForm.getValues(), - callback: function(operation, success, response) { - var responseData = success && Ext.decode(response.responseText), - errorMessage = 'Failed to create developer'; - - developerWindow.setLoading(false); - - if (!success || !responseData || !responseData.success || !responseData.data.ID) { - if (responseData.errors) { - errorMessage += ':
Response Header: $header
"); - } elseif(empty($options['returnResponse'])) { + } elseif (empty($options['returnResponse'])) { header($header); } @@ -183,7 +183,7 @@ public static function relayRequest($options) if (!empty($options['debug'])) { print(''); print_r(curl_getinfo($ch)); - print(''); + print(''); print('
'.var_export(curl_error($ch), true).''); print('
'); diff --git a/php-bootstrap/lib/Site.class.php b/php-bootstrap/lib/Site.class.php index a6c4b29..1f0ccc1 100644 --- a/php-bootstrap/lib/Site.class.php +++ b/php-bootstrap/lib/Site.class.php @@ -93,7 +93,7 @@ public static function initialize($rootPath, $hostname = null) // set useful transaction name and metadata for newrelic if (extension_loaded('newrelic')) { - newrelic_name_transaction(static::getConfig('handle') . '/' . implode('/', site::$requestPath)); + newrelic_name_transaction(static::getConfig('handle').'/'.implode('/', site::$requestPath)); if (isset($_SERVER['QUERY_STRING'])) { newrelic_add_custom_parameter('request.query', $_SERVER['QUERY_STRING']); @@ -167,7 +167,7 @@ public static function handleRequest() if (isset($_SERVER['HTTP_ORIGIN'])) { $hostname = strtolower(parse_url($_SERVER['HTTP_ORIGIN'], PHP_URL_HOST)); if ($hostname == strtolower(static::$hostname) || static::$permittedOrigins == '*' || in_array($hostname, static::$permittedOrigins)) { - header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']); + header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']); header('Access-Control-Allow-Credentials: true'); //header('Access-Control-Max-Age: 86400') } else { @@ -177,10 +177,10 @@ public static function handleRequest() } if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS' && isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) { - header('Access-Control-Allow-Methods: ' . $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']); + header('Access-Control-Allow-Methods: '.$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']); if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) { - header('Access-Control-Allow-Headers: ' . $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']); + header('Access-Control-Allow-Headers: '.$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']); } exit(); @@ -317,7 +317,7 @@ public static function getRequestPathResult($path) // if path component doesn't already end in .php, check for a .php match first if (substr($handle, -4) != '.php') { - array_push($searchPath, $handle . '.php'); + array_push($searchPath, $handle.'.php'); $foundNode = static::resolvePath($searchPath); // printf("\t\t%s\t%s\n", $foundNode ? 'matched' : 'missed', implode('/', $searchPath)); array_pop($searchPath); @@ -456,7 +456,7 @@ class_exists($className, false) if ($lastNsPos = strrpos($className, '\\')) { $namespace = substr($className, 0, $lastNsPos); $className = substr($className, $lastNsPos + 1); - $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR; + $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR; } else { $fileName = ''; } @@ -497,7 +497,7 @@ class_exists($className, false) public static function loadConfig($className) { - $cacheKey = 'class-config:' . $className; + $cacheKey = 'class-config:'.$className; if (!$configFileIds = Cache::fetch($cacheKey)) { @@ -508,7 +508,7 @@ public static function loadConfig($className) if ($lastNsPos = strrpos($className, '\\')) { $namespace = substr($className, 0, $lastNsPos); $className = substr($className, $lastNsPos + 1); - $path = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR; + $path = str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR; } else { $path = ''; } @@ -716,18 +716,18 @@ public static function redirect($path, $get = false, $hash = false) if (preg_match('/^https?:\/\//i', $path)) { $url = $path; } else { - $url = ($_SERVER['HTTPS'] ? 'https' : 'http') . '://' . static::$hostname . '/' . ltrim($path, '/'); + $url = ($_SERVER['HTTPS'] ? 'https' : 'http').'://'.static::$hostname.'/'.ltrim($path, '/'); } if ($get) { - $url .= '?' . (is_array($get) ? http_build_query($get) : $get); + $url .= '?'.(is_array($get) ? http_build_query($get) : $get); } if ($hash) { - $url .= '#' . $hash; + $url .= '#'.$hash; } - header('Location: ' . $url); + header('Location: '.$url); exit(); } @@ -780,12 +780,12 @@ public static function getVersionedRootUrl($path) $fsPath = $path; array_unshift($fsPath, 'site-root'); - $url = '/' . implode('/', $path); + $url = '/'.implode('/', $path); $Node = static::resolvePath($fsPath); if ($Node) { - return $url . '?_sha1=' . $Node->SHA1; + return $url.'?_sha1='.$Node->SHA1; } else { return $url; } diff --git a/php-bootstrap/lib/SiteCollection.class.php b/php-bootstrap/lib/SiteCollection.class.php index 157713a..7dfb4fe 100644 --- a/php-bootstrap/lib/SiteCollection.class.php +++ b/php-bootstrap/lib/SiteCollection.class.php @@ -25,10 +25,9 @@ public function __construct($handle, $record = null) if (static::$autoCreate) { $this->_record = static::createRecord($handle); } else { - throw new Exception('Collection with name ' . $handle . ' could not be located'); + throw new Exception('Collection with name '.$handle.' could not be located'); } } - } public function __get($name) @@ -73,12 +72,12 @@ public static function getCacheKey($handle, $parentID = null, $remote = false) $cacheKey .= sprintf('/%s/', $remote ? 'remote' : 'local'); } - return $cacheKey . $handle; + return $cacheKey.$handle; } public static function getByID($collectionID) { - $cacheKey = 'efs:col:' . $collectionID; + $cacheKey = 'efs:col:'.$collectionID; if (false === ($record = Cache::fetch($cacheKey))) { $record = DB::oneRecord( diff --git a/php-bootstrap/lib/SiteFile.class.php b/php-bootstrap/lib/SiteFile.class.php index ab14eac..65dac10 100644 --- a/php-bootstrap/lib/SiteFile.class.php +++ b/php-bootstrap/lib/SiteFile.class.php @@ -106,7 +106,7 @@ public static function getCacheKey($collectionID, $handle) public static function getByID($fileID) { - $cacheKey = 'efs:file:' . $fileID; + $cacheKey = 'efs:file:'.$fileID; if (false === ($record = Cache::fetch($cacheKey))) { $record = DB::oneRecord( @@ -211,7 +211,7 @@ public function getFullPath($root = null, $prependParent = true) public static function getRealPathByID($ID) { - return Site::$rootPath . '/' . static::$dataPath . '/' . $ID; + return Site::$rootPath.'/'.static::$dataPath.'/'.$ID; } public function getName() @@ -273,7 +273,7 @@ public static function create($collectionID, $handle, $data = null, $ancestorID return $record; } - function put($data, $ancestorID = null) + public function put($data, $ancestorID = null) { $record = null; $tempPath = tempnam(static::getRealPathByID(''), 'uploading'); @@ -512,7 +512,7 @@ public function outputAsResponse($includeAuthor = false) if (!empty($_GET['_sha1']) && $_GET['_sha1'] == $this->SHA1) { $expires = 60*60*24*365; header('Cache-Control: public, max-age='.$expires); - header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time()+$expires)); + header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time()+$expires)); header('Pragma: public'); } @@ -530,7 +530,7 @@ public function outputAsResponse($includeAuthor = false) header('Last-Modified: '.gmdate('D, d M Y H:i:s \G\M\T', $this->Timestamp)); if ($includeAuthor && $this->Author) { - header('Author: '.$this->Author->EmailRecipient); + header('Author: '.$this->Author->EmailRecipient); } readfile($this->RealPath); diff --git a/php-bootstrap/mail.php b/php-bootstrap/mail.php index 92cffbe..caa76f4 100644 --- a/php-bootstrap/mail.php +++ b/php-bootstrap/mail.php @@ -1,7 +1,7 @@