Get version from composer.json [Symfony] - symfony

I wonder if there is a way to get the composer.json version from a controller with Symfony. My composer.json looks like:
{
"name": "myProject",
"version": "0.0.0",
"description": "myProject description",
"license": "AGPL-3.0",
"type": "project",
"require": {
"php": "^7.1.3",
...
}
}
I can't find any reference to this.
PS: I'm using Symfony 4.

You can do something like this:
$filename = $this->getParameter('%app.kernel_dir%') . '/../composer.json';
$composerData = json_decode(file_get_contents($filename), true);
$version = $composerData['version'];
The variable should then containv the value 0.0.0 from your example.
This assumes that your controller extends the base Controller to access the %app.kernel_dir% parameter. If not, you could just as well use the relative path from your controller or something else to determine the location of the composer.json

Without packages, with Composer you can use $version = \Composer\InstalledVersions::getPrettyVersion('package/package-name')

You can use the PackageVersions library and its relative PrettyPackageVersions.
They provide a single class API to get the currently installed version of your Composer dependencies, for example:
use PackageVersions\Versions;
use Jean85\PrettyVersions;
// Will output "1.0.0#0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"
echo Versions::getVersion('myvendor/mypackage');
// Will output "1.0.0"
echo (string) PrettyVersions::getVersion('myvendor/mypackage');

Reffering Salam answer, you can also get own project (named root package in composer world) version stored in composer.json by:
$version = \Composer\InstalledVersions::getRootPackage()['version'];
or for prettier print:
$version = \Composer\InstalledVersions::getRootPackage()['pretty_version'];

Related

Do I need to append every generated bundle to composer.json manually?

I've started to learn Symfony and I am following some tutorials where there is nothing about this:
When I create a new project with symfony installer and run composer install and then php app/console server:start I can open that project in my browser.
BUT! When I create a new bundle with command php app/console generate:bundle I get this error message:
PHP Fatal error: Uncaught Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load class "BlogBundle" from namespace "BlogBundle".
Did you forget a "use" statement for another namespace? in /home/user/Symfony/myapp/app/AppKernel.php:19
And then I need to go to my composer.json file and append my new generated bundle after AppBundle like this
{
"name": "user/myapp",
"license": "proprietary",
"type": "project",
"autoload": {
"psr-4": {
"AppBundle\\": "src/AppBundle",
"BlogBundle\\": "src/BlogBundle" // <-- this is the new appended one
},
"classmap": [
"app/AppKernel.php",
"app/AppCache.php"
]
},
..........
And then when I try to start the server again it works and it shows Hello world in my browser.
So the question is do I have to do this every time (append new generated bundle in composer.json file)?
Yes. This is the reason, why you usually have an namespace above that. Some abbreviation of your name or company for example. This way you only add that namespace for the src folder and all bundles are "found" automatically.
Example:
{
...
"autoload": {
"psr-4": {
"Acme\\": "src"
},
}
...
}
Now of course your bundles need to use that namespace, eg.:
namespace Acme\BlogBundle;
class BlogBundle {
}

Missing Classes from Silverstripe Omnipay

On a fresh scotch box https://box.scotch.io/ (which I generally recommend)
and with this composer:
{
"name": "silverstripe/installer",
"description": "The SilverStripe Framework Installer",
"require": {
"php": ">=5.3.3",
"silverstripe/cms": "3.5.1",
"silverstripe/framework": "3.5.1",
"silverstripe/reports": "3.5.1",
"silverstripe/siteconfig": "3.5.1",
"silverstripe-themes/simple": "3.1.*",
"silverstripe/silverstripe-omnipay": "^2.1",
"omnipay/paymentexpress": "^2.2",
"firebase/php-jwt": "^4.0"
},
"require-dev": {
"phpunit/PHPUnit": "~3.7#stable"
},
"extra": {
"branch-alias": {
"3.x-dev": "3.5.x-dev"
}
},
"config": {
"process-timeout": 600
},
"prefer-stable": true,
"minimum-stability": "dev"
}
And using payment.yml from https://github.com/silverstripe/silverstripe-omnipay
Silverstripe builds Payments, but none of the Omnipay classes are included. I have used Omnipay before with SS with no problems.
Anybody know what is going on?
Make sure you run the following on the command-line:
$> ./framework/sake dev/build flush=all
Also always worth just blowing away the contents of SS' cache (You're using Vagrant, so assuming this is a Dev env) which is usually located in /tmp if you're using the F/S and not memcache or some such, then running dev/build again. This will both clear and rebuild your cache, and in the process tell SS about all the new classes it has available to it.
silverstripe-omnipay makes use of php namespaces for many of its files, it just so happens that ServiceFactory is one of them so in order for SilverStripe to find the correct file to include you must specify its use at the top of files you intend to use ServiceFactory.
<?php
use SilverStripe\Omnipay\Service\ServiceFactory;
...
It is not entirely obvious because modules made for SilverStripe rarely make use of namespaces fo and silverstripe-omnipay makes no mention that ServiceFactory is namespaced in its examples.
What errors do you get? and how are you trying to access the classes?
You should be able to call the classes like this (depending on the Omnipay version)
<?php
use Omnipay\Omnipay;
class PaymentPage extends Page
{
function ...
{
try {
$response = $gateway->purchase([...
}
}

Including a Symfony bundle from a subtree : how to expand autoload path?

I'm using a bundle from a subtree, so I can't modify the structure nor the placement of it. I currently am trying to get it included in autoloading process, and am failing miserably with the "class not found" error message.
Currently, my project tree (made with Symfony 3.2) is :
|- app
|- src
|- MyappBundle
|- external
|- Author
|-UserBundle
|- Controller
|- [...]
|- AuthorUserBundle.php
AuthorUserBundle.php contains :
namespace Author\UserBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AuthorUserBundle extends Bundle
{
}
To include this bundle, I added in app/AppKernel.php :
new Author\UserBundle\AuthorUserBundle(),
I also added to app/autoload.php, before AnnotationRegistry::registerLoader :
$loader->add('Author',__DIR__.'/../src/external');
I don't master the namespaces imbrications, especially regarding the depth of call, but I tried many variations in autoload.php (like '/../src/external/Author') or AppKernel.php (Author\UserBundle\AuthorUserBundle\AuthorUserBundle()) ending all with the same error message "Class not found".
What did I miss ?
Sorry for the newbie question, I tried alone first, thank you for your time.
P.S. : the external directory can't be removed, the git subtree process doesn't allow to operate in a non empty directory.
You shouldn't use git subtree to include 3rd party code. Add a composer.json to your AuthorUserBundle with all needed autoloading and dependencies. A minimal example (replace ^3.0 with ^2.7 if you still use Symfony 2.7/2.8):
{
"name": "author/user-bundle",
"license": "proprietary",
"type": "library",
"require": {
"symfony/framework-bundle": "^3.0"
},
"autoload": {
"psr-4": {
"Author\\UserBundle\\": ""
},
}
}
And require it in your main project as private repository. Please add git tags to and follow semantic versioning.
Assuming your bundle is then called author/user-bundle (composer name), add the following to your projects composer.json:
{
"require": {
"author/user-bundle": "^1.0"
},
"repositories": [
{
"type": "vcs",
"url": "git#git.example.author/user-bundle.git"
}
]
}
Edit 1: added composer.json for AuthorUserBundle repository.
I would give a try to addPsr4 method instead
$loader->addPsr4('Author\\UserBundle\\', __DIR__.'/../src/external/Author/UserBundle');

Wrap PHPWord on bundle

I just want to use PHPWord for Symfony 2. But Im new on Symfony 2.
I paste PHPWord source into my util folder bundle but there is an error loading autoloader class from PHPWord...
Question is simple, How can I "wrap" code (in this case PHPWord) in to bundle? or someway I can use it.
Any solution?
Thanks for answering, that gives me some light. Altough, This doen't work for me.
I download composer.phar and I edit my composer.json as you say: adding in my require region "phpword/phpword": "0.6.2" and creating new repository phpword...
Doesn't work, I run "php composer.phar" command but It doesn't download anything...
Any tutorial or tip to make this work?
Thank you
composer require phpoffice/phpword dev-master did the work for me.
It should download and place install PhpOffice\PHPWord under the vendor folder in your Symfony2 installation (besides modifying your composer.json automatically).
In the controller you are about to use PhpWord:
use PhpOffice\PhpWord\PhpWord;
And inside the action, you can create a new instance as follows:
$doc = new PhpWord();
You shouldn't be copying the source code yourself. Use composer to install PHPWord.
Since PHPWord doesn't use composer (yet), you'll need to define a repository in your composer.json:
{
"require": {
"phpword/phpword": "0.6.2"
},
"repositories": [
{
"type": "package",
"package": {
"name": "phpword/phpword",
"version": "0.6.2",
"dist": {
"url": "http://download-codeplex.sec.s-msft.com/Download/Release?ProjectName=phpword&DownloadId=138035&FileTime=129545976016270000&Build=19692",
"type": "zip"
},
"autoload": {
"classmap": ["."]
}
}
}
]
}
Than you'll be able to use PHPWord in your Symfony project (any PHP project in fact):
$word = new PHPWord();
$writer = new PHPWord_Writer_Word2007($word);
$writer->save('test.doc');
Update: I just realized the URL to download changes with time. It'd be better to replace it with something that doesn't change (if possible, otherwise host it somewhere yourself).
As the URL changes, you can use the github repository if you've no problem with the dev version :
{
"require": {
"phpword/phpword": "dev"
},
"repositories": [
{
"type": "package",
"package": {
"name": "phpword/phpword",
"version": "dev",
"dist": {
"url": "https://github.com/PHPOffice/PHPWord/archive/develop.zip",
"type": "zip"
},
"autoload": {
"classmap": ["."]
}
}
}
]
}
You can use this simple bundle as wrapper for PhpWord:
https://packagist.org/packages/ggggino/wordbundle

How to use PHPExcel correctly with Symfony 2

I need to use PHPExcel with a Symfony2 project. Anyone know how to set up the project correctly to use the library? Should i put it in the vendor directory? What should be changed in the configuration files etc?
Actually, to do it right you need to follow next steps:
Edit your deps file and add dependency from the PHPExcel
[PHPExcel]
git=http://github.com/PHPOffice/PHPExcel.git
target=/phpexcel
version=origin/master
Run php bin/vendors install in order to install all missing dependencies (PHPExcel in our case)
Update prefixes section in app/autoload.php:
$loader->registerPrefixes(array(
// ...
'PHPExcel' => __DIR__.'/../vendor/phpexcel/Classes',
));
Done. Now, you can use it in your bundle's controller (code based on PHPExcel example from Tests/01simple-download-xls.php):
<?php
namespace Demo\MyBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use PHPExcel;
use PHPExcel_IOFactory;
class DemoController extends Controller
{
public function demoAction()
{
$response = new Response();
// Create new PHPExcel object
$objPHPExcel = new PHPExcel();
// Set document properties
$objPHPExcel->getProperties()->setCreator("Me")
->setLastModifiedBy("Someone")
->setTitle("My first demo")
->setSubject("Demo Document");
// Add some data
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('A1', 'Hello')
->setCellValue('B2', 'world!')
->setCellValue('C1', 'Hello')
->setCellValue('D2', 'world!');
// Set active sheet index to the first sheet
$objPHPExcel->setActiveSheetIndex(0);
// Redirect output to a client’s web browser (Excel5)
$response->headers->set('Content-Type', 'application/vnd.ms-excel');
$response->headers->set('Content-Disposition', 'attachment;filename="demo.xls"');
$response->headers->set('Cache-Control', 'max-age=0');
$response->prepare();
$response->sendHeaders();
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save('php://output');
exit();
}
}
Copy the library to your vendors directory.
Configure autoloader in your bootstrap file:
$loader->registerPrefixes(array(
// Swift, Twig etc.
'PHPExcel' => __DIR__ . '/../vendor/phpexcel/lib/PHPExcel'
));
That's all.
actually the best solution is to use https://github.com/liuggio/ExcelBundle.
I tried to use #Crozin's solution but I was still getting an error about IOFactory::createWriter.
Hope this helps,
Simone
As of Symfony 2.3, you can now do this:
...
"require": {
...
"phpoffice/phpexcel": "dev-master"
...
},
...
Then just run composer update and dependencies will resolve automatically.
Or you can do composer require phpoffice/phpexcel:dev-master if you don't want to mess with the composer.json file.
If you are using composer to manage your project, you can just change the composer.json file:
"autoload": {
"psr-4": {
"": "src/",
"": "vendor/phpoffice/phpexcel/Classes/"
},
"classmap": [
"app/AppKernel.php",
"app/AppCache.php"
]
},
Then add
use PHPExcel;
use PHPExcel_IOFactory;
to your controller file, and you can use the PHPExcel like this:
$objPHPExcel = new PHPExcel();
Hope it helps.
With composer (since Symfony2.1) it's really easy, you only have to modify the composer.json.
You don't need to register the namespace anymore!
Only two things, to notice:
refer to github tags, I only found a soltion with the package type
when changing something in the composer.json related to the class autoloading stuff, you have to remove the whole directory in the vendor dir
Here is the related link: use PHPExcel with composer and Symfony2.2

Resources