PHPIDS on php 8.1 Deprecated Errors [duplicate] - php

This question already has answers here:
Reference: Return type of ... should either be compatible with ..., or the #[\ReturnTypeWillChange] attribute should be used
(2 answers)
Closed last year.
i got a problem with PHPIDS on a PHP 8.1 Server.
Here the Errors:
PHP Deprecated: Return type of IDS\Report::count() should either be compatible with Countable::count(): int, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in phpids\ib\IDS\Report.php on line 205
PHP Deprecated: Return type of IDS\Report::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in phpids\lib\IDS\Report.php on line 218
I know Deprecated Errors are not that bad, but i want that everything works Perfect.
I Searched in Google several things but no solution found.
Hopefully you find the problem.
i use the actual PHPIDS version from Github (https://github.com/PHPIDS/PHPIDS)
i know this version is not the newest but i didn't found a newer one.
thx for the help
and here the Script Report.php
<?php
/**
* PHPIDS
*
* Requirements: PHP5, SimpleXML
*
* Copyright (c) 2008 PHPIDS group (https://phpids.org)
*
* PHPIDS is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3 of the License, or
* (at your option) any later version.
*
* PHPIDS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with PHPIDS. If not, see <http://www.gnu.org/licenses/>.
*
* PHP version 5.1.6+
*
* #category Security
* #package PHPIDS
* #author Mario Heiderich <mario.heiderich#gmail.com>
* #author Christian Matthies <ch0012#gmail.com>
* #author Lars Strojny <lars#strojny.net>
* #license http://www.gnu.org/licenses/lgpl.html LGPL
* #link http://php-ids.org/
*/
namespace IDS;
/**
* PHPIDS report object
*
* The report objects collects a number of events and thereby presents the
* detected results. It provides a convenient API to work with the results.
*
* Note that this class implements Countable, IteratorAggregate and
* a __toString() method
*
* #category Security
* #package PHPIDS
* #author Christian Matthies <ch0012#gmail.com>
* #author Mario Heiderich <mario.heiderich#gmail.com>
* #author Lars Strojny <lars#strojny.net>
* #copyright 2007-2009 The PHPIDS Group
* #license http://www.gnu.org/licenses/lgpl.html LGPL
* #link http://php-ids.org/
*/
class Report implements \Countable, \IteratorAggregate
{
/**
* Event container
*
* #var Event[]|array
*/
protected $events = array();
/**
* List of affected tags
*
* This list of tags is collected from the collected event objects on
* demand when IDS_Report->getTags() is called
*
* #var string[]|array
*/
protected $tags = array();
/**
* Impact level
*
* The impact level is calculated on demand by adding the results of the
* event objects on IDS\Report->getImpact()
*
* #var integer
*/
protected $impact = 0;
/**
* Centrifuge data
*
* This variable - initiated as an empty array - carries all information
* about the centrifuge data if available
*
* #var array
*/
protected $centrifuge = array();
/**
* Constructor
*
* #param array $events the events the report should include
*
* #return Report
*/
public function __construct(array $events = null)
{
foreach ((array) $events as $event) {
$this->addEvent($event);
}
}
/**
* Adds an IDS_Event object to the report
*
* #param Event $event IDS_Event
*
* #return self $this
*/
public function addEvent(Event $event)
{
$this->clear();
$this->events[$event->getName()] = $event;
return $this;
}
/**
* Get event by name
*
* In most cases an event is identified by the key of the variable that
* contained maliciously appearing content
*
* #param string|integer $name the event name
*
* #throws \InvalidArgumentException if argument is invalid
* #return Event|null IDS_Event object or false if the event does not exist
*/
public function getEvent($name)
{
if (!is_scalar($name)) {
throw new \InvalidArgumentException('Invalid argument type given');
}
return $this->hasEvent($name) ? $this->events[$name] : null;
}
/**
* Returns list of affected tags
*
* #return string[]|array
*/
public function getTags()
{
if (!$this->tags) {
$this->tags = array();
foreach ($this->events as $event) {
$this->tags = array_merge($this->tags, $event->getTags());
}
$this->tags = array_values(array_unique($this->tags));
}
return $this->tags;
}
/**
* Returns total impact
*
* Each stored IDS_Event object and its IDS_Filter sub-object are called
* to calculate the overall impact level of this request
*
* #return integer
*/
public function getImpact()
{
if (!$this->impact) {
$this->impact = 0;
foreach ($this->events as $event) {
$this->impact += $event->getImpact();
}
}
return $this->impact;
}
/**
* Checks if a specific event with given name exists
*
* #param string|integer $name the event name
*
* #throws \InvalidArgumentException if argument is illegal
* #return boolean
*/
public function hasEvent($name)
{
if (!is_scalar($name)) {
throw new \InvalidArgumentException('Invalid argument given');
}
return isset($this->events[$name]);
}
/**
* Returns total amount of events
*
* #return integer
*/
public function count()
{
return #count($this->events);
}
/**
* Return iterator object
*
* In order to provide the possibility to directly iterate over the
* IDS_Event object the IteratorAggregate is implemented. One can easily
* use foreach() to iterate through all stored IDS_Event objects.
*
* #return \Iterator the event collection
*/
public function getIterator()
{
return new \ArrayIterator($this->events);
}
/**
* Checks if any events are registered
*
* #return boolean
*/
public function isEmpty()
{
return empty($this->events);
}
/**
* Clears calculated/collected values
*
* #return void
*/
protected function clear()
{
$this->impact = 0;
$this->tags = array();
}
/**
* This method returns the centrifuge property or null if not
* filled with data
*
* #return array
*/
public function getCentrifuge()
{
return $this->centrifuge;
}
/**
* This method sets the centrifuge property
*
* #param array $centrifuge the centrifuge data
*
* #throws \InvalidArgumentException if argument is illegal
* #return void
*/
public function setCentrifuge(array $centrifuge = array())
{
if (!$centrifuge) {
throw new \InvalidArgumentException('Empty centrifuge given');
}
$this->centrifuge = $centrifuge;
}
/**
* Directly outputs all available information
*
* #return string
*/
public function __toString()
{
$output = '';
if (!$this->isEmpty()) {
$output .= vsprintf(
"Total impact: %d<br/>\nAffected tags: %s<br/>\n",
array(
$this->getImpact(),
implode(', ', $this->getTags())
)
);
foreach ($this->events as $event) {
$output .= vsprintf(
"<br/>\nVariable: %s | Value: %s<br/>\nImpact: %d | Tags: %s<br/>\n",
array(
htmlspecialchars($event->getName()),
htmlspecialchars($event->getValue()),
$event->getImpact(),
implode(', ', $event->getTags())
)
);
foreach ($event as $filter) {
$output .= vsprintf(
"Description: %s | Tags: %s | ID %s<br/>\n",
array(
$filter->getDescription(),
implode(', ', $filter->getTags()),
$filter->getId()
)
);
}
}
$output .= '<br/>';
if ($centrifuge = $this->getCentrifuge()) {
$output .= vsprintf(
"Centrifuge detection data<br/> Threshold: %s<br/> Ratio: %s",
array(
isset($centrifuge['threshold']) && $centrifuge['threshold'] ? $centrifuge['threshold'] : '---',
isset($centrifuge['ratio']) && $centrifuge['ratio'] ? $centrifuge['ratio'] : '---'
)
);
if (isset($centrifuge['converted'])) {
$output .= '<br/> Converted: ' . $centrifuge['converted'];
}
$output .= "<br/><br/>\n";
}
}
return $output;
}
}

As of PHP 8.1, you have to fix the return type of the functions count() and getIterator() to match with interfaces.
public count(): int (see Countable)
public getIterator(): Traversable (see IteratorAggregate)
class Report implements \Countable, \IteratorAggregate
{
protected array $events;
public function count(): int
{
return count($this->events);
}
public function getIterator(): \Traversable
{
return new \ArrayIterator($this->events);
}
}

Related

Solorium issue - syntax error, unexpected ':', expecting ';' or '{' at line number 309 [duplicate]

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.

How to mention a property in PHPDoc?

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}.

Changing preg_replace to preg_replace_callback

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.

TYPO3 - 7.2 FLUID Error: file_get_contents() Filename empty

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.

How to perform nested reference query in doctrine mongodb

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;
}

Categories