MongoDBException: Invalid find by call - php

I have a MongoDBException:
"Invalid find by call Bundle\Document\Property::$fieldName
(criteriaWith)".
I don't understand what is wrong here. Can someone help me please?
Here's the Stack Trace:
1 . in vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/MongoDBException.php at line 38
public static function invalidFindByCall($documentName, $fieldName, $method) {
return new self(sprintf('Invalid find by call %s::$fieldName (%s)', $documentName, $fieldName, $method));
}
at
MongoDBException ::invalidFindByCall ('\Bundle\Document\Property',
'criteriaWith', 'findByCriteriaWith')
in vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/DocumentRepository.php at line 222
if ($this->class->hasField($fieldName)) {
return $this->$method(array($fieldName => $arguments[0]));
} else {
throw MongoDBException::invalidFindByCall($this->documentName, $fieldName, $method . $by);
}
at DocumentRepository ->__call ('findByCriteriaWith', array(array('name' => 'ho'))) in src/Bundle/Controller/PropertyController.php at line 286
else {
criteria['name'] = $name;
$entities = $repository->findByCriteriaWith($criteria);
}
The Log Messages:
CRITICAL request Uncaught PHP Exception
Doctrine\ODM\MongoDB\MongoDBException: "Invalid find by call
Bundle\Document\Property::$fieldName (criteriaWith)" at
vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/MongoDBException.php
line 38 Context: { "exception":
"Object(Doctrine\ODM\MongoDB\MongoDBException)" }

Let's go through ODM's document repository magic __call method (as that's what is called since findByCriteriaWith does not exist) and highlight interesting parts.
First we see
if (strpos($method, 'findBy') === 0) {
$by = substr($method, 6, strlen($method));
$method = 'findBy';
}
Your method name starts with "findBy" so we will enter this block leaving us later with $method = 'findBy' and $by = 'CriteriaWith' Later on $by gets camelized, as that's standard for field/property name, and leaves us with $fieldName = 'criteriaWith'. Now next thing we see is $this->class->hasField($fieldName) check which results in exception you got because your class does not have a criteriaWith field.
Summing up $repository->findBySomething($value); is equivalent to $repository->findBy(['something' => $value]) and throws exception if field does not exist in your doocument.

Related

PHP autoloader pointing to a dynamic method name

For testing/debugging/evaluation purposes I want to write wrappers for selected entries of the PHP autoloader chain. As autoloader methods are restricted to a single argument with a given value (the class name) the only way to tell the wrapper what to do seems to be the method name. I thus iterate over spl_autoload_functions(), replace the selected items with dynamically created calls of methods like Wrapper::handler_xxxx and save the original information in that class. Wrapper has a method public static function __callStatic() which should evaluate the incoming requests, do its testing/debugging/evaluating work and otherwise redirect to the (saved) original handler. However, this does not work but leads to errors like this one:
PHP Fatal error: Uncaught LogicException: Passed array does not specify an existing method (class 'Wrapper' does not have a method 'autoload_mdGVzdG1ldGhvZAo') in [somewhere]
Seems that the autoloader needs real methods and does not work with PHP-magic. Whether this is a bug or a feature (if the latter: why?), is there any way to work around it?
Edit: some code example upon request, I am not sure if this helps understanding the problem; this is by far not finished, but just an attempt to get the basic idea up and running. Calling the magic method manually (by the name given above) works fine - it is just that the autoloader-logic is not willing to call it.
class Wrapper {
const AUTOLOAD_PREFIX = 'autoload';
public static function __callStatic(String $name, Array $arguments) {
if (strpos($name, self::AUTOLOAD_PREFIX) === 0) {
try {
# valid signature found
if (preg_match(sprintf('/^%s(_c([^_]+))?_m([^_]+)$/', self::AUTOLOAD_PREFIX), $name, $matches)) {
# call via class/method
$method = self::decodeMethodName($matches[3]);
if ($matches[2]) {
$class = self::decodeMethodName($matches[2]);
$class::$method($arguments);
}
else {
# call global function
$method($arguments);
}
}
else {
# invalid name
throw new \Exception(sprintf('Invalid static call of %s::%s', __CLASS__, $name));
}
}
catch (\Throwable $e) {
echo "I got you.";
die;
}
}
else {
throw new \Exception(sprintf('Invalid static call of %s::%s', __CLASS__, $name));
}
return;
}
private static function encodeMethodName(String $method) : String {
# protect and encode method names
return str_replace(array('+', '/', '='), array(0x81, 0x82, ''), base64_encode($method));
}
private static function decodeMethodName(String $method) : String {
# reconstruct method names
return base64_decode(str_replace(array(0x80, 0x81), array('+', '/'), $method));
}
public function protectAutoloader(?String $originalClass, String $originalMethod) : Void {
$stack = array();
$autoLoaders = spl_autoload_functions();
while (!$done && count($autoLoaders) > 0) {
$item = array_pop($autoLoaders);
if (
is_string($item) &&
is_null($originalClass) &&
($originalMethod === $item)
) {
# global function
$replacement = array(
__CLASS__,
sprintf('%s_m%s', self::AUTOLOAD_PREFIX, self::encodeMethodName($item)),
);
$done = true;
}
elseif (
is_array($item) &&
($item[0] === $originalClass) &&
($item[1] === $originalMethod)
) {
# static method
$replacement = array(
__CLASS__,
sprintf('%s_c%s_m%s', self::AUTOLOAD_PREFIX, self::encodeMethodName($item[0]), self::encodeMethodName($item[1])),
);
$done = true;
}
else {
# don't touch anything else (closures)
$replacement = $item;
}
# remove item and push to the stack
spl_autoload_unregister($item);
array_push($stack, $replacement);
}
# restore autoloader chain
while (count($stack) > 0) {
$item = array_pop($stack);
spl_autoload_register($item, true);
}
return;
}
I'd activate this for a specific autoloader:
$wrapper->protectAutoloader(NULL, 'testmethod');
Now testmethod() (if existing in the chain) will be replaced by Wrapper::autoload_mdGVzdG1ldGhvZAo() and if e.g. a syntactically broken file were autoloaded the message "I got you" would be printed.

Fatal error: Call to undefined method Action::execute() /home/public_html/system/engine/event.php on line 62

Hi tried refreshing the modification cache cache in opencart and since then i am getting a blank page in front end with this error message.
public function trigger($event, array $args = array()) {
foreach ($this->data as $value) {
if (preg_match('/^' . str_replace(array('\*', '\?'), array('.*', '.'), preg_quote($value['trigger'], '/')) . '/', $event)) {
$result = $value['action']->execute($this->registry, $args);
if (!is_null($result) && !($result instanceof Exception)) {
return $result;
}
}
}
}
Thanks,
It seems your have an OC version 3.0.2.x or above.
In your $this->data of the Event Class, you have an event registered that is missing an action parameter.
$this->data[] = array(
'trigger' => $trigger,
'action' => $action, // <-- this must be an Action Object with a method execute()
'priority' => $priority
);
All events are registered via the register() method which explicitly requests that an Action object is being passed as a parameter.
Since the error is pointing to "Call to undefined method Action::execute()", I can assume, you have an issue with the action class.
Most likely you need to check the Modifications of the system/engine/action.php file in your system/storage/modifications.
It could be that the method execute() is either missing or somehow corrupt.
Debug
try to var_dump the $value to see what is there:
public function trigger($event, array $args = array()) {
foreach ($this->data as $value) {
//log out the $value before the error to see if the Action object is actually there and see what trigger causes this.
var_dump($value);
if (preg_match('/^' . str_replace(array('\*', '\?'), array('.*', '.'), preg_quote($value['trigger'], '/')) . '/', $event)) {
$result = $value['action']->execute($this->registry, $args);
if (!is_null($result) && !($result instanceof Exception)) {
return $result;
}
}
}
}
Hope this helps

How to fix: Warning: Illegal offset type in isset or empty in F:\xampp\htdocs\digikalamvc\core\model.php on line 140

How to fix this error:
Warning: Illegal offset type in isset or empty in F:\xampp\htdocs\digikalamvc\core\model.php on line 140
Fatal error: Uncaught Error: Unsupported operand types in F:\xampp\htdocs\digikalamvc\models\model_showcart4.php:90 Stack trace: #0 F:\xampp\htdocs\digikalamvc\controllers\showcart4.php(31): model_showcart4->saveOrder(Array) #1 F:\xampp\htdocs\digikalamvc\core\app.php(34): Showcart4->saveorder() #2 F:\xampp\htdocs\digikalamvc\index.php(7): App->__construct() #3 {main} thrown in F:\xampp\htdocs\digikalamvc\models\model_showcart4.php on line 90
Code in model.php on line 140: ( if (isset($_SESSION[$name])) { )
public static function sessionGet($name) {
if (isset($_SESSION[$name])) {
return $_SESSION[$name];
} else {
return false;
}
}
Code in model_showcart4.php on line 90:
$priceTotal =$basketPrice-$basketDiscount+$postprice;
Code model_showcart4:
$basket = $basketInfo[0];
$basket = serialize($basket);
$basketPrice = $basketInfo[1];
$basketDiscount = $basketInfo[2];
$postprice = $this->calculatePostPrice($addressInfo['city']);
$postType = self::sessionGet(['postType']);
if ($postType == 1) {
$postprice = $postprice['pishtaz'];
} elseif ($postType == 2) {
$postprice = $postprice['sefareshi'];
}
$priceTotal =$basketPrice-$basketDiscount+$postprice;
Code showcart4.php on line 31:
function saveorder() {
$this->model->saveOrder($_POST);
}
$postType = self::sessionGet(['postType']);
as you can see, argument is an array.
so here
isset($_SESSION[$name]) code gets to be invalid, because array key should be integer or string, not an array.
$postType = self::sessionGet('postType'); - this should work, I guess
Your warning indicates that the key given to your function doesn't exist in the $_SESSION array. In model_showcart4.php on line 83 you passed an array to your function, which is probably the cause of this error.
I would recommend to add an extra check in your if statement. Use array_key_exists function to check if the key actually exists in the given array, so if for some reason a key is given which simply doesn't exists, your code wouldn't break.
F:\xampp\htdocs\digikalamvc\core\model.php
public static function sessionGet($name) {
if (array_key_exists($name, $_SESSION) && isset($_SESSION[$name])) {
return $_SESSION[$name];
} else {
return false;
}
}

Symfony Notice: unserialize(): Error at offset 36 of 40 bytes , moving from Mysql to PostgreSQL

I'm facing a problem while calling an api made in-house.
The log says :
[2017-02-07 16:04:39] doctrine.DEBUG: SELECT h0_.id AS id_0, h0_.hash AS hash_1, h0_.request AS request_2, h0_.options AS options_3, h0_.serialized_response_body AS serialized_response_body_4, h0_.response AS response_5, h0_.sent_at AS sent_at_6 FROM http_request h0_ WHERE h0_.hash = ? ["dd3e36a5a38618974cae2b45f9cb3a67"] []
[2017-02-07 16:04:39] request.CRITICAL: Uncaught PHP Exception Symfony\Component\Debug\Exception\ContextErrorException: "Notice: unserialize(): Error at offset 36 of 40 bytes" at /var/www/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php line 57 {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\ContextErrorException(code: 0): Notice: unserialize(): Error at offset 36 of 40 bytes at /var/www/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php:57)"} []
I'm kinda lost >.<
EDIT :
In my controller, I submit a form containing several information in order to do the process.
/**
* #Rest\View(serializerGroups={"Review"})
* #Security("is_granted('ROLE_REVIEW_CREATE')")
*/
public function postAction(Request $request)
{
if ($this->getUser()->getBalance()->getTokens() == 0) {
throw new AccessDeniedException('The Review can not be created because you lack of tokens');
}
$review = new Review();
$review->setCreatedBy($this->getUser());
$reviewForm = $this->createForm(ReviewType::class, $review, [
'csrf_protection' => false,
]);
$reviewForm->submit($request->request->all());
if ($reviewForm->isSubmitted() && $reviewForm->isValid()) {
// If the user is in an organization, takes the organization analyzer environment, otherwise takes the user one.
$analyzerEnvironment = $this->getUser()->getCompany() ? $this->getUser()->getCompany()->getAnalyzerEnvironment() : $this->getUser()->getAnalyzerEnvironment();
$crawlingFlow = $this->get('app.manager.crawling_flow')->getCrawlingFlow();
$this->get('app.manager.review')->process(
$review,
$crawlingFlow,
$analyzerEnvironment
);
$reviewEncrypted = new ReviewEncrypted();
$reviewEncrypted->setReliability($review->getReliability());
$reviewEncrypted->setData($this->get('app.manager.review')->encrypt($review));
$reviewEncrypted->setCreatedBy($this->getUser());
$this->getDoctrine()->getManager()->persist($reviewEncrypted);
$this->getDoctrine()->getManager()->flush();
$review->setId($reviewEncrypted->getId());
if ($this->getUser()->getBalance()->getTokens() > 0) {
$this->getUser()->getBalance()->setTokens($this->getUser()->getBalance()->getTokens() - 1);
$this->getDoctrine()->getManager()->persist($this->getUser());
$this->getDoctrine()->getManager()->flush();
}
return $review;
}
return $reviewForm;
}
An when calling:
$crawlingFlow = $this->get('app.manager.crawling_flow')->getCrawlingFlow();
$this->get('app.manager.review')->process(
$review,
$crawlingFlow,
$analyzerEnvironment
);
Several services are called, they send requests, do stuff like storing in DB, etc ...
Question is, is there something I forgot to do when I changed the db (from mysql to postgresql), or is it something else ?
Where can possibly come the unserialize() error ? Why ?
Thanks for the help :p
EDIT 2:
Here where the error comes from according to the log "vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php line 57" :
/**
* {#inheritdoc}
*/
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
return serialize($value);
}
/**
* {#inheritdoc}
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
if ($value === null) {
return null;
}
$value = (is_resource($value)) ? stream_get_contents($value) : $value;
$val = unserialize($value);
if ($val === false && $value !== 'b:0;') {
throw ConversionException::conversionFailed($value, $this->getName());
}
return $val;
}
There is one important difference between text of MySQL and PostgreSQL, and may be it's your case. PostgreSQL do not allow \0 in text field. So, on prepare stage pg driver cut string on first \0.
Unfortunately, serialize use \0 symbol internally.
class A {
private $a = 'a';
private $b = 'b';
}
$a = new A();
var_export(serialize($a));
will show
'O:1:"A":2:{s:4:"' . "\0" . 'A' . "\0" . 'a";s:1:"a";s:4:"' . "\0" . 'A' . "\0" . 'b";s:1:"b";}'
MySQL insert of this sting will work fine:
INSERT INTO test1 VALUES ('O:1:\"A\":2:{s:4:\"\0A\0a\";s:1:\"a\";s:4:\"\0A\0b\";s:1:\"b\";}')
But Pg driver silently cut string and execute
LOG: execute pdo_stmt_00000001: INSERT INTO test1 VALUES ($1)
DETAIL: parameters: $1 = 'O:1:"A":2:{s:4:"'
or INSERT INTO test1 VALUES ('O:1:"A":2:{s:4:"') with prepare emulation.
As you can see - result is cut string and unserialize can't restore it.
Solution: use bytea datatype for Postgresql or add some kind of encode/decode of serialized string.
UPD: About object datatype in Doctrine http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/types.html#object

PHP: Fatal error: Call to undefined method ::(url)()

Whats wrong with my codes, I always got fatal error when I change my URL. I can't remove those if else below which have undefined, I will not get 2nd URL. I am beginner creating MVC please help
class event_trap
{
function __construct()
{
$url = $_GET['url'];
$url = rtrim($url. '/');
$url = explode('/', $url);
//print_r($url);
$file = 'event_mvc/controllers/' .$url[0] . '.php';
if (file_exists($file)) {
require $file;
} else {
require 'event_mvc/controllers/error.php';
$controller = new Error();
return false;
}
$controller = new $url[0];
if (isset($url[2])) {
$controller->{$url[1]}($url[2]); //<-- Undefined method
} else {
if(isset($url[1])) {
$controller -> {$url[1]}(); //<-- Undefined method
} else {
}
}
}
}
var_dump($url)
array (size=2)
0 => string 'event' (length=5)
1 => string '' (length=0)
Fatal error: Call to undefined method event::() in
C:\wamp\www\tabulation\event_mvc\libs\Bootstrap.php on line 33
Call Stack
# Time Memory Function Location
1 0.0004 142728 {main}( ) ..\event.php:0
2 0.0012 149096 event_trap->__construct( ) ..\event.php:4
Your variable $url is an array which you use to create an object and call methods with or without parameters. With the array ou have var_dumped 0=>event, 1=>'' you are creating an object of class event and call the method '' which does not exist. Correct your code or pass a valid function name.
You can try this which checks for empty string too.
if (isset($url[2]) && !empty($url[2]) {
$controller->{$url[1]}($url[2]);
} else {
if(isset($url[1]) && !empty($url[1]) {
$controller -> {$url[1]}();
}
}

Categories