Symfony incompatibilities. The LoaderInterface and the XmlFileLoader have an issue - php

Situation:
This is the screen message I became after installing tikiwiki 24.
Fatal error: Declaration of Symfony\Component\DependencyInjection\Loader\XmlFileLoader::load($resource, ?string $type = NULL) must be compatible with Symfony\Component\Config\Loader\LoaderInterface::load($resource, $type = NULL) in /var/www/contiki/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php on line 46
So please, does anyone have a clue what's going on here? I'm quite new to composer, solved many compatibility issues but this is out of my range.
I don't understand why they are incompatible.
These are (part) of the files:
My /var/www/contiki/vendor_bundled/vendor/symfony/config/Loader/LoaderInterface.php
interface LoaderInterface
{
/**
* Loads a resource.
*
* #param mixed $resource The resource
* #param string|null $type The resource type or null if unknown
*
* #throws \Exception If something went wrong
*/
public function load($resource, $type = null);
/**
* Returns whether this class supports the given resource.
*
* #param mixed $resource A resource
* #param string|null $type The resource type or null if unknown
*
* #return bool True if this class supports the given resource, false otherwise
*/
public function supports($resource, $type = null);
/**
* Gets the loader resolver.
*
* #return LoaderResolverInterface A LoaderResolverInterface instance
*/
public function getResolver();
/**
* Sets the loader resolver.
*/
public function setResolver(LoaderResolverInterface $resolver);
}
The first part of the /var/www/contiki/vendor_bundled/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php file
namespace Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\Config\Util\XmlUtils;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\ExpressionLanguage\Expression;
/**
* XmlFileLoader loads XML files service definitions.
*
* #author Fabien Potencier <fabien#symfony.com>
*/
class XmlFileLoader extends FileLoader
{
const NS = 'http://symfony.com/schema/dic/services';
/**
* {#inheritdoc}
*/
public function load($resource, $type = null)
{
$path = $this->locator->locate($resource);
$xml = $this->parseFileToDOM($path);
$this->container->fileExists($path); <-- This is rule 46
$defaults = $this->getServiceDefaults($xml, $path);
// anonymous services
$this->processAnonymousServices($xml, $path, $defaults);
// imports
$this->parseImports($xml, $path);
// parameters
$this->parseParameters($xml, $path);
// extensions
$this->loadFromExtensions($xml);
// services
try {
$this->parseDefinitions($xml, $path, $defaults);
} finally {
$this->instanceof = [];
}
}```

Sounds like something's got tangled up here, Tiki 24 is not out yet but will be branching soon, so if you want a stable safe Tiki now, probably best to use a stable released branch, i.e. 23.x? Also, we are still on Smarty 3.x and plan to upgrade to 4.x (and PHP 8+) after the release of 24 which is our next LTS version, so not sure where that is coming from... did you run sh setup.sh?
As Nico said above, this is probably more Tiki-specific than is suitable for here, so the best thing would be to come and chat with the community in our new Gitter room, here?
Welcome to Tiki! :)

Related

Twig error on WebProfiler with Doctrine filter enable

I have a strange error with Twig and the WebProfiler when I enable a Doctrine filter.
request.CRITICAL: Uncaught PHP Exception Twig_Error_Runtime: "An exception has been thrown
during the rendering of a template ("Error when rendering "http://community.localhost:8000/
_profiler/e94abf?community_subdomain=community&panel=request" (Status code is 404).")." at
/../vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/
layout.html.twig line 103
This {{ render(path('_profiler_search_bar', request.query.all)) }} causes the error.
My doctrine filter allows to add filter constraint on some classes (multi tenant app with dynamic subdomains)
<?php
namespace AppBundle\Group\Community;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Query\Filter\SQLFilter;
/**
* Class CommunityAwareFilter
*/
class CommunityAwareFilter extends SQLFilter
{
/**
* Gets the SQL query part to add to a query.
*
* #param ClassMetadata $targetEntity
* #param string $targetTableAlias
*
* #return string The constraint SQL if there is available, empty string otherwise.
*/
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
{
if (!$targetEntity->reflClass->implementsInterface(CommunityAwareInterface::class)) {
return '';
}
return sprintf('%s.community_id = %s', $targetTableAlias, $this->getParameter('communityId')); // <-- error
// return ''; <-- no error
}
}
I have also extended Symfony Router to add subdomain placeholder automatically in routing.
Do you have any idea what can cause this ?
UPDATE
<?php
namespace AppBundle\Routing;
use AppBundle\Group\Community\CommunityResolver;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Bundle\FrameworkBundle\Routing\Router as BaseRouter;
class Router implements RouterInterface
{
/**
* #var BaseRouter
*/
private $router;
/**
* #var RequestStack
*/
private $request;
/**
* #var CommunityResolver
*/
private $communityResolver;
/**
* Router constructor.
*
* #param BaseRouter $router
* #param RequestStack $request
* #param CommunityResolver $communityResolver
*/
public function __construct(BaseRouter $router, RequestStack $request, CommunityResolver $communityResolver)
{
$this->router = $router;
$this->request = $request;
$this->communityResolver = $communityResolver;
}
/**
* Sets the request context.
*
* #param RequestContext $context The context
*/
public function setContext(RequestContext $context)
{
$this->router->setContext($context);
}
/**
* Gets the request context.
*
* #return RequestContext The context
*/
public function getContext()
{
return $this->router->getContext();
}
/**
* Gets the RouteCollection instance associated with this Router.
*
* #return RouteCollection A RouteCollection instance
*/
public function getRouteCollection()
{
return $this->router->getRouteCollection();
}
/**
* Tries to match a URL path with a set of routes.
*
* If the matcher can not find information, it must throw one of the exceptions documented
* below.
*
* #param string $pathinfo The path info to be parsed (raw format, i.e. not urldecoded)
*
* #return array An array of parameters
*
* #throws ResourceNotFoundException If the resource could not be found
* #throws MethodNotAllowedException If the resource was found but the request method is not allowed
*/
public function match($pathinfo)
{
return $this->router->match($pathinfo);
}
public function generate($name, $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)
{
if (null !== ($community = $this->communityResolver->getCommunity())) {
$parameters['community_subdomain'] = $community->getSubDomain();
}
return $this->router->generate($name, $parameters, $referenceType);
}
}
I found the solution, in fact I passed my "tenant" (here my "community") object in the Session like this (in a subscriber onKernelRequest)
if (null === ($session = $request->getSession())) {
$session = new Session();
$session->start();
$request->setSession($session);
}
$session->set('community', $community);
I changed to store this object in a service and it works. Maybe using the Session to store data is a bad practice.
I think your Symmfony Router override may cause the problem. Can you paste us the code ?

VariantView for TYPO3 8.7

There has been a solution for template variants, which allowed to set a suffix for a fluid template file used by an extbase controller. It was created by Peter Niederlag and was improved by Bastian Waidelich.
The solution is not working any longer in TYPO3 8.7 because the code has been refactored and the method expandGenericPathPattern in TemplateView does not exist anymore.
How should I implement such variant view in TYPO3 8.7?
$this->view->getRenderingContext()->setControllerAction('MyAction.Variant'); should do the trick (from any initializeAction method or within action method). Note that contrary to the view override class you linked to, this approach means you must have the original action template in the path.
I created the following classes in my extension, which implement the VariantView for TYPO3 8.7.
Classes\View\VariantView.php
<?php
namespace Vendor\Extkey\View;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Fluid\View\TemplateView;
/**
* Extended Fluid Template View that supports different "variants"
*
* #license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
*/
class VariantView extends TemplateView
{
/**
* #param string $layoutVariant
* #return void
*/
public function setLayoutVariant($layoutVariant)
{
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$this->baseRenderingContext->setTemplatePaths($objectManager->get(TemplatePaths::class));
/** #var TemplatePaths $templatePaths */
$templatePaths = $this->baseRenderingContext->getTemplatePaths();
$templatePaths->setLayoutVariant($layoutVariant);
}
const DEFAULT_LAYOUT_VARIANT = '.default';
}
Classes\View\TemplatePaths.php
<?php
namespace Vendor\Extkey\View;
class TemplatePaths extends \TYPO3\CMS\Fluid\View\TemplatePaths
{
/**
* Layout variant to use for this view.
*
* #var string
*/
protected $layoutVariant = VariantView::DEFAULT_LAYOUT_VARIANT;
/**
* #param string $layoutVariant
* #return void
*/
public function setLayoutVariant($layoutVariant)
{
$this->layoutVariant = $layoutVariant;
}
/**
* Wrapper for parent class method which adds layout variant in action parameter
*
* #param string $controller
* #param string $action
* #param string $format
* #return string|NULL
* #api
*/
public function resolveTemplateFileForControllerAndActionAndFormat($controller, $action, $format = self::DEFAULT_FORMAT)
{
$action = $action . $this->layoutVariant;
return parent::resolveTemplateFileForControllerAndActionAndFormat($controller, $action, $format = self::DEFAULT_FORMAT);
}
}
In your controller add the following lines:
protected function setViewConfiguration(\TYPO3\CMS\Extbase\Mvc\View\ViewInterface $view) {
parent::setViewConfiguration($view);
$view->setLayoutVariant($this->settings['layoutVariant']);
}

How to document usage of a method when called in an abstract form?

In a legacy project, I was confused when I tried finding the usage of a method in phpstorm and without success.
/**
* #param SomeEntity[] $someEntity
*
* #return bool
*/
protected function warmupSomeEntity(array $brandUniverses)
{
// I want to find this method's usage
}
Debugging a bit further, I found that the method is called on the fly in a rather abstract way via dynamic class method invocation:
/**
* #param string $warmer
* #param array $objects
*
* #throws RuntimeException
*/
public function warmupType($warmer, array $objects)
{
$method = "warmup$warmer";
if (method_exists($this, $
$this->{$method}($objects);
} else {
throw new RuntimeException("There is no warmer '$warmer'");
}
}
Is there a phpdoc syntax where I can document that the warmUpType method will call warmupSomeEntity, or warmupSomeOtherEntity so that I can find its usage again if I want to jump to the calling code block again?
The #uses keyword was what I was looking for as it:
Display a link to the documentation for an element, and create a backlink in the other element's documentation to this
It is supported by PhpStorm and the caller is found again.
/**
* #param string $warmer
* #param array $objects
* #uses warmupSomeEntity
* #uses warmupSomeOtherEntity
* #throws RuntimeException
*/
public function warmupType($warmer, array $objects)
{
...
}

Trouble loading PHP Class within the same project

Someone could help me on the issue of referencing php files within the same project (calling classes) using "namespace","use" ( php v5.3 or higher) [My Screenshoot][http://i.imgur.com/6GC4UUK.png?1]
Zoho\
CRM\
Common\
-HttpClientInterface.php
Config\
Entities\
Exception\
Request\
Wrapper\
index.php
I've read about autoloading classes but I don't undersand very well..
Fatal error: Class 'Zoho\CRM\Common\HttpClientInterface' not found in C:\root\zohocrm-master\src\Zoho\CRM\index.php on line 73
<?php namespace Zoho\CRM;
use Zoho\CRM\Common\HttpClientInterface;
use Zoho\CRM\Common\FactoryInterface;
use Zoho\CRM\Request\HttpClient;
use Zoho\CRM\Request\Factory;
use Zoho\CRM\Wrapper\Element;
.
.
.
public function __construct($authtoken, HttpClientInterface $client =null , FactoryInterface $factory = null )
{
$this->authtoken = $authtoken;
// Only XML format is supported for the time being
$this->format = 'xml';
$this->client = new HttpClientInterface();
$this->factory = $factory ;
$this->module = "Leads";
return $this;
}
This is my class file :
<?php namespace Zoho\CRM\Common;
/**
* Common interface for Http clients
*
* #package Zoho\CRM\Common
* #version 1.0.0
*/
interface HttpClientInterface
{
/**
* Performs POST request.
*
* #param string $uri Direction to make the post
* #param string $postBody Post data
*/
public function post($uri, $postBody);
}

Use Laravel 4 Encrypter within a namespace

I am trying to use Illuminate\Encryption\Encrypter; within a namespace which I created. The code really exists in my file.
Problem:
I want laravel to use the key set under 'app/config/app.php' automaticly. However the constructer wants me to set it properly with my hands.
To see how this task is handled by Taylor Otwell, I searched for an example and saw that under "Illuminate\Cache\DatabaseStore", it was set to $encrypter as an instance, using constructer. Tylor also uses a function to getEncrypter(); as follows:
/**
* Get the encrypter instance.
*
* #return \Illuminate\Encryption\Encrypter
*/
public function getEncrypter()
{
return $this->encrypter;
}
Because I want my class to be automaticly loaded with a function in another class; I can't use IoC Container.
Here are my functions and params:
/**
* The encrypter to be used for several reasons.
*/
protected $encrypter = "Illuminate\Encryption\Encrypter";
/**
* Returns the encrypter.
*
* #return Object
*/
public function getEncrypter()
{
return $this->createEncrypter();
}
/**
* Creates a new encrypter object.
*
* #param $string $encrypter
* #return Obj $encrypter instance
*/
public function createEncrypter()
{
$class = '\\'.ltrim($this->encrypter, '\\');
return new $class;
}
/**
* Sets the crypter used by MyFacadeName
*
* #param Encrypter $encrypter
*/
public function setEncrypter($encrypter)
{
$this->encrypter = $encrypter;
}
What is the difference makes the parser think that Taylor is right and I am wrong? What am I missing?
If you are on Laravel and you cannot access the Facades because they have not been loaded/initialized yet:
\Illuminate\Support\Facades\Config::get('app.key');
your last resort might be to access the $app via $GLOBALS:
public function createEncrypter()
{
$class = '\\'.ltrim($this->encrypter, '\\');
return new $class($GLOBALS['app']['config']->get('app.key'));
}

Categories