Dynamic config file for shell commands in CakePHP 3.6 - cakephp-3.0

I have to work with multiple applications with the same code.
I have a project structure like below:
- same coding for all applications.
- different domains for different application.
- separate database for each application.
- different app.php and .env file for each application.(Ex. app1.php and .env1 | app2.php and .env2)
Now I need to work like I want to load different app.php and .env file application-wise.
How to load config files dynamically?

You can do it on your bootstrap.php file. you can conditionally load your configuration file (app_domain1.php or app_domain2.php).
// config/bootstrap.pnp
try {
Configure::config('default', new PhpConfig());
Configure::load('env', 'default');
if (requestd_domain == domain1) {
Configure::load('app_domain1', 'default', false);
}elseif(requestd_domain == domain2){
Configure::load('app_domain2', 'default', false);
}else{
Configure::load('app', 'default', false);
}
} catch (\Exception $e) {
exit($e->getMessage() . "\n");
}
You can get requested domain with $_SERVER['HTTP_HOST']
Hope your problem will be solve
For more details check Loading Additional Configuration Files

Related

Importing JSON file in Cucumber Protractor framework

I want to keep my test data in a JSON file that I need to import in cucumber-protractor custom framework. I read we can directly require a JSON file or even use protractor params. However that doesn't work. I don't see the JSON file listed when requiring from a particular folder.
testdata.json
{
"name":"testdata",
"version":"1.0.0",
"username":"1020201",
"password":"1020201"
}
Code in the Config.js
onPrepare: function() {
var data = require('./testdata.json');
},
I don't see the testdata.json file when giving path in require though its available at the location.
I wish to access JSON data using data.name, data.version etc.
Following is my folder structure:
You should make sure your json file is located in the current directory & and in the same folder where your config file resides as you are giving this path require('./testdata.json'); -
There are many ways of setting your data variables and accessing them globally in your test scripts -
1st method: Preferred method is to use node's global object -
onPrepare: function() {
global.data = require('./testdata.json');
},
Now you could access data anywhere in your scripts.
2nd Method Is to use protractor's param object -
exports.config = {
params: {
data: require('./testdata.json');
}
};
you can then access it in the specs/test scripts using browser.params.data

vuejs: the correct path of local json file for axios get request

In my Vue project, I have mocked some data for next step development. I already save the test data in a json file. And my vue project is typical one created with Vue-Cli, and the structure for my project goes as following:
My_project
build
config
data
service_general_info.json
node_modules
src
components
component-A
component-A.vue
as you can see, all the folders are created by the vue-cli originally. And I make a new folder data and place the test data json file inside.
And I want to read in the data by axios library in an event handling function inside the component of component-A as following:
methods: {
addData() {
console.log('add json data...');
axios.get('./../../data/service_general_info.json');
},
},
I use relative path to locate the target file.But get 404 error back. So how to set the path correctly? Currently I am running the dev mode in local host.
The error message is: GET http://localhost:8080/data/service_general_info.json 404 (Not Found)
In Vue-cli project, axios can't get data from custom folder.
You should use static folder to save test json file.
So you should change axios call like this:
axios.get('/static/service_general_info.json');
This will get data from json.
If you are doing just for sake of testing then you can save it in public folder and access it directly on http root.
e.g. I have the file results.json in public folder then I can access it using http://localhost:8080/results.json
For me it didn't work using static folder. I had to put it in public folder.
I put json folder in public & then accessed it like below.
getCountries() {
return axios.get('json/country-by-abbreviation.json', { baseURL: window.location.origin })
.then((response) => { return response.data; })
.catch((error) => {
throw error.response.data;
});
}
When the http call is made from the server, axios has no idea that you're on http://localhost:8080, you have to give the full url.
Like this:
methods: {
addData() {
console.log('add json data...');
axios.get('http://localhost:8080/data/service_general_info.json');
},
},
I had this same issue, only the above solutions wouldn't work as it is being uploaded to a subdirectory. I found I needed to put it in the public/assets folder and use:
axios.get(process.env.BASE_URL+'assets/file.json')
While in vue.config.js I have set the local and live paths
module.exports = {
publicPath: process.env.NODE_ENV === 'production'
? '/path/to/app/'
: '/'
}
You can simply read a static JSON file using import. Then assign in data.
import ServiceInfo from './../../data/service_general_info.json';
export default{
data(){
return {
ServiceInfo
}
}
}

--node-args in PM2 while using json config mode

I have a question, that's how to pass "--node-args" arguments in PM2 while using json config mode, like this:
pm2 start --node-args="--debug=5858" myPm2Config.json
well, I know I can write the arguments into myPm2Config.json file, but I dont want to do this, because I want to make two startup command as "debug" and "production" mode for launch application, such as "pm2_run" and "pm2_debug", and "pm2_debug" command with --node-args argument and "pm2_run" not, and I dont want to make two "myPm2Config.json" files, because that means if something needs changed, I will need to change two json config files, so, is there any easy way to do it? thanks guys!
I have found the solution! that's use js config instead of json config.
first, I create a pm2.config.js file. (mark: file name must be end with .config.js)
//[pm2.config.js]
let config = {
apps : [{
name : "node_shells",
script : "./bin/www",
log_date_format : "YYYY-MM-DD HH:mm:SS",
log_file : "logs/pm2.log",
error_file : "logs/pm2-err.log",
out_file : "logs/pm2-out.log",
pid_file : "logs/pm2.pid",
watch : true,
ignore_watch : ["logs/*", "node_modules/*", "uploads/*"]
}]
}
let debug_mode = false;
for(let arg of process.argv) {
if(arg == '-debug') {
debug_mode = true;
break;
}
}
if(debug_mode) {
console.log('== launching in debug mode ==');
config.apps[0].node_args = "--debug=5858";
}
else {
console.log('== launching in production mode ==');
config.apps[0].node_args = " "; //*require! or it will always uses latest debug options
}
module.exports = config;
then, create two launch files: "pm2_run" and "pm2_debug".
#[pm2_run]
pm2 start pm2.config.js
#[pm2_debug]
pm2 start pm2.config.js -- -debug
now, it's easy to switch debug mode or production mode!

Wildcard in Angular http.get?

I have multiple JSON files in one directory, and I am going to build the view contents from those JSON files. The JSON files are identical in structure.
What is the correct syntax for loading multiple JSON files for use with ng-repeat? I tried with this, but it throws a permission denied error (the view is loaded via a route, if it matters. Still learning Angular...).
I use these:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular-route.min.js"></script>
Snippet from the view:
<div ng-controller="releases">
<article ng-repeat="album in albums">
{{ album.artist }}
</article>
</div>
Controller:
myApp.controller('releases', function($scope, $http) {
$scope.albums = [];
$http.get('contents/releases/*.json')
.then(function(releases) {
$scope.albums = releases.data;
console.log($scope.albums);
});
});
The JSON files are like this:
{
"artist" : "Artist name",
"album" : "Album title",
"releaseDate" : "2015-09-16"
}
The error message is:
You don't have permission to access /mypage/angular/contents/releases/*.json on this server.
If I use an exact filename, for example $http.get('contents/releases/album.json'), I can access the data correctly. But naturally only for one JSON, instead of the 11 files I have.
In a previous site I have done with PHP, I used an identical method, and there I could access the same files with no problem. For both, I'm using WAMP server (Apache 2) as the platform.
Could it still have something to do with the Apache config? The reason I don't think it is that, is because it does work in PHP like this:
// Get release data
$releasesDataLocation = 'contents/releases/*.json';
$releasesDataFiles = glob($releasesDataLocation);
rsort($releasesDataFiles); // Rsort = newest release first, comment out to show oldest first
// Show the releases
foreach($releasesDataFiles as $releaseData) {
$release = new Release($releaseData);
$release->display();
}
Wildcard AFAIK in such URLs is not allowed. You should build a server side endpoint that should read all the files in your directory on server, concatenate and return the response to you.
For eX: you could expose a GET URL: /api/contents/releases
and server side handler of it can read the directory containing all release JSONs and return to you.

Play 2.0 routes file for different configurations

I have a Play 2.0 application with 3 different configurations (application.conf, test.conf and prod.conf)
Now I have a robots.txt file that should be delivered for only test.conf and for the rest environments it should give a 404 if someone tries to access it.
How can I configure my routes file to check if my application is using test.conf? Can I set some variable in test.conf that I can check in the routes file?
Something like this? (pseudo code)
#{if environment = "test"}
GET /robots.txt controllers.Assets.at(path="/public", file="robots.txt")
#{/if}
#{else}
GET /robots.txt controllers.Application.notFoundResult()
#{/else}
You can't add logic in the routes file.
I'd write a controller to serve the robots.txt file. Something like this:
In the routes file:
GET /robots.txt controllers.Application.robots
Then, in the controller, I'll test if I'm in a testing environment :
def robots = Action {
if (environment == "test") { // customize with your method
Redirect(routes.Assets.at("robots.txt"))
} else {
NotFound("")
}
}
I'm using Scala, but it can be easily translated to Java.
Edit - java sample
You can check if application is in one of three states: prod, dev or test, ie, simple method returning current state:
private static String getCurrentMode() {
if (play.Play.isTest()) return "test";
if (play.Play.isDev()) return "dev";
if (play.Play.isProd()) return "prod";
return "unknown";
}
you can use as:
play.Logger.debug("Current mode: "+ getCurrentMode());
of course in your case that's enough to use these condition directly:
public static Result robots() {
return (play.Play.isProd())
? notFound()
: ok("User-agent: *\nDisallow: /");
}