简体   繁体   中英

TYPO3: ViewHelper cannot be found

I am currently facing a strange behaviour with TYPO3 8.7 . To be more precise, what I do doesn't work on my machine, but it works on other machines and in our QA environment.

I am building an extension where I need a simple ViewHelper . Unfortunately, every time I try to use my ViewHelper , I get the following exception:

#1407060572: Fluid parse error in template Default_action_Default_3595d4917583aa65277b432499e522ff39c573c7, line 48 at character 1. Error: The ViewHelper "<website:string.idFromTitle>" could not be resolved. Based on your spelling, the system would load the class "Domain\Website\ViewHelpers\String\IdFromTitleViewHelper", however this class does not exist. (error code 1407060572). Template source chunk: {title -> website:string.idFromTitle(string: '{title}') -> v:variable.set(name: 'targetId')} <div class="alternative-content-lightbox-fce"> <div class="header"> <a href="#" class="lightbox-trigger" data-target="{targetId}">{linkTitle}</a> <h1>{title}</h1> </div> <div class="main-content">

I am using TYPO3 in " Composer Mode " with a " composer.json " file at the root of the installation and a " composer.json " file for the specific extension. In the main " composer.json " file, I have the following lines:

"repositories": {
    "website": {
        "type": "path",
        "url": "sources/website",
        "options": {
            "symlink": true
        }
    },
    ...
}
...
"require": {
    "domain/website": "@dev",
}
...

So, the extension is set as local package.

The " composer.json " file of my extension contains the following line:

"autoload": {
    "psr-4": {
        "Domain\\Website\\": "Classes"
    }
}

In the " autoload_classmap.php " file, I can see the following line:

return array(
    'Domain\\Website\\ViewHelpers\\String\\IdFromTitleViewHelper' => $baseDir . '/Classes/ViewHelpers/String/IdFromTitleViewHelper.php'
);

The " autoload_static.php " file has the following line:

public static $classMap = array (
    'Domain\\Website\\ViewHelpers\\String\\IdFromTitleViewHelper' => __DIR__ . '/../..' . '/Classes/ViewHelpers/String/IdFromTitleViewHelper.php',
);

And finally, the " autoload_psr4.php " file contains the following line:

return array(
    'Domain\\Website\\' => array($baseDir . '/Classes'),
);

So, I guess my file is autoloaded. The ViewHelper can be found in the directory " Classes/ViewHelpers/String " and it looks like so:

<?php
namespace Domain\Website\ViewHelpers\String;

use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;

class IdFromTitleViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
{
    public function initialize()
    {
    }

    public function render($string)
    {
        $id = trim($string);
        $id = strtolower($id);
        $id = str_replace(' ', '', $id);
        $id = preg_replace('/[^A-Za-z0-9\-]/', '', $id);
        $id .= uniqid();

        return $id;
    }
}

When I use the ViewHelper , I do it like so:

xmlns:f="http://typo3.org/ns/TYPO3/Fluid/ViewHelpers"
f:schemaLocation="https://fluidtypo3.org/schemas/fluid-master.xsd"

xmlns:flux="http://typo3.org/ns/FluidTYPO3/Flux/ViewHelpers"
flux:schemaLocation="https://fluidtypo3.org/schemas/flux-master.xsd"

xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
v:schemaLocation="https://fluidtypo3.org/schemas/vhs-master.xsd"

xmlns:website="http://typo3.org/ns/Domain/Website/ViewHelpers"

data-namespace-typo3-fluid="true">

...

<f:section name="Main">

    {title -> website:string.idFromTitle(string: '{title}') -> v:variable.set(name: 'targetId')}

    <div class="alternative-content-lightbox-fce">
        <div class="header">
            <a href="#" class="lightbox-trigger" data-target="{targetId}">{linkTitle}</a>
            <h1>{title}</h1>
        </div>
        <div class="main-content">
            <f:format.html>{mainContent}</f:format.html> 
        </div>
        <div id="{targetId}" class="alternative-content">
            <f:format.html>{alternativeContent}</f:format.html> 
        </div>
    </div>

</f:section>

Unfortunately, it does not work on my machine, but it works elsewhere. And I have the same problem with any other ViewHelper placed in " Classes/ViewHelpers ", like if what is inside the " Classes " directory is ignored.

I checked my TYPO3 configuration, my php.ini file and my environment variables. I cleared the cache of TYPO3 and Composer a thousand times. I reinstalled TYPO3 completely. At first, I was using TYPO3 8.7.27 , so I updated my installation to 8.7.28 , but it did not change anything. I even swapped the database with another one, just in case.

My environment is a Windows 10 environment using Wamp 3.1.9 64bit and PHP 7.0.33 .

The other thing that I noticed is the following one: when I run a composer update , when it comes to my package, I get the following error:

[RuntimeException]
Package domain/website cannot install to "C:\wamp64\www\mysite\sources\website" inside its source at "C:\wamp64\www\mysite\sources\website"

I don't know if it is related, but it can give a hint. I thought of permissions problem, but everything seems to be fine.

We have the same setup for other projects and it works perfectly well, so I don't really get what I miss. Beside what is inside the " Classes " directory, everything works fine.

Another thing I spotted, as it was suggested by Claus Due down below, is I get an error saying the class is not found if I try to do something like so:

use Domain\Website\ViewHelpers\String;
$foo = new IdFromTitleViewHelper();
print_r($foo);

However, it works if I do the following thing (for example):

include __DIR__ .'/../../../Classes/ViewHelpers/String/IdFromTitleViewHelper.php';
$foo = new Domain\Website\ViewHelpers\String\IdFromTitleViewHelper();
print_r($foo);

I also noticed that my extension is completely missing in the files " autoload_classmap.php ", " autoload_psr4.php " and " autoload_static.php " at the root of the installation (" ./vendor/composer "). Even if I composer dump-autoload -o , it does not appear. It is also not referenced in the " installed.json " file and in the " composer.lock " file.

Does anyone have a clue about this problem? Any help would be much appreciated.

Many thanks in advance.

Best regards,

SOLUTION

Just because I was desperate, I tried to redo

rm -rf vendor
rm -rf htdocs\typo3conf\ext
composer clearcache
composer install

for the nth time and... problem solved!

It might be a problem with case sensitive file systems - since it works on other machines but not your own. If the class is listed, and the filename is correct, and the file can be loaded - then the ViewHelper should of course resolve.

There is no special processing happening in order to load the class, TYPO3 relies completely on composer class loading when in compose mode. However, the expected class name is generated based on the "uri" (ns identifier, not a real uri) you provide.

You could perhaps confirm this by checking if the class can be loaded elsewhere if you specify the class name explicitly. If that fails, the cause is clear: somehow, your class file is not loading or the class within has a wrong namespace or class name.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM