Jump to content

Use external library (without Composer?)


iipa
 Share

Recommended Posts

Hi fellow developers!

I want to implement following action:

  1. Admin-priviledged user uploads a spreadsheet file (with many sheets)
  2. When page is saved, back end generates repeater items from the sheets
  3. We can render spreadsheet data from the repeater field. Profit!

Currently I'm trying to find a way to read the uploaded spreadsheet file. ProcessWire doesn't seem to have modules suitable for my needs, but external PHP Library PhpSpreadsheet sounds like it could do the job. However, I can't even try it, because I simply don't understand how I can refer to an external library!

Folder structure:

  • templates
    • _func.php > where I want to refer to the library
    • libraries
      • PhpSpreadsheet
        • bunch of *.php > what I want to refer to

I have tried different things varying from their documentation to forum posts and PW API with no luck. I would prefer not to use Composer, since it seems kind of overkill for one library.

Thanks in advance and have a great day!

Link to comment
Share on other sites

Hi @iipa I am not familiar with PhpSpreadsheet, 🙄 but more generally speaking you can upload an external library calling a require_once() in profile ready.php or in site/config.php.

I load all my libraries from site/config.php calling a simple loader

/**
 * MRCMOD03: Add custom library Argo
 *
 */
include_once(__DIR__ . '/includes/Argo.php');

which load all my functions and class libraries (same as PW does in wire/core/boot.php file)

<?php namespace Argo;

$preloads = array(
    'argo/Functions.php',
    'argo/Object.php',
    'argo/Controller.php',
    'argo/Widget.php',
    'argo/WidgetTracker.php',
    'view/ContactForm.php',
    'view/CookieBanner.php',
    'view/FollowButtons.php',
    'view/RecentPosts.php',
    'view/ShareButtons.php',
    'view/LegalNotice.php',
    'controller/CookieController.php',
);

foreach($preloads as $file) {
	include_once(__DIR__ . '/' . $file);
}

unset($preloads);

As library will have different namespace than Processwire namespace, do not forget to apply "use" directive before using a library class or function in your template 🤪

use \Argo\ShareButtons;
...
$sb = new ShareButtons();

I hope you can find some hints with that.

  • Like 3
Link to comment
Share on other sites

re: Composer

It's like npm for PHP, and super-easy to use.

Some scripts out there require lots of dependencies, and they also check if your system meets all requirements. Downloading all dependent libraries yourself manually can be time-consuming.

You can install Composer locally, install your spreadsheet stuff, and then copy / FTP the generated vendor folder to site/wherever/. From there on, just make sure your include_once() points to the proper path, and follow the docs.

tl;dr: Composer is certainly not overkill 😉

  • Like 5
Link to comment
Share on other sites

18 minutes ago, iipa said:

Thanks @Edison, that was what I was asking 🙂 Although @elabx and @dragan have good points: Composer usage might be pretty handy, and good to learn.

I installed Composer, include_once() with correct path, but class cannot be found. Should I also put use [namespace]?

@iipa You need to use the correct namespace by either aliasing the class with the use statement, or by using a fully qualified class name. As others have said though, it's much easier to use Composer with it's autoloader, since you only need to include it once and all classes will be autoloaded. It's also better for performance, as only the classes you actually use get loaded for each request. If you need help setting up Composer and the autoloader, check out my tutorial on Composer + ProcessWire 🙂

  • Like 2
Link to comment
Share on other sites

Hi @iipa , I think so... 😀 Here is an example taken from PhpSpreadsheet documentation:

<?php

require 'vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Hello World !');

$writer = new Xlsx($spreadsheet);
$writer->save('hello world.xlsx');

Php "use" directive provide you an alias for the namespace, so thanks to that in the above example you can simply instantiate this class's library as:

$spreadsheet = new Spreadsheet();

Alternatively you could call the class with the fully qualified class name which includes both namespace and class:

$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();

Of course if you have several calls... the "use" directive avoids to keep repeating the fully qualified name each time. 😎

Without informing PHP about the namespace of your class or function, it will search for it inside Processwire namespace where not finding it will return an error. 😱

  • Like 2
Link to comment
Share on other sites

3 hours ago, iipa said:

I installed Composer, include_once() with correct path, but class cannot be found. Should I also put use [namespace]?

You don't need to include_once() if the vendor folder is in the ProcessWire installation root, it has loaded the libraries already, if i remember correctly the index.php of PW takes care of this.

I am also almost sure you also have to have the use statement like @Edison points in the examples.

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...