Custom Laravel Directory Install With Composer - php

I was wondering if it was possible to create a custom laravel "template" with composer.
For example, I want to include in my composer's create-project laravel/laravel install these two extensions by default,
https://github.com/briannesbitt/Carbon
https://github.com/maxhoffmann/parsedown-laravel
or additional folders in the root directory so I don't have to re-create them each time.
I don't mean to ask how to install those ^ above,
but I mean to ask how to set it up so that
when i run
composer create-project laravel/laravel projName
It automatically has those files/extensions/etc
created and/or installed

Just add maxhoffmann/parsedown-laravel in your composer.json file:
"require": {
"laravel/framework": "4.1.*", // version could be 4.2.*
"maxhoffmann/parsedown-laravel": "dev-master"
},
The Carbon package is already avaiable with Laravel by default. Also in app/config/app.php add another entry in providers array like this (Check details here):
'providers' => array(
// other entries...
'MaxHoffmann\Parsedown\ParsedownServiceProvider'
),
Also add an entry in aliases array like this:
'aliases' => array(
// other entries...
'Markdown' => 'MaxHoffmann\Parsedown\ParsedownFacade',
),
You said:
or additional folders in the root directory so I don't have to
re-create them each time.
It doesn't make any sense, sorry!.

If I'm understanding you correctly, you can load custom libraries and have them autoloaded via composers "autoload" section. How you actually load the code into you project is up to you. git submodules is a good option. I'm not familiar with the Laravel directory structure so replace the paths to something that fits:
{
"require": {
// requires go here
},
"require-dev": {
// require dev go here
},
"config": {
"bin-dir": "bin/"
},
"autoload": {
"psr-0" : {
"Carbon": "src/lib/Carbon/src",
"Carbon\\Test": "src/lib/Carbon/tests"
}
}
}

Probably best thing to do is install default Laravel, configure as you wish then save your default template on github... that way you can just do git clone url_to_your_template_repository?

Related

Composer - autoload classes in CodeIgniter outside vendor folder

I've been working on setting up a CodeIgniter project with composer. I'm wanting to include php classes stored in files outside the vendor folder - in a shared folder.
My directory structure:
/
--application/
--shared/
-application/
-class1.php
-class2.php
-class3.php
-base/
-classb1.php
--vendor/
--composer.json
--composer.lock
Looking at the composer documentation, I see there is an autoload property in the root package that I'm trying to use to load the classes in the shared directory. These classes aren't namespaced.
My composer.json file is as follows:
{
"description" : "The CodeIgniter Application with Composer",
"require": {
"php": ">=5.3.2",
"codeigniter/framework": "3.1.*"
},
"require-dev": {
"mikey179/vfsStream": "1.1.*"
},
"autoload":{
"psr-0":{
"":"shared/application/",
"":"shared/base/",
"":"shared/data/"
}
}
}
My search led me to this question, but the classes are still not being loaded. I've ran composer update on the terminal.
Well after looking further, there's a property called classmap (documentation) in the root package.
"autoload":{
"classmap":["shared/application/","shared/base/", "shared/data/"]
}
This loads all the required files in the folders.

How to set a different path for composer installer based on components inside a framework

I've been working on a PHP Framework development and we'd like to separate the components into individual packages from the core. Like this:
vendor /
username/frameworkname /
core/
Namespace /
Core /
..Framework core files here
components/
Namespace /
Component
ComponentOne
ClassOne.php
ClassTwo.php
composer.json
LICENSE.txt
README.md
ComponentTwo
ClassOne.php
ClassTwo.php
ClassThree.php
composer.json
README.md
LICENSE.txt
ComponentHopeYouFotIT!
Core being required by composer like this:
composer require name/framework-core
And be able to install it in
vendor/username/frameworkname/src/core/Namespace/Core/
And any component like this:
composer require name/componentname
And be able to install it in:
vendor/username/frameworkname/src/components/Namespace/Component/
So that we don't have to create a separate folder for any new component and could use like this:
use Namespace\Core\CoreClass;
use Namespace\Component\{
ComponentOne\ClassTwo,
ComponentTwo\ClassOne
};
It that possible?
I've personally have tried Composer composer/installers but couldn't figure out the correct settings in composer.json to do the trick.
"config": {
"vendor-dir": "vendor/username"
},
"repositories": [
{
"type": "package",
"package": {
"name": "frameworkname/componentname",
"version": "master",
"source": {
"url": "https://github.com/username/componentname",
"type": "git",
"reference": "master"
}
},
"require": {
"composer/installers": "~1.0"
}
}
],
Have you looked at the Composer Custom Installer documentation? It does this.
The tl;dr is that you need to create a (very simple) Composer plugin to set custom install locations, and the documentation walks you through it very specifically.
Aside: My sense, having experimented a bit with composer/installers, is that it may not support custom types, but might allow you to set custom paths for supported types. That is: if you wanted to use a WordPress plugin, but install it somewhere different than normal, you could override the install-paths, but you couldn't necessarily use composer/installers to define your own type whooptido-type with a custom install location. This inference is based, I strenuously underscore, on empirical experience experimenting with it this morning, rather than actual documentation. ;)

Installing PHP Github project on localhost using composer

I downloaded the Text-Statistics ZIP master from Github and extracted and renamed the folder to stats on /Library/WebServer/Documents/stats. Then I used cd /Library/WebServer/Documents/stats and composer update and all dependencies built on /Library/WebServer/Documents/stats as well. When I go to http://localhost/stats/ in my browser, it shows as follows:
This is my first time to install a project on my localhost directory which uses composer. Shall I create an index.php to see how the codes work? Below you can also see the composer.json file:
{
"name": "textstatistics",
"description": "PHP package to measure the readability of text according to various algorithms.",
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "4.2.*"
},
"autoload": {
"psr-0" : {
"DaveChild\\TextStatistics" : "src"
}
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"suggest": {
"ext-bcmath": "More accurate floating point calculations.",
"ext-mbstring": "Handle multi-byte text properly."
}
}
The package you 'installed' is a toolbox and meant to be used inside your project. It has no index.php since that would be useless, what would it have to show?
You should add it to an existing project by running composer require davechild/textstatistics from your project's root directory.
Composer exists so you do not have to download the package, and it's dependencies, yourself (like you did with the zip). It will also generate your autoload file so you do not have to bother about requiring or loading those classes. And it is especially useful when you want to update your dependencies (just run composer update)
This is completely unrelated to github or composer. It looks like this project is not a web application, because I don't see a bootstrap file (something like index.php). This means there is nothing which makes sense to call from a webserver context.
I took a short look at the projects github page. PHP Text Statistics is a library that will be used in other projects, but it's not a standalone tool, or application.

Composer require local package

I've got a couple of libraries [Foo and Bar] that I'm developing in concert, but are still technically separate things. Previously I've just re-defined the autoloader to like "Foo\\": "../Foo/src", but now that I've added a Guzzle dependency to Foo, Bar flips it's lid because it's not one of its dependencies.
Directory structure:
/home/user/src/
Foo/
src/
FooClient.php
composer.json
Bar/
src/
BarClient.php
composer.json
Theoretical Autoload Statement: [in Bar/composer.json]
"require": {
"local": "../Foo/composer.json"
}
Example code:
require('vendor/autoload.php');
$f = new \Bar\BarClient(new \Foo\FooClient());
How can I resolve this without setting up a local Composer repo? I want to maintain these as separate packages, just that one requires the other, and therefor processes the other's dependencies.
post-answer edit:
Thanks to infomaniac I've done the following:
Initialized the git repo:
cd ~/src/Foo && git init && echo -e "vendor\ncomposer.lock" > .gitignore && git add ./ && git commit -m "Initial Commit"
Added the composer config:
"require": {
"sammitch/foo": "dev-master"
},
"repositories": [{
"type": "vcs",
"url": "/home/sammitch/src/Foo"
}],
And then composer update!
The way to link to a local, in-development package is to first add in your main project's composer.json a repository, like this:
"repositories": [
{
"type": "path",
"url": "/full/or/relative/path/to/development/package"
}
]
You also need to either have a version specified in your development package's composer.json or the way I do it is to require the package using #dev, like this:
composer require "vendorname/packagename #dev"
It should output:
- Installing vendor/packagename (dev-develop)
Symlinked from /full/or/relative/path/to/development/package
The #dev in the require command is important, composer uses this to pickup the source code and symlink it to your new package.
It's a stability flag added to the version constraint (see package link).
These allow you to further restrict or expand the
stability of a package beyond the scope of the minimum-stability
setting.
The minimum-stability flags are:
Available options (in order of stability) are dev, alpha, beta, RC, and stable.
You can use Composer's repositories feature
https://getcomposer.org/doc/05-repositories.md#path
{
"repositories": [
{
"type": "path",
"url": "../../packages/my-package"
}
],
"require": {
"my/package": "*"
}
}
Instead of using the http format, specify a file path on disk.
After spending some time, I finally understood the solution. Maybe it'll be useful for someone like me and will save you some time, so I've decided that I have to share it here.
Assuming that you have the following directory structure (relative to your project root directory):
composer.json
config
config/composition-root.php
local
local/bar-project
local/bar-project/composer.json
local/bar-project/src
local/bar-project/src/Bar.php
public
public/index.php
src
src/Foo.php
In this example you may see that the local folder is meant for nested projects of your company, e.g. bar-project. But you could configure any other layout, if you wish.
Each project has to have its own composer.json file, e.g. root composer.json and local/bar-project/composer.json. Then their contents would be as follows:
(root composer.json:)
{
"name": "your-company/foo-project",
"require": {
"php": "^7",
"your-company/bar-project": "#dev"
},
"autoload": {
"psr-4": {
"YourCompany\\FooProject\\": "src/"
}
},
"repositories": [
{
"type": "path",
"url": "local/bar-project"
}
]
}
(local/bar-project/composer.json:)
{
"name": "your-company/bar-project",
"autoload": {
"psr-4": {
"YourCompany\\BarProject\\": "src/"
}
}
}
If, for example, you wish to locate each project in a separate sibling directory, as follows:
your-company
your-company/foo-project
your-company/foo-project/composer.json
your-company/foo-project/config
your-company/foo-project/config/composition-root.php
your-company/foo-project/public
your-company/foo-project/public/index.php
your-company/foo-project/src
your-company/foo-project/src/Foo.php
your-company/bar-project
your-company/bar-project/composer.json
your-company/bar-project/src
your-company/bar-project/src/Bar.php
- then you need to link to respective directory in repositories section:
"repositories": [
{
"type": "path",
"url": "../bar-project"
}
]
After that don't forget to composer update (or even rm -rf vendor && composer update -v as the docs suggest)!
Under the hood, composer will create a vendor/your-company/bar-project symlink that targets to local/bar-project (or ../bar-project respectively).
Assuming that your public/index.php is just a front controller, e.g.:
<?php
require_once __DIR__ . '/../config/composition-root.php';
Then your config/composition-root.php would be:
<?php
declare(strict_types=1);
use YourCompany\BarProject\Bar;
use YourCompany\FooProject\Foo;
require_once __DIR__ . '/../vendor/autoload.php';
$bar = new Bar();
$foo = new Foo($bar);
$foo->greet();
The command line way to do this is
composer config repositories.package_name local path/to/package
composer require group/package_name
If the group/package_name is available both from repository and local, the local version is used.
The local command can be replaced with vcs to reference a direct repository, or composer for default.

Composer, Laravel and local packages

My issue is I have a package which isn't a repository and I am trying to get it to play nice with Laravel and composer. It is still located under the vendor folder, the only issue is that if I simply set:
"psr-0": {
"Test\\Test": "vendor/test/test/src/"
}
This will load the service provider but none of the controllers etc will autoload. What is the correct way to implement a package with larval that does not have it's own repository. Or does this go against the nature of packages and this should simply be structured under the applications controllers.
The package was created by me using workbench but I found i did not really need this as a separate repository but it would still be good to keep it as a package. Therefore the structure is exactly the same as a regular package:
vendor
testvendor
testpackage
public
src
tests
.gitignore
composer.json
phpunit.xml
UPDATE:
As a solution for the time being I am using:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"vendor/package"
]
},
As an entry in the class map. Looking forward I will probably refactor this into the app folder or create a repository for this package.
If you have some classes that you're calling "package", you're not supposed to add those files to your vendor folder. This folder is managed by composer and at any time you might loose it. Create a subfolder in your application and put those files there.
You have to be sure your PSR-0 autoloading will work for every single file in your folder structure. So, if your root is vendor/test/test/src/ and your namespace is
Test\\Test
All your files must be in
vendor/test/test/src/Test/Test/ClassFileName.php
PSR-4 is easier to deal and understand, this
"psr-4": {
"Test\\Test\\": "vendor/test/test/src/"
}
Means that your files would have to be like:
vendor/test/test/src/ClassFileName.php
Doublecheck your namespaces. It's easy to make mistakes when using namespaces with PSR-0 and remember that
composer dump-autoload
Must be ran every time you change things in composer.json or create new files. If it's a simple class autoloading, every time you create a file, if it's a PSR-X autoloading, everytime you create or update a namespace in your composer.json file.
If what you have is is really a package you should use Composer: when your package is structured as a composer package (check Laravel's composer.json as an example), the correct way of adding it to your application, if it's not list in Packagist, is via repositories.
You can have (non-packagist) packages in a public VCS repository:
{
"require": {
"monolog/monolog": "dev-bugfix"
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/igorw/monolog"
}
]
}
You can have (non-packagist) packages in a protected by password VCS repository (git, bitbucket...):
{
"require": {
"vendor/my-private-repo": "dev-master"
},
"repositories": [
{
"type": "vcs",
"url": "git#bitbucket.org:vendor/my-private-repo.git"
}
]
}
You can have your packages zipped in your hard drive and load them via the artifact repository type:
"repositories": [
{
"type": "artifact",
"url": "path/to/directory/with/zips/"
}
],
Though #Antonio Carlos Ribeiro's answer is really nice, I had problem with installing custom packages locally(which is also stated in the last part of his answer)
Let's assume this is the directory structure of the package we are trying to install:
D:/test_pack
src/
composer.json
If you do not want to upload your custom package (that most likely you have developed, yourself) to online repositories you can use one of the following two methods:
Method I
(You have to specify version for your package, otherwise you'll get this error: The requested package could not be found in any version, there may be a typo in the package name.)
1) In composer.json, Add version to your package. your package's json should look something like this:
{
"name": "gandalf/test_pack",//This is your package's name
"description": "some desc",
"version": "1.0.0",//This is the version that you have to specify
"authors": [
{
"name": "gandalf the grey",
"email": "fake#yahoo.com"
}
],
"minimum-stability": "dev",
"require": {
"laravel/framework": "~5.4"
},
"autoload": {
"psr-4": {
"Gandalf\\BotPack\\": "src/"
}
} }
2) zip your package(let's assume the zip file is in D:/test_pack/test_packa.zip)
3) In laravel's composer.json add your package name (in our case gandalf/test_pack into require part of json) and add the repository array to the composer.json file and in that array specify the directory in which your package's zip file exists(in our case D:/test_pack) . like this
{
...,
"require": {//adding our package name to laravel's composer.json
...,
"gandalf/test_pack": "*"//package's name
},
...,
"repositories": [
{
"type": "artifact",
"url": "D:/test_pack"
}
]
}
Method II(My Favorite method, You have to initialize your package directory as git local repository using git init and then git add . and git commit -m "your message")
1) initialize the package directory as git directory and commit all your changes to the local repository
(let's say D:/test_pack is the directory that contains your package(src/ directory and composer.json))
go to D:/test_pack directory and run these commands
git init
git add .
git commit -m "your message for this commit"
2) In your packages composer.json file add minimum-stability
{
"name": "gandalf/test_pack",
"description": "some desc",
"authors": [
{
"name": "gandalf the grey",
"email": "fake#yahoo.com"
}
],
"minimum-stability": "dev",//setting minimum-stability
"require": {
//dependencies that your package needs
},
"autoload": {
"psr-4": {
"Gandalf\\BotPack\\": "src/"
}
}
}
3)In laravel's composer.json file require the "dev-master" of your package
{
...,
"require": {
...,//some dependencies that laravel needs
"gandalf/test_pack": "dev-master"//requiring dev-master from repository
},
"repositories": [
{
"type": "git",
"url": "D:/test_pack"//path of the local repository directory which contains your package
}
]
}
To any Laravel project load local packages. which is stored in your machine.
In laravel's (Project) composer.json file add
"autoload": {
"psr-4": {
"YourPackage\\Namespace\\": "./local_Package_path/src"
}
},
and fire command in Laravel Project directory
composer dump-autoload
Optional
If package is still not available in your Project. then
Register your package's Service Provider.
To register your service provider, you just need to add an entry to the array of service providers in the config/app.php file.
'providers' => [
/*
* Laravel Framework Service Providers...
*/
...
YourPackage\Namespace\PackageServiceProvider::class,
],
Hope now your package loaded successfully in your laravel project.

Categories