This question already has answers here:
PHP parse/syntax errors; and how to solve them
(20 answers)
Closed 3 years ago.
I'm setting solarium in my codigniter web application. And create test query. It shows
A PHP Error was encountered
Severity: Warning
Message: Cannot modify header information - headers already sent by (output started at C:\wamp\www\solarium\application\vendor\solarium\solarium\src\Core\Client\Request.php:309)
Filename: core/Common.php
Line Number: 570
Backtrace:
And
A PHP Error was encountered
Severity: Parsing Error
Message: syntax error, unexpected ':', expecting ';' or '{'
Filename: Client/Request.php
Line Number: 309
Backtrace:
I enclose my file in below
<?php
namespace Solarium\Core\Client;
use Solarium\Component\RequestBuilder\RequestParamsInterface;
use Solarium\Component\RequestBuilder\RequestParamsTrait;
use Solarium\Core\Configurable;
use Solarium\Exception\RuntimeException;
/**
* Class for describing a request.
*/
class Request extends Configurable implements RequestParamsInterface
{
use RequestParamsTrait;
/**
* Request GET method.
*/
const METHOD_GET = 'GET';
/**
* Request POST method.
*/
const METHOD_POST = 'POST';
/**
* Request HEAD method.
*/
const METHOD_HEAD = 'HEAD';
/**
* Request DELETE method.
*/
const METHOD_DELETE = 'DELETE';
/**
* Request PUT method.
*/
const METHOD_PUT = 'PUT';
/**
* Default options.
*
* #var array
*/
protected $options = [
'method' => self::METHOD_GET,
];
/**
* Request headers.
*/
protected $headers = [];
/**
* Raw POST data.
*
* #var string
*/
protected $rawData;
/**
* Magic method enables a object to be transformed to a string.
*
* Get a summary showing significant variables in the object
* note: uri resource is decoded for readability
*
* #return string
*/
public function __toString()
{
$output = __CLASS__.'::__toString'."\n".'method: '.$this->getMethod()."\n".'header: '.print_r($this->getHeaders(), 1).'authentication: '.print_r($this->getAuthentication(), 1).'resource: '.$this->getUri()."\n".'resource urldecoded: '.urldecode($this->getUri())."\n".'raw data: '.$this->getRawData()."\n".'file upload: '.$this->getFileUpload()."\n";
return $output;
}
/**
* Set request handler.
*
* #param string $handler
*
* #return self Provides fluent interface
*/
public function setHandler($handler)
{
$this->setOption('handler', $handler);
return $this;
}
/**
* Get request handler.
*
* #return string
*/
public function getHandler()
{
return $this->getOption('handler');
}
/**
* Set request method.
*
* Use one of the constants as value
*
* #param string $method
*
* #return self Provides fluent interface
*/
public function setMethod($method)
{
$this->setOption('method', $method);
return $this;
}
/**
* Get request method.
*
* #return string
*/
public function getMethod()
{
return $this->getOption('method');
}
/**
* Get raw POST data.
*
* #return string
*/
public function getRawData()
{
return $this->rawData;
}
/**
* Set raw POST data.
*
* This string must be safely encoded.
*
* #param string $data
*
* #return self Provides fluent interface
*/
public function setRawData($data)
{
$this->rawData = $data;
return $this;
}
/**
* Get the file to upload via "multipart/form-data" POST request.
*
* #return string|null
*/
public function getFileUpload()
{
return $this->getOption('file');
}
/**
* Set the file to upload via "multipart/form-data" POST request.
*
*
* #param string $filename Name of file to upload
*
* #throws RuntimeException
*
* #return self
*/
public function setFileUpload($filename)
{
if (!is_file($filename) || !is_readable($filename)) {
throw new RuntimeException("Unable to read file '{$filename}' for upload");
}
$this->setOption('file', $filename);
return $this;
}
/**
* Get all request headers.
*
* #return array
*/
public function getHeaders()
{
return $this->headers;
}
/**
* Set request headers.
*
* #param array $headers
*
* #return self Provides fluent interface
*/
public function setHeaders($headers)
{
$this->clearHeaders();
$this->addHeaders($headers);
return $this;
}
/**
* Add a request header.
*
* #param string|array $value
*
* #return self Provides fluent interface
*/
public function addHeader($value)
{
$this->headers[] = $value;
return $this;
}
/**
* Add multiple headers to the request.
*
* #param array $headers
*
* #return self Provides fluent interface
*/
public function addHeaders($headers)
{
foreach ($headers as $header) {
$this->addHeader($header);
}
return $this;
}
/**
* Clear all request headers.
*
* #return self Provides fluent interface
*/
public function clearHeaders()
{
$this->headers = [];
return $this;
}
/**
* Get an URI for this request.
*
* #return string
*/
public function getUri()
{
return $this->getHandler().'?'.$this->getQueryString();
}
/**
* Set HTTP basic auth settings.
*
* If one or both values are NULL authentication will be disabled
*
* #param string $username
* #param string $password
*
* #return self Provides fluent interface
*/
public function setAuthentication($username, $password)
{
$this->setOption('username', $username);
$this->setOption('password', $password);
return $this;
}
/**
* Get HTTP basic auth settings.
*
* #return array
*/
public function getAuthentication()
{
return [
'username' => $this->getOption('username'),
'password' => $this->getOption('password'),
];
}
/**
* Execute a request outside of the core context in the global solr context.
*
* #param bool $isServerRequest
*/
public function setIsServerRequest($isServerRequest = false)
{
$this->setOption('isserverrequest', $isServerRequest);
}
/**
* Indicates if a request is core independent and could be executed outside a core context.
* By default a Request is not core independent and must be executed in the context of a core.
*
* #return bool
*/
public function getIsServerRequest(): bool
{
return $this->getOption('isserverrequest') ?? false;
}
/**
* Initialization hook.
*/
protected function init()
{
foreach ($this->options as $name => $value) {
switch ($name) {
case 'rawdata':
$this->setRawData($value);
break;
case 'file':
$this->setFileUpload($value);
break;
case 'param':
$this->setParams($value);
break;
case 'header':
$this->setHeaders($value);
break;
case 'authentication':
if (isset($value['username']) && isset($value['password'])) {
$this->setAuthentication($value['username'], $value['password']);
}
}
}
}
/**
* #return string
*/
public function getHash()
{
return spl_object_hash($this);
}
}
I didn't know how to solve this problem.
With the latter issue, you're running PHP 7.0+ code with a version of PHP that is less than 7.0.
With PHP 7.0 came the support of function type hinting, IE:
public function getIsServerRequest(): bool
This states that the function getIsServerRequest will return a boolean, either true or false.
Make sure that you're running the correct version of PHP.
This may also solve the first issue once you have fixed the latter issue.
I am trying to mention a property of my class somewhere else in other comments of my class, ie. in a method of that class.
For example if we have this code:
(please search for: property $mention -- #property Village::mention does not work)
class Village {
/**
* #var array Data container.
*/
public $data = [];
/**
*
*/
public $mention = 'Me';
/**
* Village constructor which injects data.
*
* #param $data
*/
public function __construct($data) {
$this->data = $data;
}
/**
* A factory for our Villages.
*
* #return Village
*/
public static function hillbilly() {
return new Village;
}
/**
* Name tells the story...
*
* Now somewhere at this exact point I want to mention the
* $mention property -- #property Village::mention does not work
* nor does #property $mention either...
*
* #return array Rednecks unset.
*/
public function redneck() {
if(sizeof($data)) {
unset($data);
}
return $data;
}
}
$countryside = [
'important' => 'data',
'axe' => 'knifes',
'shovel' => 'hoe',
'trowel' => 'mixer',
];
$village = Village::hillbilly($countryside);
How do I make a mention of a property in PHPDoc?
If you need to have the $mention in the docblock text, one would usually use the inline see {#see element description}:
/**
* Name tells the story...
*
* Now somewhere at this exact point I want to mention the
* {#see Village::$mention} property.
*
* #return array Rednecks unset.
* #see Village::$mention
* #uses Village::$mention
*/
public function redneck() {
if(sizeof($data)) {
unset($data);
}
return $data;
}
The #see or #uses standalone tags are also available, but not for embedding the link into the docblock narrative text.
Note that older phpDocumentor only allowed the inlink link tag {#link url|element description}.
I have looked for other results for this case but couldn't fix it myself. I would be thankful if someone can help me with replacing this preg_replace with preg_replace_callback
preg_replace("/[-_]([a-z])/e", "ucfirst('\\1')", ucwords($verb));
<?php
/** #see Zang_Exception **/
require_once 'Exception.php';
/** #see Zang_Schemas **/
require_once 'Schemas.php';
/**
*
* A Zang InboundXML wrapper.
*
* Please consult the online documentation for more details.
* Online documentation can be found at: http://www.zang.io/docs/api/inboundxml/
*
* --------------------------------------------------------------------------------
*
* #category Zang Wrapper
* #package Zang
* #author Nevio Vesic <nevio#zang.io>
* #license http://creativecommons.org/licenses/MIT/ MIT
* #copyright (2012) Zang, Inc. <support#zang.io>
*/
class Zang_InboundXML
{
/**
* InboundXML simple xml element container
*
* #var null|SimpleXmlElement
*/
protected $element;
/**
* Current child pointer. Used for nesting validations
*
* #var string|null
*/
protected $_currentChild = null;
/**
* Constructs a InboundXML response.
*
* #param SimpleXmlElement|array $arg:
* - the element to wrap
* - attributes to add to the element
* - if null, initialize an empty element named 'Response'
*/
public function __construct($arg = null) {
switch (true) {
case $arg instanceof SimpleXmlElement:
$this->element = $arg;
$this->_currentChild = strtolower($arg->getName());
break;
case $arg === null:
$this->element = new SimpleXmlElement('<Response/>');
$this->_currentChild = 'response';
break;
case is_array($arg):
$this->element = new SimpleXmlElement('<Response/>');
$this->_currentChild = 'response';
foreach ($arg as $name => $value) {
$this->_validateAttribute($name, 'response');
$this->element->addAttribute($name, $value);
}
break;
default: throw new Zang_Exception('InboundXML Invalid construction argument');
}
}
/**
* Converts method calls into InboundXML verbs.
*
* #return SimpleXmlElement A SimpleXmlElement
*/
public function __call($verb, array $args) {
/** convert verbs input like-this-one to LikeThisOne **/
$verb = preg_replace("/[-_]([a-z])/e", "ucfirst('\\1')", ucwords($verb));
/** Let's first go check if the verb exists **/
$this->_validateVerb(ucfirst($verb));
/** Let's go validate nesting **/
$this->_validateNesting(ucfirst($verb));
list($noun, $attrs) = $args + array('', array());
if (is_array($noun)) list($attrs, $noun) = array($noun, '');
$child = empty($noun)
? $this->element->addChild(ucfirst($verb))
: $this->element->addChild(ucfirst($verb), $noun);
foreach ($attrs as $name => $value) {
/** Validation of verb attributes **/
$this->_validateAttribute($name, $verb);
$child->addAttribute($name, $value);
}
return new self($child);
}
/**
* Returns the object as XML.
*
* #return string The response as an XML string
*/
public function __toString() {
$xml = $this->element->asXml();
return str_replace(
'<?xml version="1.0" ?>',
'<?xml version="1.0" encoding="UTF-8" ?>',
$xml
);
}
/**
* Validate existance of the verb. Return true if exists, throw exception
* if fails.
*
* #param string $verb
* #throws Zang_Exception
* #return bool
*/
private function _validateVerb($verb) {
$schemas = Zang_Schemas::getInstance();
if(!$schemas->isVerb(ucfirst($verb))) {
$available_verbs = implode(', ', $schemas->getAvailableVerbs());
throw new Zang_Exception(
"Verb '{$verb}' is not a valid InboundXML verb. Available verbs are: '{$available_verbs}'"
);
}
return true;
}
/**
* Validate if previous child allows this verb to be its child.
*
* #param string $verb
* #return boolean
* #throws Zang_Exception
*/
private function _validateNesting($verb) {
$schemas = Zang_Schemas::getInstance();
if(!$schemas->isNestingAllowed(ucfirst($this->_currentChild), ucfirst($verb))) {
$nestable_verbs = implode(', ', $schemas->getNestableByVerbs(ucfirst($this->_currentChild)));
$current_verb = ucfirst($this->_currentChild);
$next_verb = ucfirst($verb);
throw new Zang_Exception(
"InboundXML element '{$current_verb}' does not support '{$next_verb}' element. The following elements are supported: '{$nestable_verbs}'."
);
}
return true;
}
/**
* Validate if attribute of verb exists. If not, throw exception, otherwise, return true.
*
* #param string $attr
* #param string $verb
* #return boolean
* #throws Zang_Exception
*/
private function _validateAttribute($attr, $verb) {
$schemas = Zang_Schemas::getInstance();
if(!$schemas->isValidAttribute($attr, ucfirst($verb))) {
$verb_attribuges = implode(', ', $schemas->getAvailableAttributes(ucfirst($verb)));
throw new Zang_Exception(
"Attribute '{$attr}' does not exist for verb '{$verb}'. Available attributes are: '{$verb_attribuges}'"
);
}
return true;
}
}
It is a bit unclear why you want to use another function. It might be this is because you are upgrading php and the e modifier is not supported any more. And the example code you posted suggest that you are trying to turn hyphen and underscore concatenated expressions into camel case...
Take a look at this simple demonstration:
<?php
$verb = 'this is a simple-test_sentence to convert.';
echo preg_replace_callback(
"/[-_]([a-z]+)/",
function($string) { return ucfirst($string[1]); },
ucwords($verb)
);
The output obviously is:
This Is A SimpleTestSentence To Convert.
I set up an local TYPO3 7.2 environment with xampp.
The installation works fine and everything else too.
At the beginning I installed the FluidTYPO3 site kickstarter distribution because I wanted to work with FLUID there. The distribution created all extensions needed for that (vhs, flux, fluidpages, fluidcontent) and then I created my provider extension with the builder.
It also created 4 pages or 1 page and 3 subpages. As I wanted to rename them I got the following error/exception:
PHP Warning: file_get_contents(): Filename cannot be empty in F:\xampp\htdocs\src\typo3_src-7.2.0\typo3\sysext\fluid\Classes\View\TemplateView.php line 318
I tried to var_dump() that in that file but it didn't help. I get the correct path and filename on other modules but not on the "page"-module where the error appeared. I can not rename, delete or edit the pages.
It seems that something is null there, mh.
Later I saw that the extensions were not for my TYPO3 version 7.2, only for 6.2.99 I think. So I deinstalled all extensions and downloaded the development extensions from Github (https://github.com/FluidTYPO3).
I installed them with an error that my version is too high. The extensions are only for 7.1.99. I thought that it would not be a problem and it should work with it anyway.
As I tested it there was the same error again, again and again.
I don't know where the problem is. Everything works fine on 6.x installations.
Could that be a bug or did I forget something?
PHP Version: 5.6.3 /
TYPO3 Version: 7.2
Would be very nice if anyone knows about the problem or could help me to solve it. I don't know which information is needed. Feel free to ask if something is needed.
<?php
namespace TYPO3\CMS\Fluid\View;
/* *
* This script is backported from the TYPO3 Flow package "TYPO3.Fluid". *
* *
* It is free software; you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License, either version 3 *
* of the License, or (at your option) any later version. *
* *
* The TYPO3 project - inspiring people to share! *
* */
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Fluid\Compatibility\TemplateParserBuilder;
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3\CMS\Fluid\Fluid;
/**
* The main template view. Should be used as view if you want Fluid Templating
*
* #api
*/
class TemplateView extends AbstractTemplateView {
/**
* Pattern to be resolved for "#templateRoot" in the other patterns.
* Following placeholders are supported:
* - "#packageResourcesPath"
*
* #var string
*/
protected $templateRootPathPattern = '#packageResourcesPath/Private/Templates';
/**
* Pattern to be resolved for "#partialRoot" in the other patterns.
* Following placeholders are supported:
* - "#packageResourcesPath"
*
* #var string
*/
protected $partialRootPathPattern = '#packageResourcesPath/Private/Partials';
/**
* Pattern to be resolved for "#layoutRoot" in the other patterns.
* Following placeholders are supported:
* - "#packageResourcesPath"
*
* #var string
*/
protected $layoutRootPathPattern = '#packageResourcesPath/Private/Layouts';
/**
* Path(s) to the template root. If NULL, then $this->templateRootPathPattern will be used.
*
* #var array
*/
protected $templateRootPaths = NULL;
/**
* Path(s) to the partial root. If NULL, then $this->partialRootPathPattern will be used.
*
* #var array
*/
protected $partialRootPaths = NULL;
/**
* Path(s) to the layout root. If NULL, then $this->layoutRootPathPattern will be used.
*
* #var array
*/
protected $layoutRootPaths = NULL;
/**
* File pattern for resolving the template file
* Following placeholders are supported:
* - "#templateRoot"
* - "#partialRoot"
* - "#layoutRoot"
* - "#subpackage"
* - "#action"
* - "#format"
*
* #var string
*/
protected $templatePathAndFilenamePattern = '#templateRoot/#subpackage/#controller/#action.#format';
/**
* Directory pattern for global partials. Not part of the public API, should not be changed for now.
* Following placeholders are supported:
* - "#templateRoot"
* - "#partialRoot"
* - "#layoutRoot"
* - "#subpackage"
* - "#partial"
* - "#format"
*
* #var string
*/
private $partialPathAndFilenamePattern = '#partialRoot/#subpackage/#partial.#format';
/**
* File pattern for resolving the layout
* Following placeholders are supported:
* - "#templateRoot"
* - "#partialRoot"
* - "#layoutRoot"
* - "#subpackage"
* - "#layout"
* - "#format"
*
* #var string
*/
protected $layoutPathAndFilenamePattern = '#layoutRoot/#layout.#format';
/**
* Path and filename of the template file. If set, overrides the templatePathAndFilenamePattern
*
* #var string
*/
protected $templatePathAndFilename = NULL;
/**
* Path and filename of the layout file. If set, overrides the layoutPathAndFilenamePattern
*
* #var string
*/
protected $layoutPathAndFilename = NULL;
/**
* Constructor
*/
public function __construct() {
$this->templateParser = TemplateParserBuilder::build();
$this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$this->setRenderingContext($this->objectManager->get(RenderingContextInterface::class));
}
/**
* Init view
*/
public function initializeView() {
}
// Here, the backporter can insert a constructor method, which is needed for the TYPO3 CMS extension
/**
* Sets the path and name of of the template file. Effectively overrides the
* dynamic resolving of a template file.
*
* #param string $templatePathAndFilename Template file path
* #return void
* #api
*/
public function setTemplatePathAndFilename($templatePathAndFilename) {
$this->templatePathAndFilename = $templatePathAndFilename;
}
/**
* Sets the path and name of the layout file. Overrides the dynamic resolving of the layout file.
*
* #param string $layoutPathAndFilename Path and filename of the layout file
* #return void
* #api
*/
public function setLayoutPathAndFilename($layoutPathAndFilename) {
$this->layoutPathAndFilename = $layoutPathAndFilename;
}
/**
* Set the root path to the templates.
* If set, overrides the one determined from $this->templateRootPathPattern
*
* #param string $templateRootPath Root path to the templates. If set, overrides the one determined from $this->templateRootPathPattern
* #return void
* #api
* #see setTemplateRootPaths()
*/
public function setTemplateRootPath($templateRootPath) {
$this->setTemplateRootPaths(array($templateRootPath));
}
/**
* Resolves the template root to be used inside other paths.
*
* #return array Path(s) to template root directory
*/
public function getTemplateRootPaths() {
if ($this->templateRootPaths !== NULL) {
return $this->templateRootPaths;
}
/** #var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
$actionRequest = $this->controllerContext->getRequest();
return array(str_replace('#packageResourcesPath', ExtensionManagementUtility::extPath($actionRequest->getControllerExtensionKey()) . 'Resources/', $this->templateRootPathPattern));
}
/**
* Set the root path(s) to the templates.
* If set, overrides the one determined from $this->templateRootPathPattern
*
* #param array $templateRootPaths Root path(s) to the templates. If set, overrides the one determined from $this->templateRootPathPattern
* #return void
* #api
*/
public function setTemplateRootPaths(array $templateRootPaths) {
$this->templateRootPaths = $templateRootPaths;
}
/**
* Set the root path to the partials.
* If set, overrides the one determined from $this->partialRootPathPattern
*
* #param string $partialRootPath Root path to the partials. If set, overrides the one determined from $this->partialRootPathPattern
* #return void
* #api
* #see setPartialRootPaths()
*/
public function setPartialRootPath($partialRootPath) {
$this->setPartialRootPaths(array($partialRootPath));
}
/**
* Set the root path(s) to the partials.
* If set, overrides the one determined from $this->partialRootPathPattern
*
* #param array $partialRootPaths Root paths to the partials. If set, overrides the one determined from $this->partialRootPathPattern
* #return void
* #api
*/
public function setPartialRootPaths(array $partialRootPaths) {
$this->partialRootPaths = $partialRootPaths;
}
/**
* Resolves the partial root to be used inside other paths.
*
* #return array Path(s) to partial root directory
*/
protected function getPartialRootPaths() {
if ($this->partialRootPaths !== NULL) {
return $this->partialRootPaths;
}
/** #var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
$actionRequest = $this->controllerContext->getRequest();
return array(str_replace('#packageResourcesPath', ExtensionManagementUtility::extPath($actionRequest->getControllerExtensionKey()) . 'Resources/', $this->partialRootPathPattern));
}
/**
* Set the root path to the layouts.
* If set, overrides the one determined from $this->layoutRootPathPattern
*
* #param string $layoutRootPath Root path to the layouts. If set, overrides the one determined from $this->layoutRootPathPattern
* #return void
* #api
* #see setLayoutRootPaths()
*/
public function setLayoutRootPath($layoutRootPath) {
$this->setLayoutRootPaths(array($layoutRootPath));
}
/**
* Set the root path(s) to the layouts.
* If set, overrides the one determined from $this->layoutRootPathPattern
*
* #param array $layoutRootPaths Root path to the layouts. If set, overrides the one determined from $this->layoutRootPathPattern
* #return void
* #api
*/
public function setLayoutRootPaths(array $layoutRootPaths) {
$this->layoutRootPaths = $layoutRootPaths;
}
/**
* Resolves the layout root to be used inside other paths.
*
* #return string Path(s) to layout root directory
*/
protected function getLayoutRootPaths() {
if ($this->layoutRootPaths !== NULL) {
return $this->layoutRootPaths;
}
/** #var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
$actionRequest = $this->controllerContext->getRequest();
return array(str_replace('#packageResourcesPath', ExtensionManagementUtility::extPath($actionRequest->getControllerExtensionKey()) . 'Resources/', $this->layoutRootPathPattern));
}
/**
* Returns a unique identifier for the resolved template file
* This identifier is based on the template path and last modification date
*
* #param string $actionName Name of the action. If NULL, will be taken from request.
* #return string template identifier
*/
protected function getTemplateIdentifier($actionName = NULL) {
$templatePathAndFilename = $this->getTemplatePathAndFilename($actionName);
if ($actionName === NULL) {
/** #var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
$actionRequest = $this->controllerContext->getRequest();
$actionName = $actionRequest->getControllerActionName();
}
$prefix = 'action_' . $actionName;
return $this->createIdentifierForFile($templatePathAndFilename, $prefix);
}
/**
* Resolve the template path and filename for the given action. If $actionName
* is NULL, looks into the current request.
*
* #param string $actionName Name of the action. If NULL, will be taken from request.
* #return string Full path to template
* #throws Exception\InvalidTemplateResourceException
*/
protected function getTemplateSource($actionName = NULL) {
$templatePathAndFilename = $this->getTemplatePathAndFilename($actionName);
$templateSource = file_get_contents($templatePathAndFilename);
if ($templateSource === FALSE) {
throw new Exception\InvalidTemplateResourceException('"' . $templatePathAndFilename . '" is not a valid template resource URI.', 1257246929);
}
return $templateSource;
}
/**
* Resolve the template path and filename for the given action. If $actionName
* is NULL, looks into the current request.
*
* #param string $actionName Name of the action. If NULL, will be taken from request.
* #return string Full path to template
* #throws Exception\InvalidTemplateResourceException
*/
protected function getTemplatePathAndFilename($actionName = NULL) {
if ($this->templatePathAndFilename !== NULL) {
return $this->resolveFileNamePath($this->templatePathAndFilename);
}
if ($actionName === NULL) {
/* #var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
$actionRequest = $this->controllerContext->getRequest();
$actionName = $actionRequest->getControllerActionName();
}
$paths = $this->expandGenericPathPattern($this->templatePathAndFilenamePattern, FALSE, FALSE);
$possibleFileNames = $this->buildListOfTemplateCandidates($actionName, $paths, '#action');
foreach ($possibleFileNames as $templatePathAndFilename) {
if ($this->testFileExistence($templatePathAndFilename)) {
return $templatePathAndFilename;
}
}
throw new Exception\InvalidTemplateResourceException('Template could not be loaded. I tried "' . implode('", "', $possibleFileNames) . '"', 1225709595);
}
/**
* Returns a unique identifier for the resolved layout file.
* This identifier is based on the template path and last modification date
*
* #param string $layoutName The name of the layout
* #return string layout identifier
*/
protected function getLayoutIdentifier($layoutName = 'Default') {
$layoutPathAndFilename = $this->getLayoutPathAndFilename($layoutName);
$prefix = 'layout_' . $layoutName;
return $this->createIdentifierForFile($layoutPathAndFilename, $prefix);
}
/**
* Resolve the path and file name of the layout file, based on
* $this->layoutPathAndFilename and $this->layoutPathAndFilenamePattern.
*
* In case a layout has already been set with setLayoutPathAndFilename(),
* this method returns that path, otherwise a path and filename will be
* resolved using the layoutPathAndFilenamePattern.
*
* #param string $layoutName Name of the layout to use. If none given, use "Default"
* #return string contents of the layout template
* #throws Exception\InvalidTemplateResourceException
*/
protected function getLayoutSource($layoutName = 'Default') {
$layoutPathAndFilename = $this->getLayoutPathAndFilename($layoutName);
$layoutSource = file_get_contents($layoutPathAndFilename);
if ($layoutSource === FALSE) {
throw new Exception\InvalidTemplateResourceException('"' . $layoutPathAndFilename . '" is not a valid template resource URI.', 1257246930);
}
return $layoutSource;
}
/**
* Resolve the path and file name of the layout file, based on
* $this->layoutPathAndFilename and $this->layoutPathAndFilenamePattern.
*
* In case a layout has already been set with setLayoutPathAndFilename(),
* this method returns that path, otherwise a path and filename will be
* resolved using the layoutPathAndFilenamePattern.
*
* #param string $layoutName Name of the layout to use. If none given, use "Default"
* #return string Path and filename of layout files
* #throws Exception\InvalidTemplateResourceException
*/
protected function getLayoutPathAndFilename($layoutName = 'Default') {
if ($this->layoutPathAndFilename !== NULL) {
return $this->resolveFileNamePath($this->layoutPathAndFilename);
}
$paths = $this->expandGenericPathPattern($this->layoutPathAndFilenamePattern, TRUE, TRUE);
$possibleFileNames = $this->buildListOfTemplateCandidates($layoutName, $paths, '#layout');
foreach ($possibleFileNames as $layoutPathAndFilename) {
if ($this->testFileExistence($layoutPathAndFilename)) {
return $layoutPathAndFilename;
}
}
throw new Exception\InvalidTemplateResourceException('The layout files "' . implode('", "', $possibleFileNames) . '" could not be loaded.', 1225709596);
}
/**
* Returns a unique identifier for the resolved partial file.
* This identifier is based on the template path and last modification date
*
* #param string $partialName The name of the partial
* #return string partial identifier
*/
protected function getPartialIdentifier($partialName) {
$partialPathAndFilename = $this->getPartialPathAndFilename($partialName);
$prefix = 'partial_' . $partialName;
return $this->createIdentifierForFile($partialPathAndFilename, $prefix);
}
/**
* Figures out which partial to use.
*
* #param string $partialName The name of the partial
* #return string contents of the partial template
* #throws Exception\InvalidTemplateResourceException
*/
protected function getPartialSource($partialName) {
$partialPathAndFilename = $this->getPartialPathAndFilename($partialName);
$partialSource = file_get_contents($partialPathAndFilename);
if ($partialSource === FALSE) {
throw new Exception\InvalidTemplateResourceException('"' . $partialPathAndFilename . '" is not a valid template resource URI.', 1257246931);
}
return $partialSource;
}
/**
* Resolve the partial path and filename based on $this->partialPathAndFilenamePattern.
*
* #param string $partialName The name of the partial
* #return string the full path which should be used. The path definitely exists.
* #throws Exception\InvalidTemplateResourceException
*/
protected function getPartialPathAndFilename($partialName) {
$paths = $this->expandGenericPathPattern($this->partialPathAndFilenamePattern, TRUE, TRUE);
$possibleFileNames = $this->buildListOfTemplateCandidates($partialName, $paths, '#partial');
foreach ($possibleFileNames as $partialPathAndFilename) {
if ($this->testFileExistence($partialPathAndFilename)) {
return $partialPathAndFilename;
}
}
throw new Exception\InvalidTemplateResourceException('The partial files "' . implode('", "', $possibleFileNames) . '" could not be loaded.', 1225709597);
}
/**
* Builds a list of possible candidates for a given template name
*
* #param string $templateName
* #param array $paths Paths to search in
* #param string $marker Marker to replace in the $templateName
* #return array Array of paths to search for the template file
*/
protected function buildListOfTemplateCandidates($templateName, $paths, $marker) {
$upperCasedTemplateName = $this->ucFileNameInPath($templateName);
$possibleFileNames = array();
foreach ($paths as $partialPathAndFilename) {
$possibleFileNames[] = $this->resolveFileNamePath(str_replace($marker, $upperCasedTemplateName, $partialPathAndFilename));
if ($templateName !== $upperCasedTemplateName) {
$possibleFileNames[] = $this->resolveFileNamePath(str_replace($marker, $templateName, $partialPathAndFilename));
}
}
return $possibleFileNames;
}
/**
* Checks whether a template can be resolved for the current request context.
*
* #param ControllerContext $controllerContext Controller context which is available inside the view
* #return bool
* #api
*/
public function canRender(ControllerContext $controllerContext) {
$this->setControllerContext($controllerContext);
try {
$this->getTemplateSource();
return TRUE;
} catch (Exception\InvalidTemplateResourceException $e) {
return FALSE;
}
}
/**
* Processes following placeholders inside $pattern:
* - "#templateRoot"
* - "#partialRoot"
* - "#layoutRoot"
* - "#subpackage"
* - "#controller"
* - "#format"
*
* This method is used to generate "fallback chains" for file system locations where a certain Partial can reside.
*
* If $bubbleControllerAndSubpackage is FALSE and $formatIsOptional is FALSE, then the resulting array will only have one element
* with all the above placeholders replaced.
*
* If you set $bubbleControllerAndSubpackage to TRUE, then you will get an array with potentially many elements:
* The first element of the array is like above. The second element has the # controller part set to "" (the empty string)
* The third element now has the # controller part again stripped off, and has the last subpackage part stripped off as well.
* This continues until both "#subpackage" and "#controller" are empty.
*
* Example for $bubbleControllerAndSubpackage is TRUE, we have the Tx_MyExtension_MySubPackage_Controller_MyController
* as Controller Object Name and the current format is "html"
*
* If pattern is "#templateRoot/#subpackage/#controller/#action.#format", then the resulting array is:
* - "Resources/Private/Templates/MySubPackage/My/#action.html"
* - "Resources/Private/Templates/MySubPackage/#action.html"
* - "Resources/Private/Templates/#action.html"
*
* If you set $formatIsOptional to TRUE, then for any of the above arrays, every element will be duplicated - once with "#format"
* replaced by the current request format, and once with ."#format" stripped off.
*
* #param string $pattern Pattern to be resolved
* #param bool $bubbleControllerAndSubpackage if TRUE, then we successively split off parts from "#controller" and "#subpackage" until both are empty.
* #param bool $formatIsOptional if TRUE, then half of the resulting strings will have ."#format" stripped off, and the other half will have it.
* #return array unix style paths
*/
protected function expandGenericPathPattern($pattern, $bubbleControllerAndSubpackage, $formatIsOptional) {
$paths = array($pattern);
$this->expandPatterns($paths, '#templateRoot', $this->getTemplateRootPaths());
$this->expandPatterns($paths, '#partialRoot', $this->getPartialRootPaths());
$this->expandPatterns($paths, '#layoutRoot', $this->getLayoutRootPaths());
/** #var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
$actionRequest = $this->controllerContext->getRequest();
$subpackageKey = $actionRequest->getControllerSubpackageKey();
$controllerName = $actionRequest->getControllerName();
if ($subpackageKey !== NULL) {
if (strpos($subpackageKey, Fluid::NAMESPACE_SEPARATOR) !== FALSE) {
$namespaceSeparator = Fluid::NAMESPACE_SEPARATOR;
} else {
$namespaceSeparator = Fluid::LEGACY_NAMESPACE_SEPARATOR;
}
$subpackageKeyParts = explode($namespaceSeparator, $subpackageKey);
} else {
$subpackageKeyParts = array();
}
if ($bubbleControllerAndSubpackage) {
$numberOfPathsBeforeSubpackageExpansion = count($paths);
$numberOfSubpackageParts = count($subpackageKeyParts);
$subpackageReplacements = array();
for ($i = 0; $i <= $numberOfSubpackageParts; $i++) {
$subpackageReplacements[] = implode('/', ($i < 0 ? $subpackageKeyParts : array_slice($subpackageKeyParts, $i)));
}
$this->expandPatterns($paths, '#subpackage', $subpackageReplacements);
for ($i = ($numberOfPathsBeforeSubpackageExpansion - 1) * ($numberOfSubpackageParts + 1); $i >= 0; $i -= ($numberOfSubpackageParts + 1)) {
array_splice($paths, $i, 0, str_replace('#controller', $controllerName, $paths[$i]));
}
$this->expandPatterns($paths, '#controller', array(''));
} else {
$i = $controllerName === NULL ? 0 : -1;
$this->expandPatterns($paths, '#subpackage', array(implode('/', $i < 0 ? $subpackageKeyParts :
array_slice($subpackageKeyParts, $i))));
$this->expandPatterns($paths, '#controller', array($controllerName));
}
if ($formatIsOptional) {
$this->expandPatterns($paths, '.#format', array('.' . $actionRequest->getFormat(), ''));
$this->expandPatterns($paths, '#format', array($actionRequest->getFormat(), ''));
} else {
$this->expandPatterns($paths, '.#format', array('.' . $actionRequest->getFormat()));
$this->expandPatterns($paths, '#format', array($actionRequest->getFormat()));
}
return array_values(array_unique($paths));
}
/**
* Expands the given $patterns by adding an array element for each $replacement
* replacing occurrences of $search.
*
* #param array $patterns
* #param string $search
* #param array $replacements
* #return void
*/
protected function expandPatterns(array &$patterns, $search, array $replacements) {
$patternsWithReplacements = array();
foreach ($patterns as $pattern) {
foreach ($replacements as $replacement) {
$patternsWithReplacements[] = GeneralUtility::fixWindowsFilePath(str_replace($search, $replacement, $pattern));
}
}
$patterns = $patternsWithReplacements;
}
/**
* Returns a unique identifier for the given file in the format
* <PackageKey>_<SubPackageKey>_<ControllerName>_<prefix>_<SHA1>
* The SH1 hash is a checksum that is based on the file path and last modification date
*
* #param string $pathAndFilename
* #param string $prefix
* #return string
*/
protected function createIdentifierForFile($pathAndFilename, $prefix) {
/** #var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
$actionRequest = $this->controllerContext->getRequest();
$extensionName = $actionRequest->getControllerExtensionName();
$subPackageKey = $actionRequest->getControllerSubpackageKey();
if ($subPackageKey !== NULL) {
$extensionName .= '_' . $subPackageKey;
}
$controllerName = $actionRequest->getControllerName();
$templateModifiedTimestamp = filemtime($pathAndFilename);
$templateIdentifier = sprintf('%s_%s_%s_%s', $extensionName, $controllerName, $prefix, sha1($pathAndFilename . '|' . $templateModifiedTimestamp));
return $templateIdentifier;
}
/**
* Wrapper method to make the static call to GeneralUtility mockable in tests
*
* #param string $pathAndFilename
*
* #return string absolute pathAndFilename
*/
protected function resolveFileNamePath($pathAndFilename) {
return GeneralUtility::getFileAbsFileName(GeneralUtility::fixWindowsFilePath($pathAndFilename), TRUE);
}
}
$templatePathAndFilename = $this->getTemplatePathAndFilename($actionName);
This is the bad one in the function "getTemplateSource".
I downgraded the php version to 5.5 (new xampp installation) and it didn't work. :-(
Hoping for help,
thanks!
Okay I think the problem is solved.
The problem was that the column "tx_fluidpages_layout" of the table "pages" in the database had no entry. It was NULL.
Because I could not change and save it in the page properties without calling that error I changed it with phpmyadmin.
To fix that error you have to manually go to the table "pages" in the database f.e. with phpmyadmin and then to the column "tx_fluidpages_layout". There you have to edit the value and change it to "fluidpages__fluidpages". After that you can save it and reload the backend.
Now you should edit the page properties and set your page layout which comes from your provider extension.
I think it is a bug anyway, that should not happened. In TYPO3 6.x it was inserted automatically.
This describes my current schema:
/**
* #MongoDB\Document(repositoryClass="St\AppBundle\Repository\TaxiStateRepository", requireIndexes=true)
* #MongoDB\Index(keys={"location"="2d"})
*/
class TaxiState
{
/**
* #MongoDB\ReferenceOne(targetDocument="Taxi", simple=true, inversedBy="taxiState")
* #MongoDB\Index
*/
protected $taxi;
..
}
/**
* #MongoDB\Document(repositoryClass="St\AppBundle\Repository\TaxiRepository", requireIndexes=true)
*/
class Taxi
{
/**
* #MongoDB\ReferenceOne(targetDocument="Driver", simple=true)
* #MongoDB\Index
*/
protected $driver;
..
}
/**
* #MongoDB\Document(repositoryClass="St\AppBundle\Repository\DriverRepository", requireIndexes=true)
*/
class Driver
{
/**
* #MongoDB\EmbedOne(targetDocument="DriverAccount")
* #MongoDB\Index
*/
protected $driverAccount;
..
}
/** #MongoDB\EmbeddedDocument */
class DriverAccount
{
/**
* #MongoDB\String
* #Assert\NotBlank()
* #Assert\Choice(choices = {"enabled","disabled"}, message="please chose a valid status"); * #MongoDB\Index
*/
protected $status;
I basically want to run a query that filters out disabled driver accounts.. something like this:
return $this->createQueryBuilder()
->field('taxi.driver.driverAccount.status')->equals("enabled")
->getQuery()
->getSingleResult();
it complains that it doesn't have an index taxi.driver etc.. I spent all day looking at by directional reference documentation in doctrine but the examples are so sparse.. help?
For reference.. this was the query that worked right before i introduced that crazy line:
return $this->createQueryBuilder()
->field('status')->equals('available')
->field('taxi')->notIn($taxiObj)
->field('location')->near((float)$location->getLongitude(), (float)$location->getLatitude())
->distanceMultiplier(self::EARTH_RADIUS_KM)
->maxDistance($radius/111.12)
->getQuery()
->execute();
Just in case you were wondering how I "resolved" this (it's a very hacky answer.. but oh well you do what you gotta do right?) this is what I got:
/**
* Find near enabled taxi without rejected request taxi
*
* #param Document\Location $location
* #param int $radius
* #param array $taxis
* #return Document\TaxiState
*/
public function findEnabledNearTaxiWithoutRejectRequest(Document\Location $location, $radius = self::SEARCH_RADIUS, $taxis = array(), $logger)
{
$taxiObj = array_map(function ($item) {
return new \MongoId($item);
}, $taxis);
//ST-135 change to near, spherical, distanceMultiplier and maxDistance in KM
$allTaxiStates = $this->createQueryBuilder()
->field('status')->equals('available')
->field('taxi')->notIn($taxiObj)
->field('location')->near((float)$location->getLongitude(), (float)$location->getLatitude())
->distanceMultiplier(self::EARTH_RADIUS_KM)
->maxDistance($radius/111.12)
->getQuery()
->execute();
$this->addIdsOfDisabledTaxiStates($taxiObj, $allTaxiStates);
if (count($taxiObj) > 0) {
$logger->info("There are ".count($taxiObj)." taxis excluded while looking for taxis to respond to a requst: ".$this->getMongoIdsStr($taxiObj));
}
return $this->createQueryBuilder()
->field('status')->equals('available')
->field('taxi')->notIn($taxiObj)
->field('location')->near((float)$location->getLongitude(), (float)$location->getLatitude())
->distanceMultiplier(self::EARTH_RADIUS_KM)
->maxDistance($radius/111.12)
->getQuery()
->getSingleResult();
}
/**
* Get the Mongo Ids of disabled taxi States
*
* #param $ids existing array of ids we want to append to (passed by reference)
* #param $taxiStates array of Document\TaxiState
* #return array of MongoIds of disabled taxi states
* #author Abdullah
*/
private function addIdsOfDisabledTaxiStates(&$ids, $taxiStates)
{
foreach ($taxiStates as $taxiState) {
if ($taxiState->getTaxi()->getDriver()->getDriverAccount()->getStatus() != DriverAccountModel::STATUS_ENABLED) {
$mongoId = new \MongoId($taxiState->getTaxi()->getId());
array_push($ids, $mongoId);
}
}
return $ids;
}