Write output to console from helper class - php

I have a console command that runs a helper class and I want to write output with $this->info() to the console from the helper class.
My code looks like this:
App/Http/Console/Commands/SomeCommand.php
function handle(Helper $helper)
{
return $helper->somefunction();
}
App/Http/SomeHelper.php
function somefunction()
{
//some code
$this->info('send to console');
}
Is there any way to write the output to console from the helper?

I finally figured this out (works in Laravel 5.6)
In the handle() function of your SomeCommand class, add $this->myHelper->setConsoleOutput($this->getOutput());.
In your helper class, add:
/**
*
* #var \Symfony\Component\Console\Style\OutputStyle
*/
protected $consoleOutput;
/**
*
* #param \Symfony\Component\Console\Style\OutputStyle $consoleOutput
* #return $this
*/
public function setConsoleOutput($consoleOutput) {
$this->consoleOutput = $consoleOutput;
return $this;
}
/**
*
* #param string $text
* #return $this
*/
public function writeToOuput($text) {
if ($this->consoleOutput) {
$this->consoleOutput->writeln($text);
}
return $this;
}
/**
*
* #param string $text
* #return $this
*/
public function writeErrorToOuput($text) {
if ($this->consoleOutput) {
$style = new \Symfony\Component\Console\Formatter\OutputFormatterStyle('white', 'red', ['bold']); //white text on red background
$this->consoleOutput->getFormatter()->setStyle('error', $style);
$this->consoleOutput->writeln('<error>' . $text . '</error>');
}
return $this;
}
Then, anywhere else in your helper class, you can use:
$this->writeToOuput('Here is a string that I want to show in the console.');

You need to write $this->info('send to console'); this in SomeCommand.php file.For writing output follow this https://laravel.com/docs/5.2/artisan#writing-output

I have not tried, but maybe: $this->line("sent to console');

Related

How to use if in stubs in laravel?

I have an artisan command which gets some options, one of these options is --type=, like below:
protected $signature = 'make:procedure {name} {--type=}';
--type= contains the kind of difference, I want to check this option in the stub because each type has a different namespace which should be used in the stub.
for example, this is my stub:
<?php
namespace DummyNamespace;
class DummyClass
{
//
}
How can I do this, (of course this is an example, I just trying to explain my problem):
<?php
namespace DummyNamespace;
if ($type === 'one') {
echo 'use App\Some\Namespace\One'
}
class DummyClass
{
//
}
It would be highly appreciated if anyone can advise me!😊
your Custom command should derive from GeneratorCommand then you can use abstract Method getStub()
Your Stub File
namespace DummyNamespace;
/**
* Class DummyClass.
*/
class DummyClass
{
}
In Your Command File, you just need to use below code
/**
* Get the stub file for the generator.
*
* #return string
*/
protected function getStub()
{
return app_path('file/path/test.stub');
}
For Explanation Only
In GeneratorCommand class
/**
* Get the stub file for the generator.
*
* #return string
*/
abstract protected function getStub();
/**
* Build the class with the given name.
*
* #param string $name
* #return string
*
* #throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
protected function buildClass($name)
{
$stub = $this->files->get($this->getStub());
return $this->replaceNamespace($stub, $name)->replaceClass($stub, $name);
}
A very simple way to generate files from stub.
In your stub file
namespace {{namespace}};
/**
* Class {{name}}.
*/
class {{name}}
{
}
Somewhere in your command
protected function getStub()
{
return file_get_contents(resource_path('stubs/dummy.stub'));
}
protected function generate($namespace, $name)
{
$template = str_replace(
['{{namespace}}', '{{name}}'],
[$namespace, $name],
$this->getStub()
);
file_put_contents(app_path("Dummies/$name.php"), $template);
}

Does Psalm supprt #param-out for "this"?

Is it possible to manipulate phantom types in Psalm using #param-out for this or self? Example:
/**
* #template T
*/
class Foo
{
/**
* #param T $t
*/
public function __construct($t)
{
$this->t = $t;
}
/**
* WRONG:
* #param-out Test<S> $this
*/
public function test()
{
// Also this doesn't work:
$this->t = new S();
}
}
A use-case for this could be e.g. a file class with phantom type set to Open or Closed, and calling $file->open(); changes T to Open.
No. There's a pull request about it that might or might not be merged, using #param-self-out.

How inform PhpStorm about method position used in DependencyInjection way, which it "thinks" that doesn't exist?

Is there any option to inform PhpStorm that method which it says that not exist, is beyond his scope and is defined somewhere else ?
In simpler words:
I have method execution:
Db::transactional($this)->transactionalUpdate($result);
I have got method definition also:
public function transactionalUpdate(ImportantObjectButNotMuch $baconWithButter)
{
echo 'Do a lot of tricks...';
}
Unfortunately PhpStorm doesn't know that execution : ->transactionalUpdate($result); should run public function transactionalUpdate.
Is there any option to write PhpDoc or some other tag to inform it that in case of name refactorization it should change the original function name too ?
P.S. My class structure looks like this:
class Db
{
public static function transactional($object)
{
return TransactionalProxy::newInstance($object); //3. It returns ApiObject object
}
}
class ApiObject
{
public function update_record()
{
//1. I am starting from there
$result = new ImportantObjectButNotMuch();
Db::transactional($this)->transactionalUpdate($result); //2. Next i am passing $this to Db class, to transactional method //4. It should run below transactionalUpdate method
}
public function transactionalUpdate(ImportantObjectButNotMuch $baconWithButter)
{
echo 'Do a lot of tricks...'; //5. It ends there, it is working but PhpStorm doesn't see it
}
}
EDIT AFTER ANSWER:
#Nukeface and #Dmitry caused me to come up with the answer on my Question:
Lets see again into my files structure:
class Db
{
public static function transactional($object)
{
return TransactionalProxy::newInstance($object); //3. It returns ApiObject object
}
}
class ApiObject
{
public function update_record()
{
//1. I am starting from there
$result = new ImportantObjectButNotMuch();
//EDIT//Db::transactional($this)->transactionalUpdate($result); //2. Next i am passing $this to Db class, to transactional method //4. It should run below transactionalUpdate method
/** #var self $thisObject */
//Line above informs PhpStorm that $thisObject is ApiObject indeed
$thisObject = Db::transactional($this)
$thisObject->transactionalUpdate($result);
}
public function transactionalUpdate(ImportantObjectButNotMuch $baconWithButter)
{
echo 'Do a lot of tricks...'; //5. It ends there, it is working but PhpStorm doesn't see it
}
}
You should make use of Typehints. Updated your code below:
/**
* Class Db
* #package Namespace\To\Db
*/
class Db
{
/**
* #param $object
* #return ApiObject (per your line comment)
*/
public static function transactional($object)
{
return TransactionalProxy::newInstance($object); //3. It returns ApiObject object
}
}
/**
* Class ApiObject
* #package Namespace\To\ApiObject
*/
class ApiObject
{
/**
* #return void (I see no "return" statement)
*/
public function update_record()
{
//1. I am starting from there
$result = new ImportantObjectButNotMuch();
Db::transactional($this)->transactionalUpdate($result); //2. Next i am passing $this to Db class, to transactional method //4. It should run below transactionalUpdate method
}
/**
* #param ImportantObjectButNotMuch $baconWithButter
* #return void
*/
public function transactionalUpdate(ImportantObjectButNotMuch $baconWithButter)
{
echo 'Do a lot of tricks...'; //5. It ends there, it is working but PhpStorm doesn't see it
}
}
You can quickly create basic docblocks and typehints by typing /** then pressing either "enter" or "space". Enter if you want a docblock and space if you want a typehint.
Examples of own code below:
/**
* Class AbstractEventHandler
* #package Hzw\Mvc\Event
*/
abstract class AbstractEventHandler implements EventManagerAwareInterface
{
/**
* #var EventManagerInterface
*/
protected $events;
/**
* #var EntityManager|ObjectManager
*/
protected $entityManager;
/**
* AbstractEvent constructor.
* #param ObjectManager $entityManager
*/
public function __construct(ObjectManager $entityManager)
{
$this->setEntityManager($entityManager);
}
/**
* #param EventManagerInterface $events
*/
public function setEventManager(EventManagerInterface $events)
{
$events->setIdentifiers([
__CLASS__,
get_class($this)
]);
$this->events = $events;
}
/**
* #return EventManagerInterface
*/
public function getEventManager()
{
if (!$this->events) {
$this->setEventManager(new EventManager());
}
return $this->events;
}
/**
* #return ObjectManager|EntityManager
*/
public function getEntityManager()
{
return $this->entityManager;
}
/**
* #param ObjectManager|EntityManager $entityManager
* #return AbstractEventHandler
*/
public function setEntityManager($entityManager)
{
$this->entityManager = $entityManager;
return $this;
}
}
In the above example, PhpStorm knows what every function requires and returns. It knows the types and as some "return $this" it knows about the possibility to chain functions.
As an addition, the above code example uses only "docblocks". Below some "inline typehints" from within a function. Especially useful when it's not going to be immediately clear what is going to be returned. That way, again, PhpStorm knows from where to get functions, options, etc. to show you.
/** #var AbstractForm $form */
$form = $this->getFormElementManager()->get($formName, (is_null($formOptions) ? [] : $formOptions));
/** #var Request $request */
$request = $this->getRequest();
As a final hint. If you create a bunch of properties for a class, such as in my example protected $events or protected $entityManager, you can also generate the getters & setters. If your properties contain the docblocks, it will also generate the docblocks for you on these functions.
E.g. the property below
/**
* #var EntityManager|ObjectManager
*/
protected $entityManager;
When using "Alt + Insert" you get a menu at cursor location. Choose "Getters/Setters". In the pop-up, select "entityManager" and check the box at the bottom for "fluent setters". Then the code below is generated for you:
/**
* #return ObjectManager|EntityManager
*/
public function getEntityManager()
{
return $this->entityManager;
}
/**
* #param ObjectManager|EntityManager $entityManager
* #return AbstractEventHandler
*/
public function setEntityManager($entityManager)
{
$this->entityManager = $entityManager;
return $this;
}
The closes thing you can do to what you want to do is to use #return with multiple types.
/**
* #param $object
* #return ApiObject|AnotherApiObject|OneMoreApiObject
*/
public static function transactional($object)
{
return TransactionalProxy::newInstance($object);
}

PHPUnit Mockupbuilder passing return value correctly

I found some strange behavior with mockup builder, can someone explain to me why this happen?
here is my test code:
class PlaceTest extends \PHPUnit_Framework_TestCase
{
const API_KEY = 'test-api';
public function testConstruct()
{
$google = $this->getMockBuilder('GusDeCooL\GooglePhp\Google')
->setConstructorArgs(array(self::API_KEY))
->setMethods(array('getKey'))
->getMock();
$google->expects($this->any())
->method('getKey')
->will($this->returnValue(self::API_KEY));
/* #var $google \GusDeCooL\GooglePhp\Google */
$place = new Place($google);
$this->assertInstanceOf('GusDeCooL\GooglePhp\Component\Place\Place', $place);
$this->assertInstanceOf('GusDeCooL\GooglePhp\Google', $place->getParent());
$this->assertEquals(self::API_KEY, $place->getKey());
return $place;
}
/**
* #param Place $place
*
* #depends testConstruct
*/
public function testGetKey(Place $place)
{
$this->assertInstanceOf('GusDeCooL\GooglePhp\Google', $place->getParent());
$this->assertEquals(self::API_KEY, $place->getKey());
}
}
And here is the code of actual class
<?php
namespace GusDeCooL\GooglePhp\Component\Place;
use GusDeCooL\GooglePhp\Component\ChildInterface;
use GusDeCooL\GooglePhp\Google;
use GusDeCooL\GooglePhp\Place\Nearby;
class Place implements ChildInterface
{
/**
* #var Google
*/
private $parent;
/**
* #var Nearby
*/
private $nearby;
public function __construct(Google $parent)
{
$this->setParent($parent);
}
/**
* API Key
* #return string
*/
public function getKey()
{
return $this->getParent()->getKey();
}
}
While running the test, the PlaceTest::testConstruct() while doing $place->getKey() it pass the test but it errors in PlaceTest::testGetKey()
How is that happen?
It seems this is the limitation of mockup builder.
http://phpunit.de/manual/3.7/en/test-doubles.html
we can't pass mockup object into another test scope.
Please leave a comment if you found another reason.

Zend and Smarty 3 integration using

I am trying to change the layout content in my controller, which only seems to overwrite it, only append.
I have built a CMS using Zend and Smarty. I have one main layout with, which displays the content for each page:
{$this->layout()->content}
Although when I try to overwrite the 'content' in the controller with a new content area this causes both the index/index.tpl and contact/contact.tpl to be displayed:
$this->view->content = $this->view->display('contact/contact.tpl');
I know I could manually assign the content to a view smarty variable, although I would like to reduce the assigns in smarty and use Zend.
In my application.ini
smarty.caching = 1
smarty.cache_lifetime = 14400
smarty.template_dir = PATH "/templates/default/"
smarty.compile_dir = PATH "/tmp/smarty_compile/"
smarty.plugins_dir = APPLICATION_PATH "/plugins/smarty/"
smarty.config_dir = ""
smarty.cache_dir = PATH "/tmp/smarty_cache/"
smarty.left_delimiter = "{"
smarty.right_delimiter = "}"
In my bootstrap.php
protected function _initView()
{
$view = new Web_View_Smarty($this->getOption('smarty'));
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
$viewRenderer->setViewSuffix('tpl');
$viewRenderer->setView($view);
$this->bootstrap('layout');
$layout = Zend_Layout::getMvcInstance();
$layout->setViewSuffix('tpl');
return $view;
}
In my Smarty.php
<?php
/**
* Smarty template engine integration into Zend Framework
*/
class Web_View_Smarty extends Zend_View_Abstract
{
/**
* Instance of Smarty
* #var Smarty
*/
protected $_smarty = null;
/**
* Template explicitly set to render in this view
* #var string
*/
protected $_customTemplate = '';
/**
* Smarty config
* #var array
*/
private $_config = null;
/**
* Class definition and constructor
*
* Let's start with the class definition and the constructor part. My class Travello_View_Smarty is extending the Zend_View_Abstract class. In the constructor the parent constructor from Zend_View_Abstract is called first. After that a Smarty object is instantiated, configured and stored in a private attribute.
* Please note that I use a configuration object from the object store to get the configuration data for Smarty.
*
* #param array $smartyConfig
* #param array $config
*/
public function __construct($smartyConfig, $config = array())
{
$this->_config = $smartyConfig;
parent::__construct($config);
$this->_loadSmarty();
}
/**
* Return the template engine object
*
* #return Smarty
*/
public function getEngine()
{
return $this->_smarty;
}
/**
* Implement _run() method
*
* The method _run() is the only method that needs to be implemented in any subclass of Zend_View_Abstract. It is called automatically within the render() method. My implementation just uses the display() method from Smarty to generate and output the template.
*
* #param string $template
*/
protected function _run()
{
$file = func_num_args() > 0 && file_exists(func_get_arg(0)) ? func_get_arg(0) : '';
if ($this->_customTemplate || $file) {
$template = $this->_customTemplate;
if (!$template) {
$template = $file;
}
$this->_smarty->display($template);
} else {
throw new Zend_View_Exception('Cannot render view without any template being assigned or file does not exist');
}
}
/**
* Overwrite assign() method
*
* The next part is an overwrite of the assign() method from Zend_View_Abstract, which works in a similar way. The big difference is that the values are assigned to the Smarty object and not to the $this->_vars variables array of Zend_View_Abstract.
*
* #param string|array $var
* #return Ext_View_Smarty
*/
public function assign($var, $value = null)
{
if (is_string($var)) {
$this->_smarty->assign($var, $value);
} elseif (is_array($var)) {
foreach ($var as $key => $value) {
$this->assign($key, $value);
}
} else {
throw new Zend_View_Exception('assign() expects a string or array, got '.gettype($var));
}
return $this;
}
public function display($template){
$this->clearVars();
$this->_smarty->display($template);
return $this;
}
/**
* Overwrite escape() method
*
* The next part is an overwrite of the escape() method from Zend_View_Abstract. It works both for string and array values and also uses the escape() method from the Zend_View_Abstract. The advantage of this is that I don't have to care about each value of an array to get properly escaped.
*
* #param mixed $var
* #return mixed
*/
public function escape($var)
{
if (is_string($var)) {
return parent::escape($var);
} elseif (is_array($var)) {
foreach ($var as $key => $val) {
$var[$key] = $this->escape($val);
}
}
return $var;
}
/**
* Print the output
*
* The next method output() is a wrapper on the render() method from Zend_View_Abstract. It just sets some headers before printing the output.
*
* #param <type> $name
*/
public function output($name)
{
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Cache-Control: no-cache");
header("Pragma: no-cache");
header("Cache-Control: post-check=0, pre-check=0", false);
print parent::render($name);
}
/**
* Use Smarty caching
*
* The last two methods were created to simply integrate the Smarty caching mechanism in the View class. With the first one you can check for cached template and with the second one you can set the caching on or of.
*
* #param string $template
* #return bool
*/
public function isCached($template)
{
return $this->_smarty->is_cached($template);
}
/**
* Enable/disable caching
*
* #param bool $caching
* #return Ext_View_Smarty
*/
public function setCaching($caching)
{
$this->_smarty->caching = $caching;
return $this;
}
/**
* Template getter (return file path)
* #return string
*/
public function getTemplate()
{
return $this->_customTemplate;
}
/**
* Template filename setter
* #param string
* #return Ext_View_Smarty
*/
public function setTemplate($tpl)
{
$this->_customTemplate = $tpl;
return $this;
}
/**
* Magic setter for Zend_View compatibility. Performs assign()
*
* #param string $key
* #param mixed $val
*/
public function __set($key, $val)
{
$this->assign($key, $val);
}
/**
* Magic getter for Zend_View compatibility. Retrieves template var
*
* #param string $key
* #return mixed
*/
public function __get($key)
{
return $this->_smarty->getTemplateVars($key);
}
/**
* Magic getter for Zend_View compatibility. Removes template var
*
* #see View/Zend_View_Abstract::__unset()
* #param string $key
*/
public function __unset($key)
{
$this->_smarty->clearAssign($key);
}
/**
* Allows testing with empty() and isset() to work
* Zend_View compatibility. Checks template var for existance
*
* #param string $key
* #return boolean
*/
public function __isset($key)
{
return (null !== $this->_smarty->getTemplateVars($key));
}
/**
* Zend_View compatibility. Retrieves all template vars
*
* #see Zend_View_Abstract::getVars()
* #return array
*/
public function getVars()
{
return $this->_smarty->getTemplateVars();
}
/**
* Updates Smarty's template_dir field with new value
*
* #param string $dir
* #return Ext_View_Smarty
*/
public function setTemplateDir($dir)
{
$this->_smarty->setTemplateDir($dir);
return $this;
}
/**
* Adds another Smarty template_dir to scan for templates
*
* #param string $dir
* #return Ext_View_Smarty
*/
public function addTemplateDir($dir)
{
$this->_smarty->addTemplateDir($dir);
return $this;
}
/**
* Adds another Smarty plugin directory to scan for plugins
*
* #param string $dir
* #return Ext_View_Smarty
*/
public function addPluginDir($dir)
{
$this->_smarty->addPluginsDir($dir);
return $this;
}
/**
* Zend_View compatibility. Removes all template vars
*
* #see View/Zend_View_Abstract::clearVars()
* #return Ext_View_Smarty
*/
public function clearVars()
{
$this->_smarty->clearAllAssign();
$this->assign('this', $this);
return $this;
}
/**
* Zend_View compatibility. Add the templates dir
*
* #see View/Zend_View_Abstract::addBasePath()
* #return Ext_View_Smarty
*/
public function addBasePath($path, $classPrefix = 'Zend_View')
{
parent::addBasePath($path, $classPrefix);
$this->addScriptPath(PATH . '/templates/default');
$this->addTemplateDir(PATH . '/templates/shared');
return $this;
}
/**
* Zend_View compatibility. Set the templates dir instead of scripts
*
* #see View/Zend_View_Abstract::setBasePath()
* #return Ext_View_Smarty
*/
public function setBasePath($path, $classPrefix = 'Zend_View')
{
parent::setBasePath($path, $classPrefix);
$this->setScriptPath(PATH . '/templates/default');
$this->addTemplateDir(PATH . '/templates/shared');
return $this;
}
/**
* Magic clone method, on clone create diferent smarty object
*/
public function __clone() {
$this->_loadSmarty();
}
/**
* Initializes the smarty and populates config params
*
* #throws Zend_View_Exception
* #return void
*/
private function _loadSmarty()
{
if (!class_exists('Smarty', true)) {
require_once 'Smarty/Smarty.class.php';
}
$this->_smarty = new Smarty();
if ($this->_config === null) {
throw new Zend_View_Exception("Could not locate Smarty config - node 'smarty' not found");
}
$this->_smarty->caching = $this->_config['caching'];
$this->_smarty->cache_lifetime = $this->_config['cache_lifetime'];
$this->_smarty->template_dir = $this->_config['template_dir'];
$this->_smarty->compile_dir = $this->_config['compile_dir'];
$this->_smarty->config_dir = $this->_config['config_dir'];
$this->_smarty->plugins_dir = $this->_config['plugins_dir'];
$this->_smarty->cache_dir = $this->_config['cache_dir'];
$this->_smarty->left_delimiter = $this->_config['left_delimiter'];
$this->_smarty->right_delimiter = $this->_config['right_delimiter'];
$this->assign('this', $this);
}
}
There is Smarty implementation in Zend Documentation.
Smarty is bad, any template engine is bad and slowing down your application.
Use zend native views.
And remember that PHP is was invented to be a template engine.
http://framework.zend.com/manual/1.11/en/zend.view.scripts.html
When in your template, you write
{$this->layout()->content}
This is the content of the layout helper, that will render the view associated to each action.
When, in you controller, you write
$this->view->content = $this->view->display('contact/contact.tpl');
You assign a variable to your view, that can be display, using
{$content}
in your smarty template.
I think you have some confusion in your way of sorting this out. Have a look at
http://framework.zend.com/manual/1.12/en/zend.layout.quickstart.html
Anyway, your question is old and you already have selected an answer as correct, which was not really an answer by the way, but I couldn't pass by and say nothing. Using Smarty with Zend is great, Smarty is faster and compiling/caching have better fine tuning than Zend and the integration between both is neat (thanks to dependency injection). You can have the power of both libraries in one application, so go for it.

Categories