Attempted to call function "yaml_parse_file" from the global namespace - php

I am new to Symfony, Facing problem while trying to run the cron job. I am really clueless, whats wrong here. It seems that I am trying to access some functions present in app/config/functions.php from the global namespace, But I can't figure out which namespace is it. Following is my code.
<?php
namespace App\Command;
use App\Services\Upcontent\Upcontent;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class UpcontentRefreshCommand extends Command
{
protected static $defaultName = 'app:upcontent-refresh';
private $upcontent;
public function __construct(Upcontent $upcontent)
{
$this->upcontent = $upcontent;
parent::__construct();
}
protected function configure()
{
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln([
'',
'=================',
'Upcontent Refresh',
'=================',
'',
]);
$output->writeln('Clearing Cache...');
clear_cache();
$output->writeln('Cache Cleared');
$output->writeln('Refreshing Sports Topic...');
$output->writeln('Loading, be patient...');
$sports = $this->upcontent->getTopic('########');
$output->writeln([
'',
'=====================',
'End Upcontent Refresh',
'=====================',
'',
]);
}
}
?>
The error occur when I run, php72 bin/console app:upcontent-refresh Please help. Thanks in advance.

You will probably have to update the "autoload"-section to make sure that your custom functions.php is loaded.
{
"autoload": {
"psr-4" {
"App\\": "src/"
},
"files": ["app/config/functions.php"]
}
}
You might also want to refactor that file to instead move the functions into some kind of service-class, e.g. like this:
# src/Yaml/Parser.php
<?php
namespace App\Yaml;
class Parser
{
public function parseFile(string $fileName)
{
// The logic from your yaml_parse_file() inside your functions.php
}
}
Then in your command (or wherever you need your custom yaml parsing) inject the service:
use App\Yaml\Parser;
class MyService
{
private $yamlParser;
public function __construct(Parser $yamlParser)
{
$this->yamlParser = $yamlParser;
}
// ...
public function something()
{
$this->yamlParser->parseFile($filename);
}
}
Since Symfony provides a Yaml-component, you might even want to use that instead.

Related

Testing Symfony custom maker (maker bundle)

I'm trying to make a custom maker with the Symfony make bundle.
The maker command looks like this:
<?php
namespace App\Maker;
use Doctrine\Common\Annotations\Annotation;
use Symfony\Bundle\MakerBundle\ConsoleStyle;
use Symfony\Bundle\MakerBundle\DependencyBuilder;
use Symfony\Bundle\MakerBundle\Generator;
use Symfony\Bundle\MakerBundle\InputConfiguration;
use Symfony\Bundle\MakerBundle\Maker\AbstractMaker;
use Symfony\Bundle\MakerBundle\Str;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
final class MakeCustomEntity extends AbstractMaker
{
public static function getCommandName(): string
{
return 'make:custom-entity';
}
public static function getCommandDescription(): string
{
return 'Creates a new entity';
}
public function configureCommand(Command $command, InputConfiguration $inputConf)
{
$command
->addArgument('entity-class', InputArgument::OPTIONAL, sprintf('Choose a name for your entity class (e.g. <fg=yellow>%s</>)', Str::asClassName(Str::getRandomTerm())));
}
public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator)
{
}
public function configureDependencies(DependencyBuilder $dependencies)
{
$dependencies->addClassDependency(
Annotation::class,
'doctrine/annotations'
);
}
}
So far so good, the custom maker shows up when listing all commands.
However I would like to write a test for this maker (inspired from the tests I have found on the bundles github):
<?php
namespace Tests\Maker;
use App\Maker\MakeCustomEntity;
use Symfony\Bundle\MakerBundle\Test\MakerTestCase;
use Symfony\Bundle\MakerBundle\Test\MakerTestDetails;
class MakeCustomEntityTest extends MakerTestCase
{
public function getTestDetails()
{
yield 'entity_full_custom_namespace' => [
MakerTestDetails::createTest(
$this->getMakerInstance(MakeCustomEntity::class),
[
// entity class name
'\App\Domain\Entity\Test\Test',
]
)
->assert(function (string $output, string $directory) {
$this->assertStringContainsString('created: src/Domain/Entity/Test/Test.php', $output);
}),
];
}
}
When I try to run this test I get the following warning and test doesn't fail even though it should:
The data provider specified for Tests\Maker\MakeCustomEntityTest::testExecute is invalid.
You have requested a non-existent service "maker.maker.make_custom_entity". Did you mean one of these: "maker.maker.make_authenticator",...
Is this the correct way to testing custom makers? What should I do to avoid this?

Why isn't the event listener firing off in Lumen?

So I have event and listener classes defined as well as having them registered in the $listen array in EventServiceProvider.php. Here is the code:
use App\Events\EpisodeCreated;
use App\Listeners\NewEpisodeListener;
use Event;
class EventServiceProvider extends ServiceProvider {
protected $listen = [
EpisodeCreated::class => [
NewEpisodeListener::class
]
];
}
and then in EventServiceProvider's boot method I have the following:
public function boot() {
Episode::created(function($episode) {
Event::fire(new EpisodeCreated($episode));
});
}
here is the EpisodeCreated event class:
namespace App\Events;
use App\Models\Episode;
class EpisodeCreated extends Event {
public $episode;
public function __construct(Episode $episode) {
$this->episode = $episode;
}
}
and finally the listener:
namespace App\Listeners;
use App\Events\EpisodeCreated;
use App\Facades\EventHandler;
use App\Http\Resources\ShowResource;
class NewEpisodeListener {
public function __construct() {
}
public function handle(EpisodeCreated $event) {
EventHandler::sendNewEpisode((new ShowResource($event->episode->show))->toArray());
}
}
Lastly, I wrote the following unit test to make sure that the event is firing. It doesn't seem to be:
public function testNewEpisodeEventFiredOff() {
Event::fake();
$show = factory(Show::class)->create();
$episode = factory(Episode::class)->create(['show_id' => $show->id]);
Event::assertDispatched(EpisodeCreated::class);
}
I get an error saying that the event never got dispatched when I run phpunit. Also I added echo debug statements and while the EpisodeCreated object is being created, the NewEpisodeListener is not being fired off. Any help you guys can give would be greatly appreciated.
Well, my problem seems to be that I defined the boot method in EventServiceProvider without calling parent::boot(). Since I refactored my code to not use the boot method at all, I removed it and it seems to be working better now.
I had the issue and could solve this. You should add below code to your EventServiceProvider class:
public function register()
{
$this->boot();
}
It seems boot method is not called when it is run by UnitTest or Command-line command I don't know why.

PhpStorm Symfony 4 ContactType class not recognized

I have a very annoying problem today. I'm on Macbook Pro, PhpStorm 2017.3.6.
I tried to create a simple Symfony 4 contact form but something goes wrong with PhpStorm, the class "Contact Type" isn't recognized at all. I already tried to:
Clear and invalidate PhpStorm cache
Clear Symfony cache
Reboot the Macbook
Updated PhpStorm to 2017.3.6
I also tried to create the formType with another names, like TotoType for example and it's working, so its only with ContactType that's not working.
I use git also, so maybe it's a "cache" problem somewhere or a PhpStorm related problem?
<?php
namespace App\Form;
use App\Entity\Contact;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ContactType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('field_name')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
// uncomment if you want to bind to a class
//'data_class' => Contact::class,
]);
}
}
I also noticed that PhpStorm highlighted few errors about my Kernel.php file like this screenshot, and I don't know if things are related or not:
The Kernel.php file:
<?php
namespace App;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use Symfony\Component\Routing\RouteCollectionBuilder;
class Kernel extends BaseKernel
{
use MicroKernelTrait;
const CONFIG_EXTS = '.{php,xml,yaml,yml}';
public function getCacheDir()
{
return $this->getProjectDir().'/var/cache/'.$this->environment;
}
public function getLogDir()
{
return $this->getProjectDir().'/var/log';
}
public function registerBundles()
{
$contents = require $this->getProjectDir().'/config/bundles.php';
foreach ($contents as $class => $envs) {
if (isset($envs['all']) || isset($envs[$this->environment])) {
yield new $class();
}
}
}
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader)
{
$container->setParameter('container.autowiring.strict_mode', true);
$container->setParameter('container.dumper.inline_class_loader', true);
$confDir = $this->getProjectDir().'/config';
$loader->load($confDir.'/{packages}/*'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/{packages}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/{services}'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/{services}_'.$this->environment.self::CONFIG_EXTS, 'glob');
}
protected function configureRoutes(RouteCollectionBuilder $routes)
{
$confDir = $this->getProjectDir().'/config';
$routes->import($confDir.'/{routes}/*'.self::CONFIG_EXTS, '/', 'glob');
$routes->import($confDir.'/{routes}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, '/', 'glob');
$routes->import($confDir.'/{routes}'.self::CONFIG_EXTS, '/', 'glob');
}
}
I also tried to create the formType with another names, like TotoType for example and it's working, so its only with ContactType that's not working.
Based on screenshot ... the whole ContactType.php file is treated as plain text .. so no wonders that IDE does not recognize that class.
You must have accidentally marked this file as Text. To undo:
Settings/Preferences | File Types
Locate Text file type entry in the top list
Locate and remove offending pattern in the bottom list -- it will be ContactType.php or pretty similar.
I also noticed that PhpStorm highlighted few errors about my Kernel.php file like this screenshot, and I don't know if things are related or not:
Not related to the first issue for sure -- must be something else.

APCu Adapter & Symfony 3.3 -> Error

I am trying to plug APCu into the Symfony 3.3 test project.
I am getting an error, when I add ApcuAdapter to AppKernel.php.
Here is the list of what I have done:
in ./app/AppKernel.php i have added a "new" line to $bundles in public function registerBundles():
public function registerBundles()
{
$bundles = [
... ,
new Symfony\Component\Cache\Adapter\ApcuAdapter()
];
...
return $bundles;
}
Opened the project's site. It shows an error:
Attempted to call an undefined method named "getName" of class "Symfony\Component\Cache\Adapter\ApcuAdapter".
(./ means the root folder of the project)
Please, tell me why does this error happen and how to plug this adapter into the symfony framework. Thank you.
me have found the solution somewhere on the framework's website.
somehow, we should use not the Adapter, but the Simple instead.
seems very un-logical to me.
so, the Service now works and looks this way:
<?php
namespace AppBundle\Service;
use Symfony\Component\Cache\Simple\ApcuCache;
class ApcuTester
{
public function __construct
(
)
{
}
public function testMe()
{
$cache = new ApcuCache();
$TestVar_dv = 0;
$TestVar_vn = 'TestVar';
$TestVar = NULL;
//$cache-> deleteItem($TestVar_vn); // dbg
// Read
if ( $cache->hasItem($TestVar_vn) )
{
$TestVar = $cache->get($TestVar_vn);
}
else
{
$cache->set($TestVar_vn, $TestVar_dv);
$TestVar = $TestVar_dv;
}
// Modify
$TestVar++;
// Save
$cache->set($TestVar_vn, $TestVar);
// Return
return $TestVar;
}
}
And the Controller which executes this Service looks as this:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Service\MessageGenerator;
use AppBundle\Service\ApcuTester;
class LuckyController extends Controller
{
/**
* #Route("/lucky/number", name="lucky")
*/
public function numberAction
(
Request $request,
MessageGenerator $messageGenerator,
ApcuTester $apcuTester
)
{
$lucky_number = mt_rand(0, 100);
$message = $messageGenerator->getHappyMessage();
$testvar = $apcuTester->testMe();
$tpl = 'default/lucky_number.html.twig';
$tpl_vars =
[
'lucky_number' => $lucky_number,
'message' => $message,
'testvar' => $testvar
];
return $this->render($tpl, $tpl_vars);
}
}
If i wrote the same thing in pure PHP i would have done it an hour earlier :) Oh these crazy frameworks...

Unable to pass class instance to constructor

I have installed this package https://github.com/Intervention/image with composer. I have added
'IntImage' => 'Intervention\Image\Facades\Image'
to config/app under aliases
I get the following error and cant figure out what I am doing incorrectly I am sure it has something to do with namespacing /autoloading but app/acme is in the psr-o section of composer.json
'Argument 1 passed to
Acme\Services\Images\InterventionImageEditor::__construct() must be an
instance of IntImage, none given, called in
/var/www/app/ACme/Providers/ImageEditorServiceProvider.php on line 14
and defined' in
/var/www/app/Acme/Services/Images/InterventionImageEditor.php:11
I have the following directory structure
app
acme
Providers
ImageEditorServiceProvider.php
Services
Images
ImageEditorInterface.php
InterventionImageEditor.php
and the content of the files
ImageEditorServiceProvider.php
<?php namespace Acme\Providers;
use Illuminate\Support\ServiceProvider;
use Acme\Services\Images\InterventionImageEditor;
/**
*
*/
class ImageEditorServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind('Acme\Services\Images\ImageEditorInterface', function () {
return new InterventionImageEditor();
});
}
}
ImageEditorInterface.php
<?php namespace Acme\Services\Images;
interface ImageEditorInterface
{
public function hello();
}
InterventionImageEditor.php
<?php namespace Acme\Services\Images;
use IntImage;
/**
*
*/
class InterventionImageEditor implements ImageEditorInterface
{
protected $imageeditor;
public function __construct(IntImage $imageeditor)
{
$this->imageeditor = $imageeditor;
}
public function hello()
{
$hello = 'hello';
return $hello;
}
}
Can I
Use IntImage;
in this way because it is a facade or am I missing something?
edit to include solution;
changing the service provider to the following resolved the problem
<?php namespace Acme\Providers;
use Illuminate\Support\ServiceProvider;
use Acme\Services\Images\InterventionImageEditor;
use IntImage;
/**
*
*/
class ImageEditorServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind('Acme\Services\Images\ImageEditorInterface', function () {
$intimage = new IntImage;
return new InterventionImageEditor($intimage);
});
}
}
The error is coming from ImageEditorServiceProder.php:
$this->app->bind('Acme\Services\Images\ImageEditorInterface', function () {
return new InterventionImageEditor();
});
Here you are instantiating the InterventionImageEditor without any parameters. You InterventionImageEditor requires one parameter of type IntImage.
If there are places where you won't have IntImage when instantiating InterventionImageEditor then you need to update your InterventionImageEditor::__construct so that it accepts null(possibly).
function __construct(IntImage $imageeditor = null)
{
if (is_null($imageeditor)) {
// Construct a default imageeditor
// $imageeditor = new ...;
}
$this->imageeditor = $imageeditor;
}
i am not sure you can using IntImage because this file is Facades.
if you want to extending the intervention class. you should add Intervention\Image\Image to your ImageEditorServiceProvider.
use Intervention\Image\Image;
class ImageEditorServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind('Acme\Services\Images\ImageEditorInterface', function () {
return new InterventionImageEditor(new Image);
});
}
}

Categories