"Failed to locate civicrm.settings.php" using example cv wrapper function fails
artfulrobot opened this issue · 1 comments
I'm logging this here for the sake of others being able to find/recognise the issue.
Symptom
My script:
#!/usr/bin/env php
<?php
function cv(...) // From the latest README.
// This call fails
eval(cv('php:boot', 'phpcode'));
// This succeeds:
eval(`cv php:boot`);
The error is:
[Exception]
Failed to locate civicrm.settings.php. By default, this tool searches the parent directories for a standard CMS (Drupal, WordPress, etal) and standard civicrm.settings.php. Symlinks andmul
tisite configurations may interfere. To customize, set variable CIVICRM_SETTINGS to point to the preferred civicrm.settings.php.
The environment is D7, CiviCRM 5.15.1, PHP 7.3 (in a VirtualBox).
Problem
The problem seems to be that the cv()
function assumes that the script itself lives inside the CiviCRM webroot.
If your script is somewhere else (e.g. ~/bin/myscript
) then because the proc_open
call passes in __DIR__
the process runs from your ~/bin
dir, and of course then it can't find CiviCRM.
Fix ideas
We could document that the script MUST be in the CiviCRM webroot to work.
in which case I think we should add some guards against it being run over http, e.g. I regularly use this at the top of cli scripts:
if (php_sapi_name() !== 'cli') {
// Fail with 404 if not called from CLI.
if (isset($_SERVER['HTTP_PROTOCOL'])) {
header("$_SERVER[HTTP_PROTOCOL] 404 Not Found");
}
exit;
}
Or we could make it an option to the demo cv function, e.g.
/**
* @param string $dir
* script|cwd|/some/other/directory
*/
function cv($cmd, $decode = 'json', $dir = 'script') {
if ($dir === 'script') {
$dir = __DIR__;
}
elseif ($dir === 'cwd') {
$dir = getcwd();
}
}
That feels messy though.
How about using a constant: we could include this at the top:
// You will need to change this, e.g. to getcwd() if your script does not
// live inside your webroot.
define('CV_WORKING_DIR', __DIR__);
It would be nice to have the ability to add aliases and run commands on multiple sites at once :)