Jump to content
iipa

Use external library (without Composer?)

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!

Share this post


Link to post
Share on other sites

Why is composer an overkill? You are one command away from the library! The docs don't seem to offer the library as a package. 

  • Like 2

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

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]?

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By nuel
      Hi there
      Basically I want to call code within a ProcessWire page that isn't used as a template. Example: www.mypwpage.com/myphpfile.php
      I have a working PW Website with a couple of pages like /artists, /releases, /videos etc. Now I need a page /download without any editable fields in the backend, just calling some PHP code (that was coded by another guy) containing a form that checks unique download-codes in a second database and starts the download of the desired file. The script is working fine right now as part of a static website, but since I built PW behind the site, this independent «Download Section» of the page doesn't work anymore.
      Right now I have the main file download.php as a page template on a newly created empty page called /download, so until now the form is working (wow). After sending the form containing the download-code, the file check_code.php in a subfolder /site/templates/download is called and that's where I get an error.
      Any help?
    • By matsn0w
      Hey everyone, hope you're all doing well!
      I'm building my first ProcessWire website at the moment, which is of course a very good way to understand all of the possibilities ProcessWire has to offer. But that also means that I'm facing some troubles now and then, and so is the case right now.
      I made a template for a couple of pages, like the homepage, the contact page, etc. I am using Bootstrap 4.0 for the layout. 
      So here's the deal: I want to show an alert box on top of every page, warning the user that the website is still under construction. Of course, I can just include the code and add the fields I made for the alert into the template, but that means I have to do that for every page, which I obviously don't want. So I made a template with the code and fields for the alert. When I did this, I realised that I can create multiple alerts this way, so I made two pages, containing different alerts. (And converted the code into a foreach-loop in the template).
      But now my question; how can I include these pages in a different template? Can I make a field or something to insert a page or is this simply not possible? Or do I have to approach this in a different way?
      I hope I explained my problem clear!
      Thank you in advance,
      matsn0w
    • By modifiedcontent
      I have one central website, with membership registration and content etc., and then several related websites with their own URL/domains, each on Processwire, all on the same server.
      I would like to access the database of the central website from the sister websites. How would I do that?
      You can't bootstrap one PW installation into another. You can include template parts from one in the other by just using the server path, but whatever you try to get/post just comes/goes to the database of the site you are on.
      Could you switch databases by including the config.php from another PW installation somewhere?
      What is the correct, secure way to do this?
    • By SwimToWin
      I am using ProcessWire as the back-end to manage contents on multiple sites (I call them "sub-domains"). I use ProcessWire as an editing system and database only. The ProcessWire templating system is not in use. I want to use ProcessWire's API and in particular the Include & Bootstrap method to output contents -- pretty much in the same way you do, if contents is stored in a MySQL database and output in PHP files that use PDO to load data.
      The issue is that I cannot get ProcessWire to fully work on each of the "sub-domains".
      https://processwire.com/api/include/ says:
       
      > You can do anything with ProcessWire's API that you can do from a template,
      > so all of this still applies, as does everything in the developer API.
      How can I get access to variables such as $input when using Include & Bootstrap?
      I tried these:
      $wire->pages->get("/foo/bar/"); echo "Segment1: " . $wire->input->urlSegment1; # Returns null $wire->pages->get("/foo/bar/"); echo "Segment1: " . $wire->input()->urlSegment1; # Internal Server Error $p = $wire->pages->get("/foo/bar/"); echo "Segment1: " . $p->input->urlSegment1; # Returns null $p = $wire->pages->get("/foo/bar/"); echo "Segment1: " . $p->input()->urlSegment1; # Returns null @ryan Can the API Variables documentation be updated with a section / an example that explain how to use "Include & Bootstrap" for each variable (since this is a really strong feature in ProcessWire)?
      $page $pages - Example: $homepage = $wire->pages->get("/"); $input $sanitizer $session $fields $user $log $templates $config
    • By rocket
      Noob to Processwire. Trying to convert some older sites to Pwire. I am having trouble including a legacy form class into my templates:
      If I embed the php directly in the template, it works. But if I use include statements, the form object returns null.
      This works:
          use formbuild\Form;
          session_start();
          $form = new Form(init1, 'init2', ...');
          $form->param1 = ...;
          $form->param2 = ...;
          $form->param3 = ...;
       
          $form->render();
      -----------------------------------------------------------------------------------------
      This fails:
          include_once ($config->paths->templates."forms/form1.php");
          $form->render();
      ____________________________________________________________________
      My referencing is OK, no error message. The only code that cannot reside in the include file are the following lines:
          use formbuild\Form;
          $form = new Form(init1, 'init2', ...');
      My PhP is rusty, maybe that is the problem, but it could be something about Pwire, namespace maybe. I have tested it outside Pwire and no problems.
      Please advise. Thanks.
       
       
×
×
  • Create New...