1

Magento 2.3.4 Enterprise cloud I need to upload a php file that I then can call into a phtml file . I am trying to use the below code but it seems to cause a 500 error

<?php 
   include($block->getViewFileUrl('Magento_Theme::barcode-generater.php'));
?>

I have ensured that my above php file is there and all I have right now is text in the file that says test (I will add my actual php code into the file once I know if works. not sure where else to put the php file and how to include is?? Thanks

1
  • why you need to use include the files in this way?
    – Amit Bera
    Commented Sep 1, 2021 at 5:50

1 Answer 1

2

I believe $block->getViewFileUrl() is meant for retrieving static asset url's for files like jpg, gif, css, etc...

Is it possible that you can rename your php file:

  • from: barcode-generater.php
  • to: barcode-generator.phtml

Phtml files are no different than Php files really. The both can contain php and can both output things like text/html.

If you can do that then your file is pretty much no different than a normal block, just needing a block class to wrap it for rendering. I think the following would work inside your template:

<?= $block
    ->getLayout()
    ->createBlock(\Magento\Framework\View\Element\Template::class)
    ->setTemplate('Magento_Theme::barcode-generater.phtml')
    ->toHtml();
?>

Down the Rabbit Hole

I've never tried to set a template using .php file extension, but after doing some digging, it looks like Magento uses Magento\Framework\View\TemplateEngineFactory to determine which file types it will handle (at least for block templates)

Template Engine Pool

In vendor/magento/module-ui/etc/di.xml:

    <type name="Magento\Framework\View\TemplateEngineFactory">
        <arguments>
            <argument name="engines" xsi:type="array">
                <item name="xhtml" xsi:type="string">Magento\Framework\View\TemplateEngine\Xhtml</item>
            </argument>
        </arguments>
    </type>

In vendor/magento/module-store/etc/di.xml:

    <type name="Magento\Framework\View\TemplateEngineFactory">
        <arguments>
            <argument name="engines" xsi:type="array">
                <item name="phtml" xsi:type="string">Magento\Framework\View\TemplateEngine\Php</item>
            </argument>
        </arguments>
    </type>

Rendering Template With Matched Template Engine

When trying to render a template, Magento uses the file extension to find a matching template engine to render the file.

In vendor/magento/framework/View/Element/Template.php:

    public function fetchView($fileName)
    {
        // ...omitted code

        if ($this->validator->isValid($fileName)) {
            $extension = pathinfo($fileName, PATHINFO_EXTENSION);
            $templateEngine = $this->templateEnginePool->get($extension);
            $html = $templateEngine->render($this->templateContext, $fileName, $this->_viewVars);
        
        // ...omitted code

Strategy 1 - Barcode Generation From Controller Action

Based on some of our convo in comments, I have a more sound idea for what you want. Here is a module example for you to check out. It is functional. Written for Magento 2.4.3:

IMPORTANT: I didn't add error trapping, scrub query parameter values, or validate that query parameters are correct for different barcode options.

Github - Barcode Generator Module

Barcode Image Generating Action

You can create a new controller action that will respond on a custom url like /barcode/barcode/generate.

You'll need to return the correct class though for Magento to treat it like file/image data output. I used a \Magento\Framework\Controller\Result\Raw result type.

I abstracted away some of the details into atomic classes for generating a Laminas barcode object and getting a string representation of the barcode image data:

<?php
declare(strict_types=1);

namespace Mogilabs\Barcode\Controller\Barcode;

use Mogilabs\Barcode\Api\Data\BarcodeOptionsInterface;
use Mogilabs\Barcode\Api\Data\BarcodeOptionsInterfaceFactory;
use Mogilabs\Barcode\Model\Barcode\GenerateInterface;
use Mogilabs\Barcode\Model\Barcode\GetImageStringInterface;
use Laminas\Barcode\Renderer\Image;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\Controller\ResultFactory;

class Generate implements HttpGetActionInterface
{
    private RequestInterface $request;
    private ResultFactory $resultFactory;
    private BarcodeOptionsInterfaceFactory $barcodeOptionsFactory;
    private GenerateInterface $generate;
    private GetImageStringInterface $getImageString;

    public function __construct(
        RequestInterface $request,
        ResultFactory $resultFactory,
        BarcodeOptionsInterfaceFactory $barcodeOptionsFactory,
        GenerateInterface $generate,
        GetImageStringInterface $getImageString
    ) {
        $this->request = $request;
        $this->resultFactory = $resultFactory;
        $this->barcodeOptionsFactory = $barcodeOptionsFactory;
        $this->generate = $generate;
        $this->getImageString = $getImageString;
    }

    /**
     * Returns raw response consisting of barcode image
     *
     * {@inheritDoc}
     */
    public function execute()
    {
        /** @var BarcodeOptionsInterface $barcodeOptions */
        $barcodeOptions = $this->barcodeOptionsFactory->create([
            'data' => $this->request->getParams()
        ]);

        /** @var Image $barcodeRenderer */
        $barcodeRenderer = $this->generate->execute($barcodeOptions);

        $imageString = $this->getImageString->execute($barcodeRenderer);

        $contentType = sprintf('image/%s', $barcodeRenderer->getImageType());

        return $this->resultFactory
            ->create(ResultFactory::TYPE_RAW)
            ->setContents($imageString)
            ->setHttpResponseCode(200)
            ->setHeader('Content-Type', $contentType);
    }
}

CMS Page Usage

Now all you need to do in a cms page is link to the custom url with query parameters:

Slash Delimited Query Parameter Pairs

<p>
  <img src="{{store url='barcode/barcode/generate/f/png/s/code39/d/12345'}}"/>
</p>

Traditional Query Parameters

<p>
  <img src="{{store url='barcode/barcode/generate?f=png&s=code39&d=12345'}}"/>
</p>

Frontend Result

Example of CMS Home Page With Barcode Image


Strategy 2 - Serve PHP Script Directly

For commerce cloud it should automatically be serving from pub. I've recently deployed a pub/info.php to see phpinfo() and I was able to hit the file, so I think this would work for you with the script:

Place PHP Script In Document Root

Place in: /app/[project_id]/pub/barcode-generator.php

CMS Page Usage

<p>
<img src="{{store direct_url='barcode-generator.php?f=png&s=code39&d=12345'}}" />
</p>
7
  • Trying to have a php file that is used to generate a barcode which I need to display on a specific cms page. So I have a tag like <img src='barcode.php?f=png&s=code39&d=12345'> That php file then takes the variables and creates a code39 based barcode with the value of 12345 (in this example) So my question is 1) where physically as in what folder should I put the php file which I think I can rename to phtml . Should I put it in Magento_Theme/templates folder . Second would I then link to it like <img src='<?php echo $block->getViewFileUrl();?>barcode.php?f=png&s=code39&d=12345'>
    – Jayreis
    Commented Sep 1, 2021 at 16:53
  • For this to work, your main cms page will need to be the url that receives the query parameters, and barcode.php should evolve a little into a block/view model/template combination. The view model can would have the Magento request class injected where you read those query params and do the barcode generation, then output to the template. Ill think of some other ways to achieve this too.
    – sdaugherty
    Commented Sep 1, 2021 at 17:10
  • Oh! I've got an idea. You can just turn your barcode generator script into a controller/action. Controller Actions are meant for entry points that receive query parameters anyway. Have it generate the barcode image data, then you would have to alter the return type to be image data (I can look into this), then from your cms page, all you are doing is linking to that controller action (/yourmodule/barcode/generate?f=png&s=code39&d=12345)
    – sdaugherty
    Commented Sep 1, 2021 at 17:21
  • I have to work a little, but let me know if you want some code examples for the controller/action solution. A recent site we just launched does on the fly image generation just like this.
    – sdaugherty
    Commented Sep 1, 2021 at 17:32
  • @Jayreis Alright you're either gonna love or hate me, but I've made an extension to share with ya that does the controller/action generation of barcodes. Will update answer
    – sdaugherty
    Commented Sep 3, 2021 at 8:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.