Laravel PHP Process cannot run node - php

I am trying to build an angular project from a Laravel project.
When I run an exec command from Laravel I got env: node: No such file or directory
Steps to reproduce :
create Laravel project: laravel new laravel-bug
create angular project: ng new angular-bug
In the Laravel file routes/web.php, in the / route, add:
use Symfony\Component\Process\Process;
$process = new Process('cd /path/to/angular-bug && ng build');
$process->run(function ($type, $buffer) {
if (Process::ERR === $type) {
echo 'ERR > '.$buffer;
} else {
echo 'OUT > '.$buffer;
}
});
This will output the result, which for me is env: node: No such file or directory
Any ideas ?

I've had this issue before when node wasn't in the path of the web server user. The second argument to the Process::run() method is an array of environment variables. Use it to set a path.
<?php
use Symfony\Component\Process\Process;
$env = ["PATH" => "/sbin;/bin:/usr/sbin:/usr/bin:/path/to/node/if/its/different"];
$process = new Process('cd /path/to/angular-bug && ng build');
$process->run(function ($type, $buffer) {
if (Process::ERR === $type) {
echo 'ERR > '.$buffer;
} else {
echo 'OUT > '.$buffer;
}
}, $env);
The problem is that somewhere in this build process something is just calling node and expecting it will be in the path. (I think I experienced it when running npm.) This is not a great thing to do, and the software should be aware of where it’s located due to a compile-time setting or information from the package management system, or it should attempt to locate it.

Related

Brocken metadata class generation via protobuf on alpine Docker images

Sometime ago I've used ubuntu image for PHP files generation via protoc lib and it generates some metadata classes with normal hashes used by protobuf.
It was generated smth like:
namespace MyApp\ProtobufMetadata\Schema\v1;
class Request
{
public static $is_initialized = false;
public static function initOnce() {
$pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
if (static::$is_initialized == true) {
return;
}
$pool->internalAddGeneratedFile(hex2bin(
"0acd010a236170692f636174616c6f672f736368656d612f76312f726571756573742e70726f746f121d6170692e636174616c6f672e736368656d612e76312e72657175657374221d0a0a47657452657175657374120f0a0776657273696f6e18012001280d4260ca022d4350515c5368617265645c53657276696365735c436174616c6f675c536368656d615c76315c52657175657374e2022d4350515c5368617265645c50726f746f6275664d657461646174615c436174616c6f675c536368656d615c7631620670726f746f33"
), true);
static::$is_initialized = true;
}
}
But now I need to use alpine usage.
I've created Dockerfile with installing protobuf from github:
ENV PROTOBUF_VERSION 3.19.4
ENV PROTOBUF_URL https://github.com/google/protobuf/releases/download/v"$PROTOBUF_VERSION"/protobuf-cpp-"$PROTOBUF_VERSION".zip
RUN curl -L -o protobuf.zip "$PROTOBUF_URL"
RUN unzip protobuf.zip && cd protobuf-"$PROTOBUF_VERSION" && ./configure && make -j$(nproc) && make install
RUN cd .. && rm protobuf.zip
But after this when I generates new classes it generates metadata classes in some strange view:
<?php
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: api/schema/v1/request.proto
namespace MyApp\ProtobufMetadata\Schema\v1;
class Request
{
public static $is_initialized = false;
public static function initOnce() {
$pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
if (static::$is_initialized == true) {
return;
}
$pool->internalAddGeneratedFile(
'
�
#api/schema/v1/request.protoapi.schema.v1.request"
GetRequest
version (
B`�-MyApp\\Services\\Catalog\\Schema\\v1\\Request�-MyApp\\ProtobufMetadata\\Catalog\\Schema\\v1bproto3'
, true);
static::$is_initialized = true;
}
}
Does anyone hit with similar problem?
Is any way to fix lib installation or some compile to return pretty code with hex2bin usage?
compilation was made via commands with RoadRunner usage:
[ -f ./protoc-gen-php-grpc ] || ./rr get-protoc-binary
&& chmod +x ./protoc-gen-php-grpc
&& ./rr compile-proto-files"
Host system is MacOS
This was done on purpose, your Alpine is probably just running a more recent version of protoc.
Here is the PR which removed the hex2bin call: https://github.com/protocolbuffers/protobuf/pull/8006

Calling symfony/process inside Laravel controller always returns "<command> is not recognized"

I was trying to git pull by calling a spesific route.
I'm using symfony/process inside my controller like so:
public function pull()
{
$process = new Process(["git","pull"]);
$process->setWorkingDirectory(base_path());
$process->run(function ($type, $buffer) {
if (Process::ERR === $type) {
echo 'ERR > '.$buffer;
} else {
echo 'OUT > '.$buffer;
}
});
}
when I hit the route it returns:
ERR > 'git' is not recognized as an internal or external command, operable program or batch file.
then I tried to change the command to any other command like ls, npm install, rm, etc... and it is still returning the same error.
To everyone who comes here;
In order to run the system commands such as from shell or cmd(either on windows or linux or mac):
$process = Process::fromShellCommandline('inkscape --version');
$process->run(function ($type, $buffer) {
if (Process::ERR === $type) {
echo 'ERR > ' . $buffer;
} else {
echo 'OUT > ' . $buffer;
}
});
The output is:
OUT > Inkscape 1.0.2 (e86c870879, 2021-01-15) ERR > Pango version: 1.48.0
Don't forget to read the documentation:
https://symfony.com/doc/current/components/process.html#installation

Filling a form though headless browser

Due to integration restrictions, I'm forced to register people through a headless browser because the platform doesn't have an API.
I'm able to get this done on my symfony through selenium and PHP Unit. The callenge is that selenium has to be running all through which I don't believe is ideal.
This is my command:
xvfb-run --server-args="-screen 0, 1366x768x24" selenium-standalone start
I was hoping using Symfony process class, I could run the command as in below:
public function fillFormAndSubmit($inputs,$url,$form)
{
$process = new Process('/usr/bin/xvfb-run --server-args="-screen 0, 1366x768x24" selenium-standalone start');
//$process = new Process('echo Tecmint is a community of Linux Nerds > /tmp/xvfb-run.log 2> /tmp/xvfb.err');
$process->run();
usleep(3000000);
// executes after the command finishes
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
}
$this->webDriver->get($url);
$body = $this->webDriver->findElement(\WebDriverBy::cssSelector('body'))->sendKeys(array(\WebDriverKeys::CONTROL, 't'));
$form = $this->webDriver->findElement(\WebDriverBy::className($form));
foreach ($inputs as $input) {
if($input['type'] == 'select')
{
//PHPUnit_Extensions_Selenium2TestCase_Element_Select::fromElement($input['id'])->selectOptionByValue($input['value']);
//PHPUnit_Extensions_Selenium2TestCase_Element_Select::fromElement($this->byId('selectMenu'))->selectOptionByValue('t3');
//$this->select($this->byId($input['id']))->selectOptionByValue($input['value']);
$select = new \WebDriverSelect($form->findElement(\WebDriverBy::id($input['id'])));
$select->selectByValue($input['value']);
}
elseif($input['type'] == 'checkbox')
{
$form->findElement(\WebDriverBy::id($input['id']))->click();
}
else {
//echo $input['id'];
$form->findElement(\WebDriverBy::id($input['id']))->sendKeys($input['value']);
}
}
$form->submit();
echo shell_exec('pkill -f selenium-standalone');
//$this->waitForUserInput();
}
However, the shell command doesn't fire when I try to run the service on-demand. Is there a better way of doing this? If not, anyone with an idea of how to get it to work?

Yii2 How to use external PHP libraries

I want to use https://github.com/HelloFax/hellosign-php-sdk in Yii2 project so I followed following step
1 ) updated composer.json with "hellosign/hellosign-php-sdk": "3.*#dev" in require section
2) run composer update in CMD (I work with window 7)
so it downloaded required libraries (hellosign-php-sdk and libary) in vendor
3 ) include following code in controller file
$client = new HelloSign\Client('df754dd564e52fb2891a60eb2fea777b5320397********');
$response = $client->getSignatureRequest('f6197945000616b383d4752*****');
if ($response->isComplete()) {
echo 'All signers have signed this request.';
} else {
foreach ($response->getSignatures() as $signature) {
echo $signature->getStatusCode() . "\n";
}
}
Error
Unable to find 'app\controllers\HelloSign\Client' in file: C:\wamp\www\yii2hellosign/controllers/HelloSign/Client.php. Namespace missing?
How to solve this issue, any help ?
the library use psr-0 autoload, so you need to prepend classname with \ , like this:
$client = new \HelloSign\Client('...');

Symfony2 Process doest't give feedback in real-time

my idea is to start a minecraft server with the Symfony2 Process Class and want to give feedback to me in real time. So, like described in the Process cookbook part, I try the following code:
$process = new Process('sudo java -jar -Xms512M -Xmx1G ../server/minecraft_server.jar');
$process->setTimeout(null);
$process->run(function ($type, $buffer) {
if ('err' === $type) {
echo 'ERR > '.$buffer;
} else {
echo 'OUT > '.$buffer;
}
});
Because of some permission issues with the apache2 user i modified the sudoers file with this: www-data ALL = (myspecialUser) NOPASSWD: /usr/bin/java
so the www-data user can run the java command.
The server is starting in the background, but my problem is now that I'm not getting any real-time output. Only if I shutdown (or kill) the minecraft server process I get the output.
Any suggestions how to get a real-time output?
Instead of calling the run() method, you should try with the start() one:
$process = new Process('sudo java -jar -Xms512M -Xmx1G ../server/minecraft_server.jar');
$process->setTimeout(null);
$process->start(function ($type, $buffer));
echo 'OUT >' . $process->getOutput();
http://api.symfony.com/master/Symfony/Component/Process/Process.html#method_start
http://api.symfony.com/master/Symfony/Component/Process/Process.html#method_getOutput

Categories