Composer, Read package version number programmatically - composer-php

For a Symfony based console application, I need to read the it's version number from it's composer file (not branch alias), programmatically.
Manually, I can use the composer show -s to get the root package information, but there does not seem to be any command to to get the clean version of my package.
The purpose is to automatically display the installed package version, when running the application, without having to deal with *.txt files or other file-based ways that contain a semantic version number.
Sadly I am not familiar with composer's architecture, so I have no idea what components I can use to achieve this.
Any ideas or perhaps already made packages that solves is mostly welcome.

I know its kinda late reply but you can read the info from a JSON file which is written by composer.
the file is located at vendor/composer/installed.json.
Read the JSON, parse it, and get the info you want.
This package does that some what.

Install Composer in your project
composer require composer/composer --dev
example.php
<?php
// Include Composer Autoload
require __DIR__ . '/vendor/autoload.php';
use Composer\Factory;
use Composer\IO\NullIO;
$composer = Factory::create(new NullIo(), './composer.json', false);
$localRepo = $composer->getRepositoryManager()->getLocalRepository();
foreach ($localRepo->getPackages() as $package) {
echo $package->getName() . PHP_EOL;
echo $package->getVersion() . PHP_EOL;
echo $package->getType() . PHP_EOL;
// ...
}

Related

Errors in the autoloaded HTTP/Request2 code, how to troubleshoot composer?

I have two different systems with a git repository cloned on them.
the project uses composer to install various dependencies.
One of these is pear/HTTP_Request2 which requires Net/URL2.
Both systems are Windows with a xampp development enviroment. So both run an Apache2 with a PHP 7.1.* installation.
On one of them everything works perfectly after installing via composer install. But the other one always Errors in the autoloaded HTTP/Request2 code:
<b>Warning</b>: require_once(Net/URL2.php): failed to open stream: No such file or directory in <b>C:\xampp\htdocs\XXX\vendor\pear\http_request2\HTTP\Request2.php</b> on line <b>25</b><br />
<br />
<b>Fatal error</b>: require_once(): Failed opening required 'Net/URL2.php' (include_path='C:\xampp\htdocs\XXX\vendor/pear/pear_exception;C:\xampp\htdocs\XXX\vendor/pear/http_request2;C:\xampp\php\PEAR') in <b>C:\xampp\htdocs\XXX\vendor\pear\http_request2\HTTP\Request2.php</b> on line <b>25</b><br />
Looking at the code in the Package we find:
if (!class_exists('Net_URL2', true)) {
require_once 'Net/URL2.php';
}
The dependency of NetURL2 was successfully installed, judging by composers output.
None the less I tried to fix it by also requiring the dependency from HTTP/Request2 "pear/net_url2" : "^2.2.0", in the Project after i heard from a bug (long closed but still) about problems with that (Issue#composer git), which didn't result in a change.
Judging by the inspected code I also assume this question is outdated.
Now I'm stuck not knowing what to do next... Help?
Edit:
My composer.json essentially looks like this if anyone was wondering:
{
"require":
{
"php":">=7.1.4",
"pear/http_request2": "v2.3.0",
"ext-json":"1.5.0",
"ext-PDO":"7.*",
"ext-pdo_mysql":"7.*",
"ext-mbstring":"7.*",
"ext-gd":"7.*"
},
"autoload": {
"files": [
"helper.php",
"settings.php"
],
"classmap": ["./"],
"exclude-from-classmap": ["vendor/"]
}
}
To troubleshoot Composer in general, you can add -vvv flags for verbose information.
Secondly, when you've XDebug extension for PHP installed, you will see a Call Stack each time when a Fatal error happens.
Note: Run phpenmod -s cli xdebug to enable XDebug in CLI mode.
The fatal error happens in pear/http_request2 package (as per vendor/pear/http_request2/HTTP/Request2.php) when it tries to include Net/URL2.php file (part of pear/net_url2, full path: vendor/pear/net_url2/Net/URL2.php).
This path should normally be added by Composer into include_paths.php like:
vendor/composer/include_paths.php: $vendorDir . '/pear/net_url2',
which failed to do so. To generate autoload files again, run this command:
composer dump-autoload -o
and check whether the autoload files under vendor/composer has been generated as expected.
To test that out, I've run this PHP command and it worked:
php -r 'require_once "vendor/autoload.php"; require_once "vendor/pear/http_request2/HTTP/Request2.php";'
Note: To see the failing scenario, remove include of autoload.php.

Laravel use non composer package

How can I use this non composer package to my controller?
https://github.com/lelag/otphp
I've tried
use OTPHP;
$totp = new \OTPHP\TOTP($secret);
and I get
Class 'OTPHP\TOTP' not found
You will need to require the file.
require_once('/path/to/otphp.php');
Or if you want to use composer.json, look into using classmaps

Undefined class Route (Laravel in PhpStorm)

How can I fix this alert in PhpStorm?
And also how to get autocompletion for Route and other Facades?
Check the Laracasts walkthrough
1) Go to: https://github.com/barryvdh/laravel-ide-helper
2) Click on the gist
Generated version for L5: https://gist.github.com/barryvdh/5227822
3) Click on "Raw" to get the current version (as of June 22, 2016 it is):
https://gist.githubusercontent.com/barryvdh/5227822/raw/4d4b0ca26055fa4753b38edeb94fad2396c497c0/_ide_helper.php
4) Make sure you're in your root directory (this is mine)
cd /var/www/html/project
5) Download the gist:
wget https://gist.githubusercontent.com/barryvdh/5227822/raw/4d4b0ca26055fa4753b38edeb94fad2396c497c0/_ide_helper.php
6) Add "_ide_helper.php" to the .gitignore file
sudo nano .gitignore
Add "_ide_helper.php" on a new line at the bottom
7) Download the .gitignore and _ide_helper.php files into PhpStorm
This is what my PhpStorm project directory looks like afterwards:
8) After the files are downloaded into PhpStorm, the "Undefined class" error will disappear and autocompletion will now work. Might need to restart it.
There is greate IDE support for Laravel shipped from Baryvdh:
https://github.com/barryvdh/laravel-ide-helper
after you install it you just call in the console:
php artisan ide-helper:generate
which generate alll facede shortcuts in _ide_helper.php file (which you have to exclude from git)
There is also something special for PhpStorm:
php artisan ide-helper:meta
which will give Laravel container context for example:
$foo = app(Foo::class);
PhpStorm will know that the $foo variable is type of Foo class.
I know this is an old thread, but it is still relevant. For me, I decided to add the following to my routes/web.php since I don't want to have to worry about regenerating meta data for the app.
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Auth;
Edit: The above does not add any overhead to PHP as the use simply acts as a reference for PHP.
I solved this problem simply by installing the Laravel idea plugin.
Use the following link:
https://laravel-idea.com/
You can install it on your phpstorm.
Its good feature is that you can use it for 30 days for free and pay the amount after satisfaction.

Installing and using Mink with Browserkit driver

I seem to be unable to install Mink with Browserkit driver on Centos.
I am using these instructions: https://github.com/minkphp/MinkBrowserKitDriver
The steps I am taking is by:
adding a file in my project directory with the name composer.json and the contents:
{
"require": {
"behat/mink": "~1.5",
"behat/mink-browserkit-driver": "~1.1"
}
}
Use the commands as below.
$> curl -sS https://getcomposer.org/installer | php
$> php composer.phar install
Now there are 3 files (composer.json, composer.lock, composer.phar) and one folder (vendor) in the project directory. Where do I run the "Usage example" code from (as on the documentation)?
I have tried adding require_once "vendor/autoload.php"; to my test.php file:
<?php
require_once "vendor/autoload.php";
use Behat\Mink\Mink,
Behat\Mink\Session,
Behat\Mink\Driver\BrowserKitDriver;
use Symfony\Component\HttpKernel\Client;
$app = require_once(__DIR__.'/app.php'); // Silex app
$mink = new Mink(array(
'silex' => new Session(new BrowserKitDriver(new Client($app))),
));
$mink->getSession('silex')->getPage()->findLink('Chat')->click();
but getting a fatal error that app.php cannot be opened. I have also tried adding the following to test.php:
require_once 'vendor/behat/mink-browserkit-driver/tests/app.php';
Any help would be appreciated :)
Its seems you're missing some guideline in order to organize your code. Before integrating Behat and Mink, first of all you should organize your Silex project. My advice is for you to take a look at the official Silex Skeleton project.
After that you can start by installing behat, mink and your driver:
cd path/to/your/silex/project/root
composer require behat/behat:~2.5 behat/mink behat/mink-browserkit-driver
Then you can initialize behat.
bin/behat --init
Then configure your mink driver in behat.yml (on your project root directory)
default:
extensions:
Behat\MinkExtension\Extension:
browserkit: ~
base_url: http://my.dev.host
Notice that browser kit cannot execute JS, remember that (if you want to execute JS on your tests, you should install another driver)
After that you can start writing your features on the features directory (behat should've created that for you), for example if you have this controller in src/controllers.php:
<?php
//...
$app->get('/hello', function () use ($app) {
return new Response("Hello world!");
});
You can write the feature (on features/greeting.feature):
Feature: Greetings from /hello page
In order to say hello world
As a visitor
I need to go to the /hello page and see Hello world!
Scenario: See Hello world!
Given I am on "/hello"
Then I should see "Hello world!"
Another option is to use full behat extension for silex: https://github.com/tabbi89/Behat-Silex-Extension
You can check how integrations of Mink and browserKit work there.

Composer classmap autoload does not load new files in folder

The following problem: I have defined a classmap in my composer.json:
"autoload": {
"classmap": [
"app/controllers",
"app/models",
"app/helper.php"
]
}
However, when I create a new file in the "controllers" or "models" folder, it will not load them and I always have to make a composer dump-autoload.
Is this the correct behavior? I thought the autoloader from composer monitors the folder for new files then?
Yes, this is correct behaviour. If you want new classes to be loaded automatically, you have to use either PSR-0 or PSR-4 autoloading.
Generating the classmap requires Composer to know the filename that contains a certain class. This can only be done by parsing the whole source code in the directory and scanning for classes, interfaces and trait definitions.
This usually is a CPU and I/O intensive task, so it is only done when Composer does install/update or (on demand) dumps the autoloader, it is not done with every require "vendor/autoload.php";.
Note that the classmap autoloading is simply there for old legacy codebases that didn't implement at least PSR-0. It is not intended for new code - unless you want to pay the price to dump the autoloader again and again during development.
Go to the root of your server by SSH. Now do the following:
Run ls to list all the files.
You will see composer.lock file; remove the file with rm composer.lock command.
Now run php composer update command.
Depending on your linux type you may have to run php-cli composer update.
Step 3 will create a new composer.lock file and all your classes will be loaded again. Do this anytime you add new classes.
or:
Run composer dump-autoload command.
As already pointed out this is correct behavior. If you want new classes to be loaded automatically, you have to use either PSR-0 or PSR-4 autoloading.
The classmap autoload type specified is composer.json is mainly used by legacy projects that do not follow PSR-0 or PSR-4. I have recently started working on such a project and wanted to try to automatically run the composer dump-autoload command when a new class is created. This is actually tricky without including all of the composer source inside the project. I came up with this just to remind the developer they need to dump the classmap:
$loader = include_once 'vendor/autoload.php';
if ( ! $loader ) {
throw new Exception( 'vendor/autoload.php missing please run `composer install`' );
}
spl_autoload_register(
function ( $class ) {
if ( 'A_Common_Class_Prefix' === substr( $class, 0, 10 ) ) {
throw new Error( 'Class "' . $class . '"" not found please run `composer dump-autoload`' );
}
},
true
);
This registers another autoloader which is run after composer's autoloader so any classes composer did not find would be passed to it. If the class matches a prefix an exception is throw reminding the developer to re-dump the autoloader and update the classmap.
For me, it somehow did not work too with Yii 1 class-map, when I added - required it along with many other libraries present - I don't remember exactly perhaps I manually edited the file or file permissions were to blame, it was not regenerated for some reason, even when I removed the composer.lock and erased completely the vendor folder - perhaps some cache, as far as I remember, but effectively what helped was to install firstly isolatedly only this single library, it generated class-map, then I added all the other remaining libraries separately at once at second step, viola, everything loadable.

Resources