Class not being autoloaded - php

I've made a little library for myself and I'm trying to autoload it into my laravel project, it installs fine but whenever I try to use the class it simply says it's not found.
I've checked all the classmap files in vendor/composer and it doesn't seem to be in any of them.
This is my composer.json for my lib:
{
"name": "my-user/aspect-parser",
"version": "1.0.0",
"type": "package",
"require": {
"nesbot/carbon": "^1.22"
},
"autoload": {
"psr-4": {
"AspectParser\\": "src/"
}
}
}
My file structure is:
AspectParser
src
Parser.php

It was an issue with the type in composer.json. I've changed it to library and it adds to the autoload classmap.

Related

Composer Override a package file

I am trying to override a package file, as it doesn't work without modification and it hasn't been updated to fix this.
Package is webklex\laravel-pdfmerger and the file is PDFMerger.php
In it has:
use fpdi\FPDI;
for it to work correctly it needs to be:
use FPDI;
Obviously whenever I update using composer, this file is of course then incorrect, and at this stage I have to manually go in and change the file to get it working.
There must be a better way?
I've attempted making a copy of the git package, and then using composer to import it and attempt to override, composer snippet is below, but it doesn't do what I want it to do.
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"type": "project",
"repositories": {
"laravel-pdfmerger": {
"type": "package",
"package": {
"name": "****/laravel-pdfmerger-mirror",
"version": "1.1.1",
"source": {
"url": "https://bitbucket.org/****/laravel-pdfmerger-mirror.git",
"type": "git",
"reference": "origin/master"
}
}
}
},
"require": {
...
"****/laravel-pdfmerger-mirror": "1.1.1",
"webklex/laravel-pdfmerger": "1.1"
},
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/",
"VendorExtensions\\xerolaravel\\": "packages/vendorExtensions/xerolaravel",
"Webklex\\PDFMerger\\PDFMerger\\": "vendor/****/laravel-pdfmerger-mirror/src/PDFMerger"
}
},
Any help here would be great.
--- EDIT ---
updated my composer.json file to remove the repository and change the psr-4 autoload to the following:
psr-4": {
"App\\": "app/",
"VendorExtensions\\xerolaravel\\": "packages/vendorExtensions/xerolaravel",
"Webklex\\laravel-pdfmerger\\PDFMerger\\": "vendor/webklex/laravel-pdfmerger/src/PDFMerger"
}
But it is still not overriding the original file whenever I do use PDFMerger. Is it because I'm using a Facade?
Figured this one out at last...
1) Import Forked respository in your composer.json file, but ensure the name matches the name of the package you are replacing; in my case webklex/laravel-pdfmerger, like so:
"repositories": {
"webklex/laravel-pdfmerger": {
"type": "package",
"package": {
"name": "webklex/laravel-pdfmerger",
"version": "1.1.1",
"source": {
"url": "url to git",
"type": "git",
"reference": "origin/master"
}
}
}
},
Note: Ensure you set a version higher than what is currently available on the original package, so here I added .1 to differentiate the change and tag the commit as this so I can select it.
2) require the package, but ensure you request the version you tagged in your commit:
"require": {
"php": ">=5.6.4",
"webklex/laravel-pdfmerger": "1.1.1"
},
3) Update the autoload to point to where the package has been imported:
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/",
"Webklex\\PDFMerger\\": "vendor/webklex/laravel-pdfmerger/src"
}
},
Run composer update and then dump the autoload.
You should then be able to reference the package in your application as per the instructions in the original package.
You can do this by putting your edited package in a vendor-custom directory and adding it to the autoload section of your composer.json.
"autoload": {
"psr-4": {
"App\\": "app/",
"Vendor\\Package": "vendor-custom/vendor/package"
}
},
Gregwar psr-0 example:
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
},
"psr-0": {
"Gregwar\\Cache": "vendor-custom/gregwar/cache",
"Gregwar\\Image": "vendor-custom/gregwar/image",
"Gregwar\\ImageBundle": "vendor-custom/gregwar/image-bundle"
}
},
In PHP, you can actually alias a class to another, and that behaviour include namespaces.
This is extremely useful in legacy projects where you want to start using namespaces but don't want to refactor all usage of the said class.
You have the opposite here, the class is defined in a namespace but the class you are using is not in a namespace, still, aliasing the class would do.
So the function you might be looking for is class_alias.
Here is an example
<?php
class FPDI {
public function __construct() {
var_dump('I am FPDI');
}
}
class_alias('FPDI', 'fpdi\FPDI');
$noNamespace = new FPDI; // would, off course work
$namespace = new fpdi\FPDI(); // would work too, thanks to the class alias
So if you are using Laravel, your job should be as simple as aliasing the class correctly.
This can actually be done where you define your providers and aliases.
So at the beginning of config/app.php
<?php
class_alias('FPDI', 'fpdi\FPDI');
return [
// all of the below array stays as you have it, it was just snipped for concision purpose
];

Private repo composer.json not being used

My problem is that a privately made repo's composer.json seems to be broken when trying to use it as a package elsewhere.
I have a private repo with code needed for other projects. The repo's composer.json looks like this:
{
"name": "somevendor/global",
"require": {
"nesbot/carbon": "^1.21"
},
"autoload": {
"psr-4": {
"" : "src/"
},
"files": [
"somedir/somefile.php"
]
}
}
The src is in the base directory of the repo, and contains PSR-4 namespaced classes. I have namespace folders within that, e.g. a Foo directory with classes in the Foo namespace:
-- src
-- Foo
// some Foo\... classes
// some global namespace classes
-- somedir
somefile.php // A file with helper functions
In the project folder, I'm accessing the somevendor/global repo via a composer.json file:
{
"require": {
"somevendor/global-folder": "dev-master"
},
"repositories": [
{
"type": "package",
"package": {
"name": "somevendor/global",
"version": "dev-master",
"type": "package",
"source": {
"url": "git#bitbucket.org/somevendor/global.git",
"type": "git",
"reference": "master"
}
}
}
]
}
Running composer install in the project folder seems to work at first. I have installed SSH keys properly so it can access the private repo on Bitbucket and grab the files:
$ composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Installing somevendor/global (dev-master master)
Cloning master
Writing lock file
Generating autoload files
And then in the project's PHP code I require vendor/autoload.php, but none of the classes are being autoloaded, including the Carbon package specified in the first repo's composer.json file:
Fatal error: Uncaught Error: Class 'Foo\Foo' not found in...
I've clearly made a mistake here, have I structured the first repo wrongly?
I "solved" this by taking out all of the "require" entries from the remote repo's composer.json file and moving them to the local website's composer.json file.
This is what the files looked like:
The remote private repo's composer.json:
{
"name": "somevendor/global",
"license": "proprietary",
"autoload": {
"psr-4": {
"" : "src/"
},
"files": [
"functions/functions.php"
]
}
}
The local website's composer.json:
{
"require": {
"nesbot/carbon": "^1.21",
"somevendor/global": "dev-master"
},
"repositories": [
{
"type": "vcs",
"url": "git#bitbucket.org:somevendor/global.git"
}
]
}
It kept throwing Composer\Repository\InvalidRepositoryException because I forgot to put the name into the remote repo's composer.json file, so don't forget that bit!
Also remember to set up your git ssh keys if you've set them up. I used this Bitbucket tutorial to do this.

How to autoload a repository in composer which does not follow PSR-0 or PSR-4?

So, I'm trying to use jcleblanc/reddit-php-sdk, but it follows no standards whatsoever and does not have a repository available, so I've had to manually define it myself in my composer.json file:
"repositories" : [{
"type": "package",
"package": {
"name": "jcleblanc/reddit-php-sdk",
"version": "dev-master",
"source": {
"url": "https://github.com/jcleblanc/reddit-php-sdk",
"type": "git",
"reference": "origin/master"
},
"autoload": {
"classmap": ["reddit-php-sdk/", "/", "reddit.php", "config.php"]
}
}
}],
Directory structure in vendor/ here:
However, when I then run composer dump-autoload, the classes in this project are not autoloaded, and don't appear in any of the autoload_*.php composer files. This means I of course get a "Class 'reddit' not found" error whenever I try and use it.
Solutions?
You can use Composer's file autoloading.
{
"autoload": {
"files": ["src/MyLibrary/functions.php"]
}
}
However, that's more geared towards helper function files and I've not tried it with a Class file (although there's no reason it shouldn't work).
Ended up forking the project myself, but it turns out the original project is broken anyway.

Composer not composing - saying file not found

I'm using the excellent phpwkhtmltopdf library and want to update to latest version and for this I need to use composer.
File structure:
vendor
--mikehaertl
--php-shellcommand
--php-tmpfile
autoload.php
Composer.json file:
{
"name": "mikehaertl/phpwkhtmltopdf",
"description": "A slim PHP wrapper around wkhtmltopdf with an easy to use and clean OOP interface",
"keywords": ["pdf", "wkhtmltopdf", "wkhtmltoimage" ],
"homepage": "http://mikehaertl.github.com/phpwkhtmltopdf/",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Michael Haertl",
"email": "haertl.mike#gmail.com"
}
],
"require": {
"php": ">=5.0.0",
"mikehaertl/php-tmpfile": "1.0.*",
"mikehaertl/php-shellcommand": "1.0.*"
},
"autoload": {
"psr-4": {
"mikehaertl\\wkhtmlto\\": "src/"
}
},
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
}
}
I'm trying to use the library like this:
require '/home/bookmark/vendor/autoload.php';
use mikehaertl\wkhtmlto\Pdf;
...
$pdf = new Pdf('http://anysite.com'); <-- error points to this line
The problem is I get the error:
Fatal error: Class 'mikehaertl\wkhtmlto\Pdf' not found in /home/bookmark/public_html/ajax/action.php on line 132
This is my first time using composer, any idea what I'm doing wrong?
If you are using some package, you must not copy their composer.json file - that won't work.
The best thing would be to run composer init once to create an initial composer.json file for your project, and composer require mikehaertl/phpwkhtmltopdf:~2.0 to add this package you want to work with.
After that, it should work.

Composer package class not found

I'm trying to create a composer package but I'm getting a class not found error. I'm using Laravel 4 but I'm trying to create a generic PHP package.
I created the package in my vendor/ directory.
vendor/
theninthnode/
defaqto/
src/
Defaqto.php
vendor/
composer.json
Here is my composer.json file
{
"name": "theninthnode/defaqto",
"description": "",
"authors": [
{
"name": "Billy Jones",
"email": "billyjones26#gmail.com"
}
],
"minimum-stability": "dev",
"require": {
"php": ">=5.3.0"
},
"autoload": {
"classmap": ["src"]
}
}
And my class:
<?php
class Defaqto
{
....
}
When I try to call the package class from my app like so
$defaqto = new Defaqto();
I just get
Class 'Defaqto' not found
I've tried composer dump-autoload from within my package and also my applications root.
I also tried adding theninthnode/defaqto to my root composer.json file.
Am I missing something?

Categories