In this case, I need composer to look two folders above the current Laravel project.
Now run composer update to install the package into your project.
Whats good about this approach is you can do this with third-party packages. This is useful as you can run tests and add features that you plan to raise pull requests for.
I tend to build packages from scratch or copy one of my existing packages and remove what I dont need.
In this post, I’m imagining building a package called laravel-tags.
The folder structure will be:
license.md
For the license, I use The MIT licence which allows users to freely use, copy, modify, merge, publish, distribute, sublicense, and sell the software and its associated documentation.
this file contains:
# The license
The MIT License (MIT)
Copyright (c) 2023 dcblogdev
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
composer.json
I’ll start by adding a composer.json file that contains:
Breaking this down, first, the package needs a name in the convention of vendor name and package name dcblogdev/laravel-tags in my case the vendor name is dcblogdev and package name is laravel-tags
Add a require section if your package has dependencies
In a require-dev section, I import these third-party packages for development only
testbench package allows you to use Laravel conventions for testing.
Inside autoload to any folders that you want composer to autoload. I have a folder called src which will contain the classes and tests for all the tests
One important aspect of this package name I’ll often give the package a nickname to use so instead of using laravel-tags I’ll use tags
I’ll do this by using Tags in any classes namespace and creating an alias:
The methods getEnviromentSetup and defineDatabaseMigrations are not needed by default. They are only required if you need to use a database and load migrations.
Inside getPackageProviders the main package service provider is loaded.
Now create a file called Pest.php
in( __DIR__ );
This file calls a uses() function to load the tests case I’ll use __DIR__ inside the in() method to make Pest use the TestCase class in the root of this directory.
Inside the package root create a phpunit.xml file containing:
src/./tests
This sets the location for tests to read from, it’s rare this file will need to be changed from this default.
I set an APP_KEY as standard for running tests, its value is not important.
Pint
To setup find create a folder in the package root called pint.json I use the Laravel preset:
{
"preset": "laravel"
}
ReadMe
inside the project root create a file called readme.md to document the project, I typically use this format:
# Laravel Tags
Explain what the package does.
# Documentation and install instructions
[https://dcblog.dev/docs/laravel-tags](https://dcblog.dev/docs/laravel-tags)
## Change log
Please see the [changelog][3] for more information on what has changed recently.
## Contributing
Contributions are welcome and will be fully credited.
Contributions are accepted via Pull Requests on [Github][4].
## Pull Requests
- **Document any change in behaviour** - Make sure the `readme.md` and any other relevant documentation are kept up-to-date.
- **Consider our release cycle** - We try to follow [SemVer v2.0.0][5]. Randomly breaking public APIs is not an option.
- **One pull request per feature** - If you want to do more than one thing, send multiple pull requests.
## Security
If you discover any security related issues, please email dave@dcblog.dev email instead of using the issue tracker.
## License
license. Please see the [license file][6] for more information.
ServiceProvider
Inside src create the service provider in my case TagsServiceProvider.php
configurePublishing();
}
public function configurePublishing(): void
{
if (! $this->app->runningInConsole()) {
return;
}
$this->publishes([
__DIR__.'/../config/tags.php' => config_path('tags.php'),
], 'config');
}
public function register(): void
{
$this->mergeConfigFrom( __DIR__.'/../config/tags.php', 'tags');
// Register the service the package provides.
$this->app->singleton('tags', function () {
return new Tags;
});
}
public function provides(): array
{
return ['tags'];
}
}
Inside the boot function set called to other methods, to begin with I only have one called configurePublishing This will publish any files defined in this page and will only run when the class is ran from a CLI
The register method allows a published config file to be merged in with a local ./config/tags.php config file
And set up the main class to be instantiated.
Facades
If you want to make use of facade ie have static called to a class that would normally be instantiated.
Inside src create a folder called facades and your class such as Tags.php
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept All”, you consent to the use of ALL the cookies. However, you may visit "Cookie Settings" to provide a controlled consent.
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. These cookies ensure basic functionalities and security features of the website, anonymously.
Cookie
Duration
Description
cookielawinfo-checkbox-analytics
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Analytics".
cookielawinfo-checkbox-functional
11 months
The cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional".
cookielawinfo-checkbox-necessary
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookies is used to store the user consent for the cookies in the category "Necessary".
cookielawinfo-checkbox-others
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Other.
cookielawinfo-checkbox-performance
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Performance".
viewed_cookie_policy
11 months
The cookie is set by the GDPR Cookie Consent plugin and is used to store whether or not user has consented to the use of cookies. It does not store any personal data.
Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.
Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.
Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.
Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.