Console Clear - Symfony Console Component - symfony

I'm writing a console app using Symfony 2 Console Component, and I want to run a console clear command before (or as) the first line of my app.
I have done some research and am struggling to find if this is possible.

I have been looking for similar functionality. There is nothing built-in to the symfony console that can clear the screen as far as I can tell, but you can still achieve the clear behavior by using the escape code for resetting the terminal like so:
$output->write(sprintf("\033\143"));
See the post "Clear the Ubuntu bash screen for real" and "What commands can I use to reset and clear my terminal?" for a more extensive explanation of the codes, and this symfony console pull request, where I got the code from, that attempted to emulate the clear functionality.

As the doc says, you can use something like this:
$kernel = $this->getContainer()->get('kernel');
$application = new Application($kernel);
$application->setAutoExit(false);
$input = new ArrayInput(array(
'command' => 'cache:clear',
));
// You can use NullOutput() if you don't need the output
$output = new BufferedOutput();
$application->run($input, $output);
// return the output, don't use if you used NullOutput()
$content = $output->fetch();
As your are using a command, your command must extends ContainerAwareCommand so you can access the container and your services.

Related

Using a Composer class in functions.php

I'm trying to add a shortcode to my Wordpress site to pull a piece of data from a Google spreadsheet and drop it into a page. To do this, I'm trying to use Sheetsu. The php libraries for Sheetsu are managed through Composer.
I've got a working piece of standalone code, but when I drop it in functions.php, like this...
function do_sheetsu() {
require('vendor/autoload.php');
use Sheetsu\Sheetsu;
$sheetsu = new Sheetsu(['sheetId' => '8b297aa81110']);
$response = $sheetsu->search(['id' => '2.05.1']);
$collection = $response->getCollection();
echo $collection->get(0)->answer;
}
add_shortcode('sheetsu','do_sheetsu');
...it blanks my site. If I comment out the use Sheetsu\Sheetsu; line, my site comes back, but I get no output, and the error "PHP Fatal error: Class 'Sheetsu' not found" which I suppose makes perfectly good sense.
I know enough php to be able to break things, apparently, and my knowledge of Composer comes mostly from messing around with Flarum a little bit.
I'm sure I'm missing something obvious here, I'm guessing involving namespace declarations or something, but I can't put the pieces together.
I'm looking suspiciously at my composer.json file, as well—something doesn't seem right, but I'm not sure what to fix.
For the record, my composer.json, composer.lock, and vendor folder are in my theme folder with functions.php. My composer.json file looks like this:
{
"require": {
"emilianozublena/sheetsu-php": "^0.0.6"
}
}
and I'm not sure it should.
But what's more troubling is finding a way around that use Sheetsu\Sheetsu line that seems to totally break Wordpress...
Thanks for any help!
I assume here you have installed the package using command line running composer install or composer require emilianozublena/sheetsu-php.
You cannot use the use php keyword inside function. The use keyword must be declared in the outermost scope of a file (the global scope). Refer to this answer for more detail here
So, in this condition you can chain the namespace while instantiating your class. In our case new Sheetsu(['sheetId' => '8b297aa81110']) becomes new \Sheetsu\Sheetsu(['sheetId' => '8b297aa81110']);
Try this code below
function do_sheetsu() {
require('vendor/autoload.php');
$sheetsu = new \Sheetsu\Sheetsu(['sheetId' => '8b297aa81110']);
$response = $sheetsu->search(['id' => '2.05.1']);
$collection = $response->getCollection();
echo $collection->get(0)->answer;
}
add_shortcode('sheetsu','do_sheetsu');

How to make symfony display exceptions in functional testing with phpunit

When I run unit tests with PhpUnit in console all exceptions are display immediately there. However when I moved to functional testing I cannot see exceptions which occur.
First I tried symfony WebTestCase as it was said here. So I called $client with needed parameters and I have a response. But it took time to me to understand that this behaviour is just like I manually open a page I want to test. And a response from $client->request contains text (html). Yes errors are show there but there are pretty much html and it is really hard to find the exception. Yes, I can use $crawler->filter('.text-exception')->first()->text() but I want so that exception was visible like in unit test. When I tested commands exceptions are shown by PhpUnit as well as normal.
I tried to copy code from web/app_dev.php to test case. But it is the same. I have only html response.
So how can I make it so that PhpUnit display exceptions in functional testing like in unit testing?
You can use profiler to do it:
$client->enableProfiler();
$client->request('GET', '/');
$profile = $client->getProfile();
$exceptionProfile = $profile->getCollector('exception');
if ($exceptionProfile->hasException()) {
$message = sprintf(
"No exception was expected but got '%s' with message '%s'. Trace:\n%s",
get_class($exceptionProfile->getException()),
$exceptionProfile->getMessage(),
$exceptionProfile->getException()->getTraceAsString()
);
throw new AssertionFailedError($message);
}

Symfony: how to customize output of available commands?

We are building a console application using symfony/console (great library by the way). The available commands show up as such:
Available commands:
check-deps Get a report of resolved and missing (if any) dependencies.
gen-docs Rebuild the API / code documentation
help Displays help for a command
list Lists commands
restart Restart the Nginx and PHP-FPM processes.
show-changes Show all local changes to the source code since the last push.
test Run the unit tests
test-coverage Run the unit tests and include a coverage report.
The name of the command shows up in green and the description shows up in white.
Currently, Available commands is the only section. Is there a simple way using OOP to create multiple sections for commands?
Alternatively, is there a way to change the green color for the command label?
You can create a new section by using colon notation.
$this
->setName('newSection:greet') //<--- This line does the trick
->setDescription('Greet someone')
->addArgument(
'name',
InputArgument::OPTIONAL,
'Who do you want to greet?'
)
->addOption(
'yell',
null,
InputOption::VALUE_NONE,
'If set, the task will yell in uppercase letters'
);
However in that case you need to run your command with new section name added as namespace,
> php app.php newSection:greet Avindra.
If you name your section with a whitespace like "New Section" you need to call your command like,
> php app.php "New Section:greet" Avindra.
And this is how you can change the color of info annotation of the application itself.
#!/usr/bin/env php
<?php
require __DIR__.'/vendor/autoload.php';
use Command\GreetCommand;
use Command\HelloCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
$application = new Application();
$application->add(new GreetCommand());
$application->add(new HelloCommand());
//Create a new OutputFormatter
$formatter = new OutputFormatter();
//Change info annotation color by blue
$formatter->setStyle('info', new OutputFormatterStyle('blue'));
//Construct output interface with new formatter
$output = new ConsoleOutput(OutputInterface::VERBOSITY_NORMAL, null, $formatter);
//Run your application with your new output interface
$application->run(null, $output);
You can check the related source code for more options here;
https://github.com/symfony/Console/blob/5f241906889f0a3e7b1854b42e7c92a0ea8516ce/Formatter/OutputFormatter.php#L51
https://github.com/symfony/Console/blob/b6b351d326e2fb2fe673a808630f938c2881a473/Formatter/OutputFormatterStyle.php#L21
Hope it helps.

Twig's dump function returns a blank screen

I am using Twig's dump function in Symfony2. I have configured Symfony according to its instructions.
I have a page variable, and an orders array. dump works on page, but not orders. When I call it on orders, I get a white screen - no php errors or anything. I have no idea how to debug this.
Any ideas?
A little explanation
A white (blank) screen in this case means the PHP fatal error: Allowed memory size exhausted. During my investigation, I found that twig uses thevar_dump function while I have VarDumper component installed.
I think its made to work along in case the VarDumper component is not installed, but twig's dump() function covered in symfony's VarDumper component documentation like a complex solution, that's strange.
So, using VarDumper's dump() function instead of native var_dump() solves the memory problem (because VarDumper limits result dump collection to adequate amount). Also VarDumper's dump() give more convenient results - you can click on tree leafs to show/hide its content.
What exactly do you need to do
Install VarDumper component if not installed
Go to file: vendor/twig/twig/lib/Twig/Extension/Debug.php
Find twig_var_dump function
Replace all var_dump() calls to dump()
Delete/comment ob_start() + ob_get_clean() construction (which is needed
if you use var_dump() as it echoes data immideately, but dump() acting
more intelligent)
OR
copy + replace the entire function using this:
function twig_var_dump(Twig_Environment $env, $context)
{
if (!$env->isDebug()) {
return;
}
$count = func_num_args();
if (2 === $count) {
$vars = array();
foreach ($context as $key => $value) {
if (!$value instanceof Twig_Template) {
$vars[$key] = $value;
}
}
dump($vars);
} else {
for ($i = 2; $i < $count; $i++) {
dump(func_get_arg($i));
}
}
}
PS: Question's asked in 2013, but I hope it helps because I had this problem now.
My context:
"symfony/symfony": "2.5.*"
"symfony/var-dumper": "~2.6"
I had same issue, increasing the memory_limit up to 1Gb didn't help.
In my case I want to call the
{{ dump() }}
with no parameters (to see all the available vars in the context of the current template. In my case the following helped: https://stackoverflow.com/a/11500141/2166261 , though the memory_limit issue still persists)
Most likely you are hitting your PHP memory limit. Try increasing it in the php.ini
There is probably no single answer to this problem, as a range of things could cause it. As other people have suggested, increasing the memory limit for PHP may help. In my case this did not help, however, I was able to resolve the issue by installing xdebug.
So far, it seems then that a checklist for resolving this issue would look something like this:
Ensure that the latest version of xdebug is installed
If that doesn't resolve it, try increasing PHP memory limit
The Arkemlar answer works fine.
BUT
after that the twig dump() caused a RuntimeException in the functional test with phpunit in my case.

How do I decide between theme('node', $node) and drupal_render($node->content) for programmatic $node output

Given a $node, I'm trying to decide between the following two ways of outputting that $node.
either
$output = theme('node', $node);
or
node_build_content($node);
$output = drupal_render($node->content);
They both seem to give similar results, but is there something I should consider before I choose one way over the other?
Your output is similar if there are no other modules and themes altering the output via the theme layer.
But! If you bypass the theme layer, you'll probably start experiencing unexpected behaviour when you install modules or themes and change config settings that use the theme layer to alter the node's output.
In short, by bypassing the theme layer, you're building error into your application. These error are likely to occur after you hand your application over to someone (a client perhaps) who starts changing settings in admin/
See the decorator pattern if you're interested. Drupal uses this extensively.
http://en.wikipedia.org/wiki/Decorator_pattern
Well, sortof.
What you really want is
$output = node_view($node);
if you just call node_build_content, and then call theme('node', $node), hook_nodeapi('alter') is never called, nor is hook_link().
So if any module is expecting to alter the built node, it wont get a chance to, and if there is supposed to be links on it they wont be there either.
Additionally you can call $output = node_view($node, FALSE, FALSE, FALSE); which gives you the node without the links.
See the documentation for node_view().
If you look into the source of drupal_render(), it actually calls theme() itself as well (provided a #theme override is provided).
In Drupal 7, you should do :
$elements = node_view($node, 'teaser');
$rendered_node = drupal_render($elements);
The solution that worked here was a combination of both of these techniques. Just using theme('node', $node); doesn't seem to work without the help of node_build_content($node);.
Here is the result of an example only using theme('node', $node);.
But if we first do node_build_content($node); prior to handling the $node to the theme function, you can see that the form button is also rendered.
Therefore, the real solution is:
node_build_content($node);
$output = theme('node', $node);
First is recommended, as it is passed via the theme layer.

Resources