Getting errors working with a third-party library (Class not found)

#1

So I would like to use a third-party library (Cloudinary for PHP) in a new plugin. I have looked at quite a few other plugins that include third-party libraries in one way or another, and I get the feeling that this should be pretty simple. But I’m also pretty sure that I’m missing some key bits of understanding here, because I can’t get it to work. This is what I’ve got so far:

File structure:

user/plugins/cloudinary/
user/plugins/cloudinary/vendor/cloudinary_php/

The latter contains the library as a git submodule.
Then in my cloudinary.php file, I include it like this:

require_once(__DIR__.'/vendor/autoload.php');

This file was created by running composer.phar install in the plugin’s directory, after adding the library to composer.json. (Apparently this also created another directory with the third-party code in user/plugins/cloudinary/vendor/cloudinary/cloudinary_php/.)

However, upon doing $test = new Cloudinary('fat_bunny'); in cloudinary.php, I get a Crikey error that says "Class 'Grav\Plugin\Cloudinary' not found". If I include the autoload.php file that’s in the submodule directory:

require_once(__DIR__.'/vendor/cloudinary_php/autoload.php');

the Crikey error says:

"cloudinary_autoloader(): Failed opening required '/home/anna/toolkit/grav-cloudinary/user/plugins/cloudinary/vendor/cloudinary_php/src/Grav\Plugin\Cloudinary.php' (include_path='.:/usr/share/php')

I think a blow-by-blow account of how exactly to get Composer stuff included in Grav would definitely help me out, but I haven’t found one yet, so I intend to fumble my way through this and then write it up :slight_smile: So can someone point me in the right direction please? What am I not getting here? And generally speaking, which is the better way to go: get the library as a submodule from Git, or install it with Composer? And how do people get it when they install the plugin then?!

#2

maybe you just forgot to explicitly use the namespace from your external class in the new() statement ?
(I did just the same recently in my project icalendar , use an external composer bundle, which is added via ‘composer install’).

#3

I’d like to see some comprehensive documentation on this as well. Maybe we can sort it out together and then write the docs :slight_smile:

I’m taking my clues from the Instagram plugin https://github.com/artifex404/grav-plugin-instagram

1 Like
#4

… Man, that was IT! Thank you so much. I went and read up on namespaces as I realised I didn’t quite understand the whole concept, and a tiny little backslash fixed it:

$test = new \Cloudinary('fat_bunny');

What I still don’t really understand though is this whole Composer thing. I mean… I remember installing it globally early on in my Grav adventures, but I don’t remember exactly why. Do I understand that correctly that Grav comes shipped with its own local Composer installation…? Which is why plugins that require third-party libraries to be installed via Composer can be automatically installed, so no end user has to do extra Composer installs?!

I mean if I am getting this right, then someone could download and unzip Grav and then proceed to install any plugin whatsoever with GPM, and never do a composer install once. Is that right…?? :sweat_smile:

#5

Yes indeed, let’s totally do that. Including all the tiny stumbling blocks that most people don’t trip over… :slight_smile:

I’m now making progress again with the plugin, and the errors I’m currently getting are Cloudinary-code related, so they have no real place here. I think all I would need to explain the process of including Composer-installable third-party libraries in a Grav plugin is a better understanding of the role Composer plays in Grav and GPM (see my answer to hoernerfranz).

#6

ok, fine to read my proposal worked :grinning:
as for the composer explanation, there is a lot of documentation out there on the web, as composer is a quasi standard package manager for php bundles.
I don’t think it makes much sense to include (and thus duplicate) all this in the grav documentation, maybe just some useful links.
@douglas: yes, looking at existing projects which do similar things as the ones intended is always a good idea - I’m doing this all the time, too :wink:

#7

I’m going to dig deeper into how PSR autoloading works. That’s the stumbling block for me. Namespacing and ‘use’ all make sense to me. It’s just that I see several different ways in which autoloading is implemented. In Drupal, I’ve never had to explicitly load the autoloader inside my custom modules, but I see this pattern in Grav plugins:

// Autoload composer components
    require __DIR__ . '/vendor/autoload.php';

So I need to do some research on why that is.

#8

If you have any links to explanations of my questions regarding when and why somebody needs to run composer install in the case of third-party libraries etc. (see above), please post them and I will read them ALL. Because I didn’t find anything anywhere.

I do feel that another slightly more detailed example in the cookbook section of the Grav docs wouldn’t go amiss, if only to make it easier for newbies like me to get into making plugins.

Yes that is a good idea! Please post it here if you find a helpful explanation, I’m absolutely interested.

(Btw the Cloudinary plugin has a first release now and it works and I’m just so chuffed. :smiling_face_with_three_hearts: Thanks again for your help!)