Laravel 5.1 Package Development - loading packages dependencies in development - php

Hi I'm trying to develop a package in Laravel 5.1. Thanks to help here I have the basics set up.
My current problem is how to load dependencies for the package while I'm developing it.
In the packages composer.json I have added dependencies and have these installed now in a vendor folder within my packages development folder. This is not the frameworks root vendor folder.
Here's my require section of the packages composer.json:
"require": {
"illuminate/support": "~5.1",
"php" : ">=5.3.0",
"google/apiclient": "dev-master"
},
Because they are not part of the main autoload process what is the best approach to ensuring the dependencies for my package are loaded correctly from within the development folder? How do I include the autoload? I'm concerned that if I reference them to their current location/namespace that it will break when later installed as a package in another app.
in my code I have the following:
$client = new \Google_Client($config);
which gives the error:
Class 'Google_Client' not found
I can get round this by adding this dependency to the main composer.json but don't think that is the correct approach to keep the package development independent (if that makes sense)
When I developed in L4.2 there was the workbench which took care of the loading which of course no longer features in L5.1
Any help and best practice appreciated

Because they are not part of the main autoload process
I think you misunderstood how composer dependencies are managed. When in your main compose.json file you list a dependency, composer will add it to the main autoload process as well as all their dependencies, and the dependencies of their dependencies, and so on recursively.
You don't have to worry about where the dependencies are stored or how Composer will load them. Composer will automatically add them to the autoload file and all you have to do is make sure you require the composer autoload file. Once you require the composer autoload file, all the classes and functions loaded by composer will be available. Provided you required the composer autoload file all you have to do to use the classes from any of the installed packages is to make sure you address them using the proper namespace. Composer is smart enough to know where all classes are stored and how to load them (that is what psr-0, psr-4,... are for).
So if you are developing a Composer package, lets call it 'A', and you list the package 'C' as one of the dependencies of your package 'A', composer will add it to the autoload file for you. If you use another package, lets say, Laravel, which has a dependency of you package 'A', then also the package 'C' will be available within Laravel, since it is a dependency of 'A'.
I.e: If this is your composer.json file
{
"name": "foo/bar",
"require": {
"google/apiclient": "1.0.*"
}
}
This code will work
require_once __DIR__ . '/vendor/autoload.php';
$client = new Google_Client();
$youtube = new Google_Service_YouTube($client);
Note I've required the composer autoload file, which seems to be your problem. When you are using Laravel, it will add that file for you.

Related

How can I check if PHP Composer autoload is working?

I am trying to transfer a small web application, which uses PHP Composer, from an old out of date server to a new server.
On the new server, I have run composer install to install the dependencies from the composer.lock file.
The web application requires a config file to set itself up (not that it does a lot of setting up), which includes the line
require_once __DIR__ . '/vendor/autoload.php';
…which should locate the autoloader relative to the config file, and make the packages installed by Composer known to the system.
However, this doesn't seem to be working properly, as when the web app tries to use SwiftMailer (which was installed via Composer), it says:
PHP Fatal error: Uncaught Error: Call to undefined method Swift_SmtpTransport::newInstance()
…in the file that calls it, which obviously suggests that it does not know about it and cannot find it.
Is there a way that I can meaningfully check what the result of the autoloader include is and see what it is (or is not) doing?
Make sure to add a use statement to your classes. You can arrange your classes and give your classes namespaces then allow composer to also auto-load your classes.
You can tell composer how your classes are arranged according to namespaces as follows:
In the autoload section of your composer.json file edit it to know how the namespaces of your classes is arranged
"autoload": {
"psr-4": {
"App\\": "src/",
"Mynamespace\\": "lib/src/ProjectSrc/"
}
},
The autoload section now tells composer the Classes in the ProjectSrc folder will have a root namespace of Mynamespace. From this information composer can determine all other sub namespaces in your directory tree. This will not happen automatically composer has to rebuild its mapping of classes with the composer dump-autoload command.

Custom composer autoload directory, loading multiple packages

Im developing a group of packag within a Laravel 5 app.
all the packages have the following structure.
Folder structure:
Vendor/Package/src
composer.json
"autoload": {
"psr-4": {
"Vendor\\Package\\": "src/"
}
},
I would like to be able to have a separate folder outside of the vendors/ folder that contains the packages, under development. As they are the basis for the application. NOTE: These packages will not be downloaded through composer, just auto-loaded with composer.
e.g.
\Laravel-App
\app
\bootstrap
\config
\database
\public
...
\src
The \src directory containing all the packages mentioned above.
It's not relevant that there is a composer.json inside each package, because the are not managed by composer (, yet). Their autoload definition will only be used for an autoload dump by Composer, if the package is installed/updated.
Here there are not handled by Composer, just sitting around in a folder.
There are multiple ways of solving the autoloading problem.
You could:
use the PHP autoload functions to register your own autoloader (during bootstrap)
use Laravel's Autoloader to add the path to these packages (during app bootstrap, somewhere after laravel autoloader init)
use Composer's Autoloader to add the paths to these packages (during app bootstrap, after Composer init)
but the easiest way would be to define the mapping in the autoload section of the composer.json file of your main application. Then they will be included in the dumped autoloader, after install or update of your Composer managed dependencies.

Why do CodeIgniter projects sometimes include composer.phar package?

I'm new to Composer and in my current project I would like to install a bunch of PHP libraries like:
Doctrine
Security Library (Which i have no idea but looking for in CodeIgniter)
Bootstrap layout libraries and other when necessary
For that matter , I would like to use Composer based library management in my application,
and i get confused that if i have to include composer.phar on my project directory or not.
since i have it on my environment path and I can run Composer form command line .
How can integrate the above libraries into my codeigniter application then..
Appreciate your toughs!
The composer.phar file is an executable and it should not be committed. What it actually does is that it looks in your composer.json file and there you can declare some more dependencies (libraries for example) and their version:
{
"require": {
"doctrine/orm": "*"
}
}
The version in this case is declared with "*" so Composer will get the latest version. This is very useful if there are more people on the project, to make sure all of them have the same version of dependencies installed (so the composer.json file must be committed).
If you run "composer.phar update" on the other hand, this will get the latest version of all dependencies, no matter the version placed in composer.json and updates the lock file with the new versions.

Symfony2.3 - How to add a custom vendor

I have a Symfony 2.3 project and I would like to use a custom vendor. I know that on Symfony versions 2.1 and 2.2, you can declare vendors in the deps file.
But how can I declare a custom vendor in Symfony 2.3 project? There is a composer.json file, but I don't really understand how it works.
EDIT:
The custom vendor's code is located on github.
composer.json manages dependencies through the composer tool (which you should have installed). It behaves similarly to npm if you have used that at all.
You can include a custom vendor in a couple of ways - although for the custom vendor code to be (auto)loaded & picked up by composer it will need to have a composer.json file.
Packagist
If the custom vendor has successfully submitted their to packagist then you life is easy, you can search for it and take note of the name (in the <vendor>/<package> format.
Open up your composer.json file and at the end of the "require": {} statement add your vendor. For example if our package was called peterjmit/awesome-package
// ...
"require": {
// ...
"peterjmit/awesome-package": "*"
},
// ...
You can replace the * with a version number if you wish. Once you have done that, you can run the composer update command to pull in your new package. If you only want to update the new package you can use composer update peterjmit/awesome-package.
Thanks to the composer autoloader, and the PSR-0 standard, classes from the package are auto-loaded so there is no other "plumbing" for you to do.
VCS repository
If the custom vendor is not on packagist, but does have a composer.json file then you can specify a custom repository to composer. You need to have the same require statement as before, but you need to add a new statement to composer.json
// ...
"require": {
// ...
"peterjmit/awesome-package": "*"
},
"repositories": [
{
"type": "vcs",
"url": "git#bitbucket.org:peterjmit/awesome-package.git"
},
// .. etc.
If the package does not have a composer.json then you can always fork it and add your own. But if the code does not conform to PSR-0 then you will have to sort out your own auto-loading strategy for the package.

How to get multiple vendor directories with composer?

My project relies on ZF and on a JS library. I wanted to be able to deploy the ZF library to the normal location (vendor/zendframework/zendframework1) but then deploy my JS library to somewhere else (public/my-vendor/my-library). Is there anyway to do this?
Composer is meant to manage your PHP dependencies, not JS.
Also, it only supports one vendor folder.
You might follow the way Symfony bundles use:
install everything in vendor
link (or copy) public assets to a public directory as part of your deployment process
In my opinion it's safer than installing something in a public folder (as long as you copy/link public part of a library only).
I came across the symlink idea but I wanted to automate this instead of manually creating the symlinks. I was going to create a composer script to create the symlink. I then found that symlinks on Windows and *nix need to be created in different ways which made this solution get messier by the second. I found that in the composer docs they talk about this same type of issue on the custom installers page and say that to solve this to create your own custom installer.
Relavent docs section: http://getcomposer.org/doc/articles/custom-installers.md
My custom installer: https://github.com/ddelrio1986/zf1-public-asset-installer
I have implemented this composer plugin to install packages into user (custom) defined folders you can just include it in your composer.json, follow the example and tell me if you have more questions :)
https://github.com/mnsami/composer-custom-directory-installer
composer-custom-directory-installer
A composer plugin, to install differenty types of composer packages in custom directories outside the default composer default installation path which is in the vendor folder.
This is not another composer-installer library for supporting non-composer package types i.e. application .. etc. This is only to add the flexability of installing composer packages outside the vendor folder. This package only supports composer package types,
https://getcomposer.org/doc/04-schema.md#type
The type of the package. It defaults to library.
Package types are used for custom installation logic. If you have a package that needs some special logic, you can define a custom type. This could be a symfony-bundle, a wordpress-plugin or a typo3-module. These types will all be specific to certain projects, and they will need to provide an installer capable of installing packages of that type.
How to use
Include the composer plugin into your composer.json require section::
"require":{
"php": ">=5.3",
"mnsami/composer-custom-directory-installer": "1.1.*",
"monolog/monolog": "*"
}
In the extra section define the custom directory you want to the package to be installed in::
"extra":{
"installer-paths":{
"./monolog/": ["monolog/monolog"]
}
by adding the installer-paths part, you are telling composer to install the monolog package inside the monolog folder in your root directory.
As an added new feature, we have added more flexibility in defining your download directory same like the composer/installers, in other words you can use variables like {$vendor} and {$name} in your installer-path section:
"extra": {
"installer-paths": {
"./customlibs/{$vendor}/db/{$name}": ["doctrine/orm"]
}
}
the above will manage to install the doctrine/orm package in the root folder of your project, under customlibs.
Note
Composer type: project is not supported in this installer, as packages with type project only make sense to be used with application shells like symfony/framework-standard-edition, to be required by another package.
By default, Composer reads composer.json schema. But, it can also use a different file. For instance, you can have zendframework.json and my-library.json.
In the zendframework.json, you can define:
"config": {
"vendor-dir": "zendframework/vendor"
},
In the my-library.json, you can define:
"config": {
"vendor-dir": "my-library/vendor"
},
Finally, you can update the libraries in this way:
COMPOSER=zendframework.json composer update
COMPOSER=my-library.json composer update
This is a simple idea. The benefit is that you solve the issue without third-party tools.

Categories