How to call cache:clear command with argumemt within another command - Symfony3 - php

I know that I can run a command within another command.
like this example..
$command = $this->getApplication()->find('cache:clear');
$arguments = array();
$input = new ArrayInput($arguments);
$returnCode = $command->run($input, $output);
$text = '';
if ($returnCode != 0) {
$text .= 'successfully...';
}
$output->writeln($text);
But when I trying to run the cache:clear command with their options-
$arguments = array(
'--env=prod' => true
);
I get the following error
[Symfony\Component\Console\Exception\InvalidOptionException]
The "--env=prod" option does not exist.
How can I run this command?

You should use it like:
$arguments = array(
'--env' => 'prod',
);

-- is only needed when passing an option, not an argument.
To make your command able to consider your argument, just use:
$arguments = ['env' => 'prod'];
If it doesn't work, simply use $input->setArgument('env', 'prod');

Related

Cannot run any process command in Symfony

I'm trying to run a linux process in Symfony 5.1 as described here:
https://symfony.com/doc/current/components/process.html
use Symfony\Component\Process\Process;
(...)
$command = 'echo hello';
$process = new Process([$command]);
$process->start();
foreach ($process as $type => $data) {
if ($process::OUT === $type) {
echo "\nRead from stdout: ".$data;
} else { // $process::ERR === $type
echo "\nRead from stderr: ".$data;
}
}
No matter what my command line is, I get the following output:
Read from stderr: sh: 1: exec: echo hello: not found
In the docs you mentioned you can see example: https://symfony.com/doc/current/components/process.html#usage
$process = new Process(['ls', '-lsa']);
Source code for Process constructor:
https://github.com/symfony/symfony/blob/5.1/src/Symfony/Component/Process/Process.php#L132
First parameter is:
* #param array $command The command to run and its arguments listed as separate entries
Try $process = new Process(['echo', 'hello']); not $process = new Process(['echo hello']);

How set ApplicationDefaultCredentials in Google Translate api php?

I'm trying to set Google Translation API on my server.
But code returns error "Could not construct ApplicationDefaultCredentials"
$translationClient = new Google\Cloud\Translate\V3\TranslationServiceClient();
putenv('GOOGLE_APPLICATION_CREDENTIALS="/path/to/credetials.json"');
$content = ['one', 'two', 'three'];
$targetLanguage = 'es';
$response = $translationClient->translateText(
$content,
$targetLanguage,
TranslationServiceClient::locationName('[ProjectID]', 'global')
);
$res = '';
foreach ($response->getTranslations() as $key => $translation) {
$separator = $key === 2
? '!'
: ', ';
$res .= $translation->getTranslatedText() . $separator;
}
} catch(\Exception $e) {
$res = $e->getMessage();
}
die(json_encode($res));
I've already spend a lot of time to setting it but with no result.
Please, help me
You can pass the credentials in a config variable and then initialize the client.
<?php
require __DIR__ . '/vendor/autoload.php';
use Google\Cloud\Translate\V2\TranslateClient;
/** Uncomment and populate these variables in your code */
$config = ['credentials' => 'key.json'];
$text = "The text to translate.";
$targetLanguage = "ja";
$translate = new TranslateClient($config);
$result = $translate->translate($text, [
"target" => $targetLanguage,
]);
print("Source language: $result[source]\n");
print("Translation: $result[text]\n");
?>
Source language: en
Translation: 翻訳するテキスト
Php putenv https://www.php.net/manual/en/function.putenv.php
Andrey this worked for me on Windows 10 Pro. Wampserver 3.2.0. Php 7.4.4. It definitely has a problem with Windows backslashes. Forwardslashes and avoiding double quotes and single quotes together has helped to bump the compiler along.
$file = trim("C:/users/boss/onedrive/desktop/google.json",'"');
putenv("GOOGLE_APPLICATION_CREDENTIALS=$file");

Get console.log from Selenium using php webdriver

I'm trying to run integration tests against some of our AMP pages to see if they validate. AMP runs validation if you append #development=1 to a URL and puts the results in console.log. I need to be able to read console.log to check this.
This is what I have so far:
$caps = DesiredCapabilities::firefox();
$caps->setCapability('loggingPrefs', array('browser'=>'ALL'));
//connect to selenium
$webdriver = RemoteWebDriver::create('http://127.0.0.1:4444/wd/hub', $caps);
$webdriver->get('https://www.example.com/amp/page.html#development=1');
sleep(10);
$logs = $webdriver->manage()->getLog('browser');
var_dump($logs);
Using Facebook's webdriver for PHP. I can get the logs back, but it doesn't seem to include anything from console.log. How can I capture this data?
As far as I can tell, the Facebook PHP WebDriver implementation does not seem to implement any of the LoggingPreferences "facilities". However, because PHP is what-I-believe-is-called weakly typed, you can "cheat" by making a call to:
$chromeCapabilities->setCapability( 'loggingPrefs', ['browser' => 'ALL'] );
And then later, call (say)
var_dump( $chromeDriver->manage()->getLog( 'browser' ) );
to access the console log.
The following is a working sample I used to get this working after about 30 hours of investigation - I hope it helps someone! It can use Selenium or not, if not, then it calls the ChromeDriver directly. The test site includes some JavaScript to explicitly write to the console.log:
<?php
require_once (__DIR__.'/../vendor/autoload.php');
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Chrome;
$javaPath = '"C:\\Program Files (x86)\\Common Files\\Oracle\\Java\\javapath\\java.exe"';
$seleniumPath = '"'. __DIR__ . '\\..\\selenium-server-standalone-3.141.5.jar"';
$chromeDriverPath = 'C:\path\to\chromedriver.exe';
$site = 'http://mytestsite';
$seleniumPort = 4445;
$useSelenium = true;
$chromeDriverPathEnvVar = 'webdriver.chrome.driver';
putenv( $chromeDriverPathEnvVar .'='. $chromeDriverPath );
$chromeOptions = new Chrome\ChromeOptions();
$chromeOptions->addArguments( array( '--headless' ) );
$chromeCapabilities = DesiredCapabilities::chrome();
$chromeCapabilities->setCapability( Chrome\ChromeOptions::CAPABILITY, $chromeOptions );
$chromeCapabilities->setCapability( 'loggingPrefs', ['browser' => 'ALL'] );
$selenium = null;
if ($useSelenium) {
$descriptorspec = array(
0 => array('pipe', 'r'), // stdin is a pipe that the child will read from
1 => array('file', __DIR__ . '/selenium_log-' . date('Ymd-His').'_'. $seleniumPort . '-stdout.txt', 'a'), // stdout is a pipe that the child will write to
2 => array('file', __DIR__ . '/selenium_log-' . date('Ymd-His').'_'. $seleniumPort . '-stderr.txt', 'a') // stderr is a file to write to
);
$selenium_cmd = $javaPath .' -D'. $chromeDriverPathEnvVar .'="'. $chromeDriverPath .'" -jar '. $seleniumPath .' -port '. $seleniumPort; // If interested, add .' -debug';
$selenium = proc_open( $selenium_cmd, $descriptorspec, $pipes, null, null, array( 'bypass_shell' => true ) );
$host = 'http://localhost:'. $seleniumPort .'/wd/hub'; // this is the default
$chromeDriver = RemoteWebDriver::create($host, $chromeCapabilities );
} else {
$chromeDriver = Facebook\WebDriver\Chrome\ChromeDriver::start( $chromeCapabilities );
}
$chromeDriver->get( $site );
var_dump( $chromeDriver->manage()->getLog( 'browser' ) );
$chromeDriver->quit(); sleep(1);
$chromeDriver->action(); sleep(1);
$chromeDriver->close();
if ($useSelenium) {
fclose( $pipes[0] );
proc_terminate( $selenium );
#pclose( $selenium );
}
I was banging my head against this for a while- getting an empty array returned from $driver->manage()->getLog('browser');. Then I found this github issue. I changed
$desiredCapabilities->setCapability('loggingPrefs', ['browser'=>'ALL']); to
$desiredCapabilities->setCapability('goog:loggingPrefs', ['browser'=>'ALL']);. The difference was adding in goog: before loggingPrefs.
After that, whammo, $driver->manage()->getLog('browser'); returns a non-empty array =).

Pass array as parameter to php script

I want to run php script and pass parameters to it. Parameter are in array.
I json_encode array:
$bot = array(
'timing' => '* * * * *',
'path' => '/sompath/'
);
$bot = json_encode($bot);
And send it to script:
exec('nohup php script.php "' . $bot . '" > /bot.log 2>&1 &');
But then, in script, I don' receive arguments:
print_r($argv[1]); // {path:/sompath/,frequency:*
Looks like special symbols like asterisks are not parsed and break json.
How do I pass array to another script and be shure that all arguments are kept?
If you want to pass the json data as a string you should first escape it:
$bot = array(
'timing' => '* * * * *',
'path' => '/sompath/'
);
$bot = json_encode($bot);
$bot=escapeshellarg($bot);
And then on the receiving script:
print_r(json_decode($argv[1]));
It was simple. Should use urlencode to pass json correctly.
exec('nohup php script.php "' . urlencode($bot) . '" > /bot.log 2>&1 &');
And then, in in script.php:
$params = urldecode($argv[1]);
$params = json_decode($params, true);
I can't send arguments using nohup. By the way, this code is working for me!
$arg1 = escapeshellarg("Hello World");
$ouput = shell_exec("php file.php {$arg1} >/dev/null 2>&1 &");
file.php
$argument = $argv[1];

Calling console command within command and get the output in Symfony2

I have a few console command in Symfony2 and I need to execute one command from another command with some parameters.
After successfull execution of the second command I need to get the result (as an array for example), not the display output.
How can I do that?
Here you can have a basic command inside a command. The output from the second command can be a json, then you just have to decode the output json to retrieve your array.
$command = $this->getApplication()->find('doctrine:fixtures:load');
$arguments = array(
//'--force' => true
''
);
$input = new ArrayInput($arguments);
$returnCode = $command->run($input, $output);
if($returnCode != 0) {
$text .= 'fixtures successfully loaded ...';
$output = json_decode(rtrim($output));
}
you have to pass the command in the arguments array, and to avoid the confirmation dialog in doctrine:fixtures:load you have to pass --append and not --force
$arguments = array(
'command' => 'doctrine:fixtures:load',
//'--append' => true
''
);
or it will fail with error message “Not enough arguments.”
There is an new Output class (as of v2.4.0) called BufferedOutput.
This is a very simple class that will return and clear the buffered output when the method fetch is called:
$output = new BufferedOutput();
$input = new ArrayInput($arguments);
$code = $command->run($input, $output);
if($code == 0) {
$outputText = $output->fetch();
echo $outputText;
}
I did the following
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\StreamOutput;
$tmpFile = tmpfile();
$output = new StreamOutput($tmpFile);
$input = new ArrayInput(array(
'parameter' => 'value',
));
$command = . . .
$command->run($input, $output);
fseek($tmpFile, 0);
$output = fread($tmpFile, 1024);
fclose($tmpFile);
echo $output;
¡it works!
I understand it's old post and above answers solves the problem with a bit of digging. In Symfony2.7, I had a bit issue making it work, so with above suggestions, I dug a little and have compiled the full answer here. Hope it will be useful for someone.
Using Console command under console command
As an update for Onema's answer, in Symfony 3.4.x (used by Drupal 8),
you also need to set setAutoExit(false),
and the command returns an int(0) if successful.
Here's the updated example that I'm using to script composer commands in php for a Drupal 8.8 project. This gets a list of all composer packages as json, then decodes that into a php object.
<?php
require __DIR__.'/vendor/autoload.php';
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Input\ArrayInput;
use Composer\Console\Application;
$input = new ArrayInput([
'command' => 'show',
'--format'=>'json',
]);
$output = new BufferedOutput();
$application = new Application();
// required to use BufferedOutput()
$application->setAutoExit(false);
// composer package list, formatted as json, will be barfed into $output
$status = $application->run($input, $output);
if($status === 0) {
// grab the output from the $output buffer
$json = $output->fetch();
// decode the json string into an object
$list = json_decode($json);
// Profit!
print_r($list);
}
?>
The output will be something like this:
stdClass Object
(
[installed] => Array
(
... omitted ...
[91] => stdClass Object
(
[name] => drupal/core
[version] => 8.9.12
[description] => Drupal is an open source content management platform powering millions of websites and applications.
)
... omitted ...
)
)
With the help of Onema's hint Google found the rest of the solution for me here.

Categories