Symfony2 Composer post-install-cmd - symfony

I need to install an symfony2 bundle over the composer and do some stuff after the install process. So for the "stuff" after the install i add one line to the "post-install-cmd" in the composer.json
ServiceBundle\\Core\\Platform::registerService
and it calls the function, everything fine
public static function registerService(Event $event) {
//some stuff
exit;
}
The command I use:
php composer.phar update serviceplatform/bundles/poll
Now my question:
Is it possible to get the name "serviceplatform/bundles/poll" or pass any arguments to the statement? I need the path from the bundle after the install.

extra node is what you're looking for - https://getcomposer.org/doc/04-schema.md#extra
In your composer.json:
"extra": {
"your-parameter": "serviceplatform/bundles/poll"
}
Then, in your ServiceBundle\Core\Platform::registerService:
public static function registerService(Event $event)
{
$extras = $event->getComposer()->getPackage()->getExtra();
$yourParameter = $extras['your-parameter'];
//do your stuff
}
It should do the trick.

Related

Command created issue

I have a command which is in production already and I suspect not to be working. The dev who worked on it is not there anymore. So I come here to find some help.
There is 2 things I don't understand.
1- The command name is inside the Controller folder... ApiController but it extends ContainerAwareCommand so I guess this is fine...
2- The command is not find, but might be related to the first point.
When I try: php bin/console app:commandTest
I've got his error in console:
There are no commands defined in the "app" namespace.
class ApiController extends ContainerAwareCommand
{
protected function configure () {
$this->setName('app:commandTest');
$this->setDescription("Some desc");
$this->setHelp("Some help");
}
public function execute(InputInterface $input, OutputInterface $output)
{ // whatever }
}
Peoples told me this code worked when the previous dev was working on it...but I can't see how actually. I hope you can see how to do it or how to make it work.
Thanks.
EDIT: What I tried to add to my services.yaml but it's not working
services:
app.command.api_controller:
class: AppBundle\Controller\ApiController
arguments: ["%command.default_name%"]
tags: - { name: console.command }
config.yaml
imports:
- { resource: services.yml }
But doing this there is an error
The file "/var/www/unitimmo/UniTimmo/app/config/services.yml" does not contain valid YAML

Custom Repository in Doctrine

I have a controller:
public function getAllItemsAction()
{
$content = $this->getDoctrine()->getRepository(Item::class)->findAll();//<-(1)--THIS TO REPOSITORY
if ($content === NULL) {
return new View("Items not found", Response::HTTP_NOT_FOUND);
}
return new View($content,Response::HTTP_OK);
}
How can I move this line (1) to the repository and then use this method from the repository in the controller?
The line you highlighted is actually not related from Doctrine: you are getting a service from the Dependency Injection container, and then calling a method on it.
What may bothers you is that you are using an alias (getDoctrine()) and the registry from Doctrine, which is there for conveniency.
But actually you could also declare you repository as a service and do this: $this->get('item_repository)->findAll()`.

symfony 4 : How to get "/public" from RootDir

I have an image under the public folder.
How can I get my image directory in symfony4 ?
In symfony 3, it's equivalent is :
$webPath = $this->get('kernel')->getRootDir() . '/../web/';
It is a bad practice to inject the whole container, just to access parameters, if you are not in a controller. Just auto wire the ParameterBagInterface like this,
protected $parameterBag;
public function __construct(ParameterBagInterface $parameterBag)
{
$this->parameterBag = $parameterBag;
}
and then access your parameter like this (in this case the project directory),
$this->parameterBag->get('kernel.project_dir');
Hope someone will find this helpful.
Cheers.
You can use either
$webPath = $this->get('kernel')->getProjectDir() . '/public/';
Or the parameter %kernel.project_dir%
$container->getParameter('kernel.project_dir') . '/public/';
In Controller (also with inheriting AbstractController):
$projectDir = $this->getParameter('kernel.project_dir');
In config/services.yaml:
parameters:
webDir: '%env(DOCUMENT_ROOT)%'
In your controller:
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
...
public function yourFunction(Parameterbag $parameterBag)
{
$webPath = $parameterBag->get('webDir')
}
If you need to access a directory within public, change the last line to the following:
$webPath = $parameterBag->get('webDir') . '/your/path/from/the/public/dir/'
You can inject KernelInterface to the service or whatever and then get the project directory with $kernel->getProjectDir():
<?php
namespace App\Service;
use Symfony\Component\HttpKernel\KernelInterface;
class Foo
{
protected $projectDir;
public function __construct(KernelInterface $kernel)
{
$this->projectDir = $kernel->getProjectDir();
}
public function showProjectDir()
{
echo "This is the project directory: " . $this->projectDir;
}
}
Starting from Symfony 4.3 we can generate absolute (and relative) URLs for a given path by using the two methods getAbsoluteUrl() and getRelativePath() of the new Symfony\Component\HttpFoundation\UrlHelper class.
New in Symfony 4.3: URL Helper
public function someControllerAction(UrlHelper $urlHelper)
{
// ...
return [
'avatar' => $urlHelper->getAbsoluteUrl($user->avatar()->path()),
// ...
];
}
All above answers seems valid, but I think it's simplier if you configure it as parameter in services.yaml
If you need to use it in serveral services, you can bind it like this:
# services.yaml
services:
_defaults:
autowire: true
autoconfigure: true
bind:
$publicDir: "%kernel.project_dir%/public"
# src/Services/MyService.php
class MyService
{
public function __construct(
private string $publicDir,
) {
}
// …
}
This way, this is configured at one place only, and if later you decide to change /public to something else, you will have to change it only in .yaml file.
If you don't need the root directory but a subdirectory, it might be better to define the final target path: This way you will be more flexible if you need later to move only that directory, like $imageDir or $imagePath (depends if you will use the full directory or only the public path).
Note also the default public path is defined in composer.json file, in the extra.public-dir key

Class not found when using custom class

I am using excel reader from https://github.com/nuovo/spreadsheet-reader and it is in app folder.
Now when I try to access it from HomeController.php using following code.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use App\spreadsheet_reader\php_excel_reader\excel_reader2;
use App\spreadsheet_reader\SpreadsheetReader;
class HomeController extends Controller
{
public function index()
{
require_once(base_path().'/app/spreadsheet_reader/php_excel_reader/excel_reader2.php');
$Reader = new \App\spreadsheet_reader\SpreadsheetReader(base_path().'/UnRegisterClient.xlsx');
}
}
Then it gives me following error.
Class 'App\spreadsheet_reader\SpreadsheetReader' not found
Any suggesstion how I can solve this? I mean how I can use my custom class?
Put your external files in the folder app/Libraries (first, create the Libraries folder) then just autoload the folder with that file.
For example, add this folder in the array or “classmap” in composer.json :
"autoload": {
"classmap": [
"database",
"app\Libraries"
],
"psr-4": {
"App\\": "app/"
}
},
Then run composer dump-autoload in your command line.
I think the SpreadsheetReader is not defined in the namespace. You should call just new \SpreadsheetReader(...) or add use SpreadsheetReader and then call it new SpreadsheetReader()

registerContainerConfiguration do not execute in Prod

i would like to load a yml file in same time that the config.yml.
this is my code:
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load($this->getRootDir().'/config/config_'.$this->getEnvironment().'.yml');
$envParameters = $this->getEnvParameters();
if(isset($envParameters['config.boutique'])){
$loader->load($this->getRootDir().'/config/boutique/'.$envParameters['config.boutique'].'.yml');
}
}
in mode dev, this work like a charm but when i am in mode prod, this function do not execute.
i have to replace this line in app.dev.php :
$kernel = new AppKernel('prod', true);
by
$kernel = new AppKernel('prod', false);
how can i to load this yml file in mode prod?
thanks for your help
If I understand right, you can't define a parameter in the config file and use it already because symfony has to compile its kernel.
You can define the file by putting
#config_prod.yml
imports:
- { resource: boutique/YOUR_VALUE.yml }
#config_dev.yml
imports:
- { resource: boutique/YOUR_VALUE_DEV.yml }
If the YOUR_VALUE is dynamic I hope this post will help: Symfony: Dynamic configuration file loading . It is using DependencyInjection of the Bundle

Resources