I'm working on a Drupal 8 starter kit with Composer, similar to drupal-composer/drupal-project.
In my post-install script, I want to re-generate a settings.php file with my custom values.
I've seen that can be done with the drupal_rewrite_settings function.
For example, I'm rewriting the config_sync_directory value like that :
require_once $drupalRoot . '/core/includes/bootstrap.inc';
require_once $drupalRoot . '/core/includes/install.inc';
new Settings([]);
$settings['settings']['config_sync_directory'] = (object) [
'value' => '../config/sync',
'required' => TRUE,
];
drupal_rewrite_settings($settings, $drupalRoot . '/sites/default/settings.php');
Problem is I want my Drupal 8 project to have a Dotenv so the maintainers don't have to modify the settings.php but only a .env file in the root folder of the project. To make it work, my settings.php must look like this :
$databases['default']['default'] = [
'database' => getenv('MYSQL_DATABASE'),
'driver' => 'mysql',
'host' => getenv('MYSQL_HOSTNAME'),
'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
'password' => getenv('MYSQL_PASSWORD'),
'port' => '',
'prefix' => '',
'username' => getenv('MYSQL_USER'),
];
$settings['trusted_host_patterns'] = explode(',', '^'.getenv('SITE_URL').'$');
As you can see, the values are replaced by PHP functions, and I can't see a good way to print those values, to the point I'm not even sure that's possible.
So my question is : is it possible to escape a PHP function as an Array value when declaring this variable ?
Looks like it's not possible because of the way the Drupal function works.
Solution 1 by #misorude
Using the drupal_rewrite_settings function, we can add the value of settings as a String, like this :
$settings['settings']['trusted_host_patterns'] = (object) [
'value' => "FUNC[explode(',', '^'.getenv('SITE_URL').'$')]",
'required' => TRUE,
];
And after that, we can replace all occurrences of "FUNC[***]" by *** directly in the settings.php file.
Solution 2
Put all your settings in a separate file. Example here, a custom.settings.php file :
if (getenv('DEBUG') == 'true') {
$settings['container_yamls'][] = DRUPAL_ROOT . '/sites/dev.services.yml';
$config['system.performance']['css']['preprocess'] = FALSE;
$config['system.performance']['js']['preprocess'] = FALSE;
}
$databases['default']['default'] = [
'database' => getenv('MYSQL_DATABASE'),
'driver' => 'mysql',
'host' => getenv('MYSQL_HOSTNAME'),
'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
'password' => getenv('MYSQL_PASSWORD'),
'port' => '',
'prefix' => '',
'username' => getenv('MYSQL_USER'),
];
$settings['trusted_host_patterns'] = explode(',', '^'.getenv('SITE_URL').'$');
$settings['file_private_path'] = 'sites/default/files/private';
$settings['config_sync_directory'] = '../config/sync';
Then we can copy the default.settings.php and add our custom settings.
$fs = new Filesystem();
$settings_generated = $drupalRoot . '/sites/default/settings.php';
$settings_default = $drupalRoot . '/sites/default/default.settings.php';
$settings_custom = $drupalRoot . '/../includes/custom.settings.php';
$fs->remove($settings_generated);
$fs->dumpFile($settings_generated, file_get_contents($settings_default) . file_get_contents($settings_custom));
There's also a appendToFile method that seems way better than dumping a new file with dumpFile, but it was not working unfortunatly.
Related
I want to upload a file from Laravel to another server using FTP.
It seems a very simple task, so let's take a look at my configurations:
.env file
FTP_HOST=dl.myserver.com
FTP_USERNAME=beni#dl.myserver.com
FTP_PASSWORD=somePass
filesystem.php
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'ftp' => [
'driver' => 'ftp',
'host' => env('FTP_HOST'),
'username' => env('FTP_USERNAME'),
'password' => env('FTP_PASSWORD'),
'passive' => true,
'port' => 21,
'root' => '/home/myserver/public_html/podcasts'
],
.
.
.
and my controller finally
$year = Carbon::now()->year;
$month = Carbon::now()->month;
$day = Carbon::now()->day;
//podcast
$podcast = $request->file('podcast');
$filename = $podcast->getClientOriginalName();
$purename = substr($filename, 0, strrpos($filename, '.'));
$filenametostore = $purename . '_' . $year .'_' . $month . '_' . $day . '.' . $podcast->getClientOriginalExtension();
Storage::disk('ftp')->put($filenametostore, fopen($request->file('podcast'), 'r+'));
.
.
.
but I have this error:
League\Flysystem\ConnectionRuntimeException
Could not log in with connection: dl.myserver.com::21, username:
beni#dl.myserver.com
My FTP account and information is true because I logged in using FileZilla.
As a mention, my dl.server.com is using CPANEL.
Is there any Idea about this issue?
Thanks in Advance
You need to put the password with double quotes in your .env
Particularly if your password contains spaces or #
FTP_PASSWORD="some#Pass"
Surprisingly the problem solved when I replaced env('FTP_HOST'), env('FTP_USERNAME') and env('FTP_PASSWORD') with equivalent string values in filesystems.php file!
I tried pure PHP FTP functions and figured it out:
$conn_id = ftp_connect("dl.myserver.com");
ftp_login($conn_id, "beni#dl.myserver.com", "somePass");
dd(ftp_put($conn_id, $filenametostore, $request->file('podcast'), FTP_ASCII));
So my Laravel filesystem.php looks like this:
'ftp' => [
'driver' => 'ftp',
'host' => "dl.myserver.com", //env('FTP_HOST'),
'username' => "beni#dl.myserver.com", //env('FTP_USERNAME'),
'password' => "somePass", //env('FTP_PASSWORD'),
],
and it works fine in my case.
Is there anyway to change the baseUrl of CKFinder dynamically?
I need to use this kind of path: /websitebuilder/www/user_images/$id/. I used google to find some answer, but I didn't manage to make it works.
Can someone please give me any hint how should I do that?
I know that in config.php you change the baseUrl param, but how to make it dinamically?
Hi you can use the example for different folder per instance CKFinder 3 HOWTO.
Basically you should update you config.php to something like this:
$id = getID();
$config['backends'][] = array(
'name' => 'default',
'adapter' => 'local',
'baseUrl' => 'http://example.com/ckfinder/userfiles/' . $id,
'root' => '/path/to/ckfinder/userfiles/' . $id
);
1 create new middleware:
php artisan make:middleware DynamicCkfinderConfig
with this code in the handel function :
not forget to 'use Auth' in the top of file;
public function handle(Request $request, Closure $next)
{
if (auth()->check()) {
config([
'ckfinder.backends.default' => [
'name' => 'default',
'adapter' => 'local',
'baseUrl' => '/user-' . md5(Auth::user()->id) . '/',
'root' => public_path('/user-' . md5(Auth::user()->id) . '/'),
'chmodFiles' => 0777,
'chmodFolders' => 0755,
'filesystemEncoding' => 'UTF-8'
]
]);
}
return $next($request);
}
2 add the middleware in the kernel.php file
protected $routeMiddleware = [
'ckfinderConfig' => \App\Http\Middleware\DynamicCkfinderConfig::class,
];
3 use the middleware in the ckfinder connector route
Route::any('/ckfinder/connector', [CKFinderController::class, 'requestAction'])
->name('ckfinder_connector')->middleware(['ckfinderConfig']);
I have managed to connect my app with ireport 5.6.0. It does produces a pdf file. My only problem now is that the pdf file only contains one row and null values.
Although I have tested it a lot, I even printed the parameter directly in the report and it is displayed. I don't know what to do anymore.
When I tried to query in iReport it gives me value like in the image
But when I transfer the condition in my code, it will just give me a pdf file with null and one row.
$my_where = "where fempidno='0828' and year(fdate)='2017' and month(fdate)='08' limit 30";
$text = '"' . $my_where . '"';
$output = public_path() . '/reports/report1';
$jasper = new JasperPHP;
// Compile a JRXML to Jasper
$jasper->compile(public_path() . '/reports/report1.jrxml')->execute();
$jasper->process(
base_path('/public/reports/report1.jasper'),
false,
array('pdf'),
array('title' => $text)
)->execute();
I also replaced in iReport so that it will be
SELECT * FROM dtr $P!{title}
The result will is still null with one row only. :-(
Looks like you did not pass connection or used the wrong connection string.
You can pass connection like at this sample:
JasperPHP::process(
base_path('/public/reports/report1.jasper'),
false,
array('pdf'),
array('title' => $text),
array(
'driver' => 'postgres',
'username' => 'username',
'host' => 'localhost',
'database' => 'mydb',
'port' => '5433',
)
)->execute();
or like this:
JasperPHP::process(
base_path('/public/reports/report1.jasper'),
false,
array('pdf'),
array('title' => $text),
\Config::get('database.connections.mysql')
)->execute();
More information about using JasperPHP can be found here
I'm having some problems while trying to get phalcon webtools working.
When using command line devtools I can create controllers and models without problems.
However, things aren't that easy with the webtools.
It correctly shows already created controllers and models:
Controllers (http://i.imgur.com/IRWPaVJ.png)
Models (http://i.imgur.com/rIbvbg9.png)
And I can also edit them (http://i.imgur.com/orJweLl.png).
Apparently, Db connexion is ok, since webtools shows every table in the DB:
Models (http://i.imgur.com/iOkZfyo.png)
Scaffolding (http://i.imgur.com/5ZLRuq5.png)
However, when trying to create a controller from the web interface, I got the next error:
"Please specify a controller directory"
Same when trying to create a Model from a database table :
"Database configuration cannot be loaded from your config file"
Or when trying to generate scaffold :
"Adapter was not found in the config. Please specify a config variable
[database][adapter]"
My app/config/config.php content:
return new \Phalcon\Config(array(
'database' => array(
'adapter' => 'Mysql',
'host' => 'localhost',
'username' => 'phalcon',
'password' => 'phalcon',
'dbname' => 'phalcon',
'charset' => 'utf8',
),
'application' => array(
'controllersDir' => __DIR__ . '/../../app/controllers/',
'modelsDir' => __DIR__ . '/../../app/models/',
'viewsDir' => __DIR__ . '/../../app/views/',
'pluginsDir' => __DIR__ . '/../../app/plugins/',
'libraryDir' => __DIR__ . '/../../app/library/',
'cacheDir' => __DIR__ . '/../../app/cache/',
'baseUri' => '/phalconTest/',
)
));
My public/webtools.config.php content:
define('PTOOLS_IP', '192.168.248.135');
define('PTOOLSPATH', 'C:/phalcon-devtools');
My public/webtools.php:
use Phalcon\Web\Tools;
require 'webtools.config.php';
require PTOOLSPATH . '/scripts/Phalcon/Web/Tools.php';
Tools::main(PTOOLSPATH, PTOOLS_IP);
Im running Phalcon 1.3.4 - Windows x86 for PHP 5.4.0 (VC9)
It seems like a bug in webtools.
Look at vendor/phalcon/devtools/scripts/Phalcon/Builder/Component.php
there is the _getConfig function.
The quick and dirty solution is prepend ../ to path.
You need to change the first line in app/config/config.php
defined('APP_PATH') || define('APP_PATH', realpath('..'));
To add to some of the answers, the editing of configPath by prepending ../ and also some code changes, has forgotten a a little '/' when modelPath has been rtrimmed.
Also, code will be updated and fixed but as of now, one can probably fix the issues by editing your/path/phalcon-devtools/scripts/Phalcon/Builder/Model.php; find
$modelsDir = rtrim(rtrim($modelsDir, '/'), '\\') . DIRECTORY_SEPARATOR;
if ($this->isAbsolutePath($modelsDir) == false) {
$modelPath = $path . DIRECTORY_SEPARATOR . $modelsDir;
} else {
// $modelPath = $modelsDir;
// replace or ADD TO LINE ABOVE so it looks like BELOW:
$modelPath = DIRECTORY_SEPARATOR . $modelsDir;
}
Then Models will work in webtools along with TKF's answer. Enjoy.
Apply changes in webtools.config.php like here:
<?php
if (!defined('PTOOLS_IP'))
define('PTOOLS_IP', '192.168.');
if (!defined('PTOOLSPATH'))
define('PTOOLSPATH', '/path/to/phalcon/devtools');
return array(
'application' => array(
'controllersDir' => __DIR__ . '/../../app/controllers/',
'modelsDir' => __DIR__ . '/../../app/models/',
),
'database' => array(
'adapter' => 'Mysql',
'host' => 'localhost',
'username' => 'usr',
'password' => 'pwd',
'dbname' => 'dbname',
)
);
Somewhat related, I had an issue with the webtools url getting longer and longer .. Eventually I could fix this by adding the word webtools in a replacement for the baseUri in config.php .
<?php ### config.php ... somewhat relevant parts ...
return new \Phalcon\Config([
'database' => [ # ... some things ...
],
'application' => [ # ... some more ...
// This allows the baseUri to be understand project paths that are not in the root directory
// of the webpspace. This will break if the public/index.php entry point is moved or
// possibly if the web server rewrite rules are changed. This can also be set to a static path.
'baseUri' => preg_replace(
'/(public([\/\\\\]))?(index)|(webtools).php$/',
'',
$_SERVER["PHP_SELF"]
),
]
]);
I want to use Laravel Environment for my Database credential, I did this:
inside bootstrap\start.php :
$env = $app->detectEnvironment(array(
'local' => array('My_PC'),
'production' => array('server.example.com')
));
created .env.local.php on same directory where serve.php is, and inside this code:
return array(
'DATABASE_NAME' => 'laravel_db',
'DATABASE_USER' => 'root',
'DATABASE_PASSWORD' => '1234'
);
and inside app\config created a local\app.php file containing this code:
return array(
'debug' => true,
);
and inside the app\config\database.php for my secured mysql connection I did:
'mysql' => array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => $_ENV['DATABASE_NAME'],
'username' => $_ENV['DATABASE_USER'],
'password' => $_ENV['DATABASE_PASSWORD'],
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
but I'm getting an error on the CLI:
{"error":{"type":"ErrorException","message":"Undefined index: DATABASE_NAME","file":"c:\\xampp\\htdocs\\Larave_project\\app\\config\\database.php","line":58}}
How to resolve this issue?
The hostname based env detection solution will only work on Unix type system.
It won't work on Windows.
In Laravel 4.2 you can detect environment this way:
$env = $app->detectEnvironment(function() {
if ($_SERVER['SERVER_NAME'] == "127.0.0.1") {
$domain = $_SERVER['HTTP_HOST'];
if (strpos($domain, 'localhost') !== FALSE || strpos($domain, "127.0.0.1") !== FALSE) {
die("Configure your local `hosts` file and go to address: http://{storeName}.local");
}
$len = strpos($domain, ".local");
if ($len !== FALSE) {
// will load .env.*.php
$len = strpos($domain, ".local");
$env = substr($domain, 0, $len);
return $env;
}
}
// will load .env.php
return 'production';
});
(this is bootstrap/start.php)
Then:
setup hosts file (in your operating system) to redirect mysuperstore.local to 127.0.0.1
go to URL like http://mysuperstore.local which loads .env.mysuperstore.php into $_ENV.
In configuration files (those placed in app/config/) refer to $_ENV. To see where $_ENV does come from take a look into documentation topic about "Protecting Sensitive Configuration".