dotenv-connector within TYPO3 CMS - typo3

I try to use helhum/dotenv-connector in my TYPO3 Project.
I have done the following:
my composer.json:
{
"require": {
"typo3/cms": "^8.5",
"helhum/dotenv-connector": "1.0.0",
"helhum/typo3-console": "^4.1"
},
"extra": {
"helhum/typo3-console": {
"install-extension-dummy": false
},
"typo3/cms": {
"cms-package-dir": "{$vendor-dir}/typo3/cms",
"web-dir": "web"
},
"helhum/dotenv-connector": {
"env-dir": "",
"allow-overrides": true,
"cache-dir": "var/cache"
}
}
}
Then I ran
composer install
After that I setup the TYPO3 using the command
php vendor/bin/typo3cms install:setup
This should be similar with doing the install the "normal" way.
After that, i placed a .env next to my composer.json
This .env contains the following:
TYPO3_CONTEXT="Development"
TYPO3__DB__database="dotenvconnector"
TYPO3__DB__host="127.0.0.1"
TYPO3__DB__password="root"
TYPO3__DB__port="3306"
TYPO3__DB__username="root"
Then i removed all informations about the DB from web/typo3conf/LocalConfiguration.php using the typo3_console-command
php vendor/bin/typo3cms configuration:remove DB
I then ran composer install and composer update again.
When calling the TYPO3 in the browser now, it keeps telling me
The requested database connection named "Default" has not been configured.
So what am i missing? Obviously my .env is not parsed or used at all.
FYI: Cachefile is written in var/cache with the following content:
<?php
putenv('TYPO3__DB__database=dotenvconnector');
$_ENV['TYPO3__DB__database'] = 'dotenvconnector';
$_SERVER['TYPO3__DB__database'] = 'dotenvconnector';
putenv('TYPO3__DB__host=localhost');
$_ENV['TYPO3__DB__host'] = 'localhost';
$_SERVER['TYPO3__DB__host'] = 'localhost';
putenv('TYPO3__DB__password=root');
$_ENV['TYPO3__DB__password'] = 'root';
$_SERVER['TYPO3__DB__password'] = 'root';
putenv('TYPO3__DB__port=3306');
$_ENV['TYPO3__DB__port'] = '3306';
$_SERVER['TYPO3__DB__port'] = '3306';
putenv('TYPO3__DB__username=root');
$_ENV['TYPO3__DB__username'] = 'root';
$_SERVER['TYPO3__DB__username'] = 'root';

Our setups work like this:
AdditionalConfiguration.php
$loader = new Dotenv\Dotenv(__DIR__ . '/../../', '.env.defaults');
$loader->load();
$loader = new Dotenv\Dotenv(__DIR__ . '/../../');
$loader->overload();
Interesting to see here that we run with a .env.defaults file that holds the standard config (no users or passwords of course) which we then overload with the custom .env file per user/environment.
This helps a lot when adding new functionality which requires a new .env configuration so other people on the team don't run into Fatals or Exceptions.
$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['dbname'] = getenv('TYPO3_DB_NAME');
$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['host'] = getenv('TYPO3_DB_HOST');
$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['password'] = getenv('TYPO3_DB_PASSWORD');
$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['user'] = getenv('TYPO3_DB_USER');
LocalConfiguration.php
return [
'BE' => [
'debug' => '<set by dotenv>',
'explicitADmode' => 'explicitAllow',
'installToolPassword' => '<set by dotenv>',
'loginSecurityLevel' => 'rsa',
'sessionTimeout' => '<set by dotenv>',
],
'DB' => [
'Connections' => [
'Default' => [
'charset' => 'utf8',
'dbname' => '<set by dotenv>',
'driver' => 'mysqli',
'host' => '<set by dotenv>',
'password' => '<set by dotenv>',
'port' => 3306,
'user' => '<set by dotenv>',
],
],
]...
I didn't paste the entire config but I think you get the point.

The dotenv-connector reads the .env file into the environment, but does not assign any values to TYPO3 configuration variables. You should be able to read them with getenv in your php code.
The connector is not specifically geared towards TYPO3, but is a general tool for any composer based php application. Therefore it would be out of the scope of the project, to know about the TYPO3 specific variable assignments.
There is another project, the configuration loader, that can help to assign environment variables to TYPO3 configuration variables.
.env -dotenv-connector-> environment -configuration-loader-> $GLOBALS['TYPO3_CONF_VARS']
The configuration loader can be found at https://github.com/helhum/config-loader . And an example of it all wired together in https://github.com/helhum/TYPO3-Distribution .
You don't have to use the configuration loader. You could also assign the values manually with getenv().

One important note with PHP 7.2 (on TYPO3 v9) and the usage of argon hash:
You must use single quotes / ticks for the values in the .env file.
Example:
Instead of my_value="foobar"
write my_value='foobar'

Related

PHP Warning in Typo3DatabaseBackend line 158 after updating DDEV to 1.19

After updating DDEV to 1.19 I get following error after backend login in TYPO3 11.5.8:
PHP Warning: gzuncompress(): need dictionary in
/var/www/html/public/typo3/sysext/core/Classes/Cache/Backend/Typo3DatabaseBackend.php
line 158
I already tried a lot of things:
I have tried all officially PHP versions which are possible with DDEV.
I have downgraded doctrine/dbal 2.13.8, 2.13.7, 2.13.6, ...
I have downgraded MariaDB 10.3 to 10.2
Nothing works. So it needs a deeper view of the problem:
In Typo3DatabaseBackend.php at line 158 I have added
$tmp = gzuncompress($data);
With help of xdebug I can see that uncompress works without any problems. So, IMO it can't be a zlib problem.
As next step I have converted the compressed $data with bin2hex($data) into $tmp and in my database I have tried to HEX the value, too:
SELECT uid, CONVERT(content USING utf8) FROM cache_rootline WHERE uid = 1;
Interesting point:
Before: 789c4d904172c3200
In DB: 0x783f4d3f41723f200
Select: 783f4d3f41723f200
Nearly each 2nd byte is correct, but the other bytes are totally wrong.
I have exported my MariaDB data and switched to MySQL 8.0 and imported the data again. Because of some utf8mb4_unicode_ci incompatibilities I have recreated all cache tables with help of Installtool of TYPO3.
After login to TYPO3 backend I got following error:
General error: 3988 Conversion from collation utf8_general_ci into utf8mb4_unicode_ci impossible
I have searched full TYPO3 project, but I can't find utf8_general_ci anywhere.
Do you have any idea, what could be wrong?
Thank you for your help.
Stefan
On new DDEV project four LocalConfiguration looks something like that:
'DB' => [
'Connections' => [
'Default' => [
'charset' => 'utf8',
'driver' => 'mysqli',
],
],
],
and DDEV creates following to your AdditionalConfiguration.php
'DB' => [
'Connections' => [
'Default' => [
'dbname' => 'db',
'driver' => 'pdo_mysql',
'host' => 'db',
'password' => 'db',
'port' => '3306',
'user' => 'db',
],
],
],
Maybe you have added following to your configuration to create new tables with a specific collation:
'DB' => [
'Connections' => [
'Default' => [
...
'tableoptions' => [
'charset' => 'utf8mb4',
'collate' => 'utf8mb4_general_ci',
],
],
],
],
Do you see the problem? The charset option of LocalConfiguration.php was NOT overwritten in your AdditionalConfiguration. So, you have a charset miss-match in your configuration. Please keep them in sync.
Either set collation back to utf8_unicode_ci or add:
'charset' => 'utf8mb4',
in AdditionalConfiguration.php
Have fun with TYPO3
Stefan
For me the easiest way was to replace the pdo_mysql driver with mysqli.
Because I'm only using MariaDB and my database was utf8_general_ci encoded, this was the easiest fix/help.

MongoDB Connect Issue jenssegers/laravel-mongodb

I'm using jenssegers/laravel-mongodb MongoDB Jenssegers
I'm running into an issue where I can't seem to connect using the framework, but using a simple test script, I can connect fine.
The simple connection script I wrote:
<?php
$manager = new MongoDB\Driver\Manager("mongodb://user:password#cluster0-shard-00-00-reodz.mongodb.net:27017,cluster0-shard-00-01-reodz.mongodb.net:27017,cluster0-shard-00-02-reodz.mongodb.net:27017/test?ssl=true&replicaSet=Cluster0-shard-0&authSource=admin");//ssl=true
$command = new \MongoDB\Driver\Command(["ping" => 1]);
$cursor = $manager->executeCommand("admin", $command);
$reply = $cursor->toArray()[0];
var_dump($reply);
When I run that, I get
["ok"]=> int(1)
Which is what I expect and is all good. I setup my config/database.php file with the same connection string, this is my config/database.php file:
return [
'default' => env('DB_CONNECTION','mongodb'),
'connections' => [
'mongodb' => [
'driver' => 'mongodb',
'dsn' => env('DB_DSN','mongodb://user:password#cluster0-shard-00-00-reodz.mongodb.net:27017,cluster0-shard-00-01-reodz.mongodb.net:27017,cluster0-shard-00-02-reodz.mongodb.net:27017/test?ssl=true&replicaSet=Cluster0-shard-0&authSource=admin'),
'database' => env('DB_DATABASE'),
]
]
];
The .env file:
APP_ENV=local
APP_DEBUG=true
APP_KEY=
APP_TIMEZONE=UTC
#DB_CONNECTION=mongodb
#DB_HOST="cluster0-shard-00-00-reodz.mongodb.net"
#DB_PORT=27017
DB_DATABASE="test"
#DB_USERNAME="user"
#DB_PASSWORD="password"
CACHE_DRIVER=file
QUEUE_DRIVER=sync
When I access a route that I've associated with MongoDB, I'm getting:
(1/1) ConnectionTimeoutException
No suitable servers found (serverSelectionTryOnce set): [Failed to resolve 'user:password#cluster0-shard-00-00-reodz.mongodb.net:27017,cluster0-shard-00-01-reodz.mongodb.net:27017,cluster0-shard-00-02-reodz.mongodb.net:27017/test?ssl=true&replicaset=cluster0-shard-0&authsource=admin']
I would assume the problem is localized to my database.php file or my .env file, does anyone see an error? If the test.php can connect and return the ping, shouldn't Lumen be good to go?
Thanks
D

Set Module name, Controller name, and Action name in Zend framework?

I recently started programming with Zend Framework.I want to change module name, controller name and action name of a module in my framework through coding, while coding in the same framework.
Its name is Application(module & controller) and I want to change it to Institute. Is this possible through coding?
I searched through Google for help, but either i couldn't find it or understand it properly. Any help would be appreciated.
This is really just a case of renaming things:
Update all namespaces from Application to Institute in all the classes in the module including the Module.php
Update the name of the controller and it's entry in config/module.config.php
Make sure you update the name of your view directory if you have one in the module, ie view/application/index etc to view/institute/index and make sure you update the entry in module.config.php to the same path
Update name of Application directory to Institute
Update the name in the array of modules in modules.config.php or if you are using an earlier version application.config.php from under the modules key.
That's all I can think of you would need to do
******** EDIT ********
So the basic idea would be as follows:
Add a console in a new module (I've used zend mvc console but you should probably use https://github.com/zfcampus/zf-console as mvc console is deprecated)
module.config.php
<?php
namespace Rename;
use Zend\ServiceManager\Factory\InvokableFactory;
return [
'console' => array(
'router' => array(
'routes' => array(
'rename-module' => array(
'options' => array(
'route' => 'module rename <moduleNameOld> <moduleNameNew>',
'defaults' => array(
'controller' => Controller\IndexController::class,
'action' => 'rename'
)
)
)
)
)
),
'controllers' => [
'factories' => [
Controller\IndexController::class => InvokableFactory::class,
],
],
];
IndexController.php
<?php
namespace Rename\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Console\Request as ConsoleRequest;
use Zend\Mvc\Console\Controller\AbstractConsoleController;
class IndexController extends AbstractConsoleController
{
public function renameAction()
{
$request = $this->getRequest();
// Make sure that we are running in a console and the user has not tricked our
// application into running this action from a public web server.
if (!$request instanceof ConsoleRequest) {
throw new \RuntimeException('You can only use this action from a console!');
}
$moduleNameOld = $request->getParam('moduleNameOld');
$moduleNameNew = $request->getParam('moduleNameNew');
$module = file_get_contents(getcwd() . "/module/$moduleNameOld/src/Module.php", 'r+');
$updatedModule = str_replace($moduleNameOld, $moduleNameNew, $module);
file_put_contents(getcwd() . "/module/$moduleNameOld/src/Module.php", $updatedModule);
rename("module/$moduleNameOld", "module/$moduleNameNew");
}
}
This can be run like
php public/index.php module rename Application Institute
I've only done renaming the module here and renaming the namespace in the Module.php
to finish this off you would need to recursively find all .php files in the Application directory and loop over applying the string replace (which should be improved really). Then you could update the view and application level config too with similar logic and using the steps above.
The code I've written is pretty bad and probably insecure but might help you along the way

how to access local.php file from controller in zf3

I am working with Zend-framework 3. I want to access the content of config files (local.php) in the controller. please explain. Thank you all in advance.
After some research, I found the simplest way to access any config file. Just in your Module.php pass $container->get('config') as one of the argument to your controller's constructor and voila you can now access any property in the controller. That much simple. :-) Happy coding..!!
You can do something like this (it's not tested):
// config.php
return [
'webhost' => 'www.example.com',
'database' => [
'adapter' => 'pdo_mysql',
'params' => [
'host' => 'db.example.com',
'username' => 'dbuser',
'password' => 'secret',
'dbname' => 'mydatabase',
],
],
];
And in your controller:
// Consumes the configuration array
$config = new Zend\Config\Config(include 'config.php');
// Print a configuration datum (results in 'www.example.com')
echo $config->webhost;
Presume, you have this ZF3 package: zend-config
If you dont have, you have to include it via composer
composer require zendframework/zend-config

No translation for the language - Works on development server but not in production

While translation works fine on the development server we get the following notice on the production server: No translation for the language 'fr' available.
Here is the translation configuration in the bootstrap (forcing the locale for the test) :
$locale = "fr_CA.utf8";
$translate = new Zend_Translate(
array(
'adapter'=>'gettext',
'content' => APPLICATION_PATH . '/lang',
'locale' => $locale,
'scan' => Zend_Translate::LOCALE_DIRECTORY,
'disableNotices' => false,
'clear' =>true,
'reload'=>true,
)
);
The .mo file is in APPLICATION_PATH/lang/fr_CA.utf8/LC_MESSAGES/messages.mo
There are translated strings in the .mo file and the locale exists on both servers, according to "locale -a".
Any clue as to why such a setup could work on one server and not the other?
EDIT :
I got it to work with the following configuration :
$translate = new Zend_Translate(
array(
'adapter'=>'gettext',
'content' => APPLICATION_PATH.'/lang/'.$locale.'/LC_MESSAGES/messages.mo',
'locale' => $locale,
'disableNotices' => true,
'clear' =>true,
'reload'=>true,
)
);
It seems like the scanning was not working.
I had a similar problem (using the array adapter)
Reason: production site webroot path contains hidden directory /home/.sites/path/to/my/webroot/
// Settings:
$locale = new Zend_Locale('browser');
$language = $locale->getLanguage();
// Solution: added option 'ignore' => '===' to override
// default $_options settings in Zend_Translate_Adapter
$translate = new Zend_Translate(array(
'adapter' => 'array',
'content' => APPLICATION_PATH . '/languages/' . $language,
'scan' => Zend_Translate::LOCALE_DIRECTORY,
'locale' => $locale,
'ignore' => '===', // override default '.'
));
I had a similar problem but using application.ini to configure translation.
These were the Zend_Translate related lines:
resources.translate.adapter = "gettext"
resources.translate.content = APPLICATION_PATH "/languages"
resources.translate.options.scan = 'directory'
This worked fine on our development server but not on our staging server. We had to remove the quotes from the scan option:
resources.translate.options.scan = directory
Without quotes it worked. But I have no idea why this particular config line can't handle quotes on our staging server.