I updated a environment. I upgraded PHP and Mongo. The code was using the legacy driver but now I'm using mongodb. I'm also using mongo-php-library. This code snippet is broken now and I'm not sure how to fix it. I've read about updateOne and replaceOne but I'm not sure how to use it:
function update($collection,$criteria,$data,$insertIfNotExists = false)
{
if (!isset($this->collection[$collection])) {
$this->collection[$collection] = self::$database->selectCollection($collection);
}
if ($insertIfNotExists) {
$oldData = $this->collection[$collection]->findOne($criteria);
if ($oldData == NULL) {
$data['createdDate'] = date("Y-m-d H:i:s");
$data['modifiedDate'] = (isset($data['modifiedDate'])) ? $data['modifiedDate']:date("Y-m-d H:i:s");
return ($this->collection[$collection]->insert($data)) ? array('status'=>'ok'):array('status'=>'error','error'=>'unknown_error');
} else {
$newData = $oldData;
foreach($data as $n=>$v) {
$newData[$n] = $v;
}
$newData['modifiedDate'] = (isset($newData['modifiedDate'])) ? $newData['modifiedDate']:date("Y-m-d H:i:s");
return ($this->collection[$collection]->update($criteria,$newData)) ? array('status'=>'ok'):array('status'=>'error','error'=>'unknown_error');
}
} else {
return ($this->collection[$collection]->update($criteria,$data)) ? array('status'=>'ok'):array('status'=>'error','error'=>'unknown_error');
}
}
The new driver changed the name of some methods. Instead of update() (that was used to update one or more documents), now you have updateOne() and updateMany(). The same applies to the other legacy methods insert() and remove(). You can get all further information you need on these changes in PHP MongoDB's Extension Docs and in MongoDB PHP Library.
So, just changing to the code below would fix that error:
$this->collection[$collection]->updateOne($criteria,$data)
Edit
Seems that you only need to update the field modifiedDate, so you can do the following:
$criteria = ['number' => '999'];
$newData = ['modifiedDate' => '2019-07-11 03:00:00'];
$this->collection[$collection]->updateOne(
$criteria,
'$set' => $newData
);
More info here: Update One Document
Related
I've got this code which works well standalone:
file_put_contents('dataFile', implode('',
array_map(function($data) {
return stristr($data,"NSQ = ") ? "NSQ = school\n" : $data;
}, file('dateFile'))
));
This reads dataFile and finds the entry NSQ = and updates it to be NSQ = school
I'm going to reuse this multple times so changed it into a function:
function updatesite($site) {
file_put_contents('dataFile', implode('',
array_map(function($data) {
return stristr($data,"$site = ") ? "$site = school\n" : $data;
}, file('dateFile'))
));
}
Initially, I got an error that $site didn't exist, so I added global $site; before the return.
That stopped the error, but it doesn't update the file.
Is there any way I can use a variable like this?
You can use use to pass variables to a function callback like this:
function updatesite($site) {
file_put_contents('dataFile', implode('',
array_map(function($data) use ($site) {
return stristr($data,"$site = ") ? "$site = school\n" : $data;
}, file('dateFile'))
));
}
I have updated my laravel version from 5.5 to 5.6 and followed the update guide but there is one error that I cannot figure out.
Error
Argument 2 passed to Symfony\Component\HttpFoundation\Cookie::__construct() must be of the type string or null, array given
My code generating this error:
public function show($id, DealService $dealService, CookieJar $cookieJar)
{
if(null != $coupon = $dealService->getActiveDealById($id))
{
if(!Cookie::has('recent'))
{
$ids = [];
array_unshift($ids, $id);
$cookieJar->queue('recent', $ids);
}
else
{
$ids = Cookie::get('recent');
if(!in_array($id, $ids))
{
array_unshift($ids, $id);
$ids[] = $id;
$cookieJar->queue('recent', $ids);
}
}
if(!empty($ids))
{
$recent_deals = $dealService->getDealsByIds($ids);
}
$related_deals = $dealService->getRelatedActiveDeals($id);
return view('couponia.show', ['coupon' => $coupon, 'recent_deals' => $recent_deals, 'related_deals' => $related_deals]);
}
else
{
return view('errors.404');
}
}
CookieJar queue method throws the exception as it is trying to create a Cookie instance, but this code used to work perfectly in 5.5 and the CookieJar documentation also suggests that it accepts array as argument.
The Problem was that after the update the Symphony Library was also updated to version 3.3 which does not support array cookies anymore. At this point a solution could be to serialize the array and then unserialize.
I, using the Graphaware Neo4j-php-OGM. I would like to access the 2nd level relationship. I can't seen to get it to work. What am i doing wrong?
I'm trying to execute the following:
public function allowToContinue($userUuid, $permissionUuid)
{
$userRepo = $this->entityManager->getRepository(User::class);
$permRoleRepo = $this->entityManager->getRepository(PermRole::class);
$permissionRepo = $this->entityManager->getRepository(Permission::class);
$user = $userRepo->findOneBy(['uuid' => $userUuid]);
$permission = $permissionRepo->findOneBy(['uuid' => $permissionUuid]);
$allowed = false;
foreach ($user->getPermrole() as $userRole)
{
var_dump($userRole);
$role = $permRoleRepo->findOneBy(['uuid' => $userRole->getUuid()]);
var_dump($role);
foreach ($role->getPermissions() as $perm)
{
var_dump($perm->getUuid());
if($perm->getUuid() === $permissionUuid){
$allowed = true;
}
}
}
return $allowed;
}
Stacktrace:
Error:
Call to a member function isCollection() on null
at vendor/graphaware/neo4j-php-ogm/src/Hydrator/EntityHydrator.php:107
at GraphAware\Neo4j\OGM\Hydrator\EntityHydrator->hydrateSimpleRelationshipCollection('permissions', object(Result), object(neo4j_ogm_proxy_App_Entity_Generic_PermRole))
(vendor/graphaware/neo4j-php-ogm/src/Persisters/BasicEntityPersister.php:104)
at GraphAware\Neo4j\OGM\Persisters\BasicEntityPersister->getSimpleRelationshipCollection('permissions', object(neo4j_ogm_proxy_App_Entity_Generic_PermRole))
(vendor/graphaware/neo4j-php-ogm/src/Proxy/NodeCollectionInitializer.php:22)
at GraphAware\Neo4j\OGM\Proxy\NodeCollectionInitializer->initialize(object(Node), object(neo4j_ogm_proxy_App_Entity_Generic_PermRole))
(vendor/graphaware/neo4j-php-ogm/src/Proxy/LazyCollection.php:52)
at GraphAware\Neo4j\OGM\Proxy\LazyCollection->doInitialize()
(vendor/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php:332)
at Doctrine\Common\Collections\AbstractLazyCollection->initialize()
(vendor/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php:274)
at Doctrine\Common\Collections\AbstractLazyCollection->getIterator()
(src/Security/RoleChecker.php:45)
at App\Security\RoleChecker->allowToContinue('8d88d920-5ab0-11e8-a371-001c42dff143', 'd93370b0-585d-11e8-a371-001c42dff143')
(src/Controller/Generic/UserController.php:146)
at App\Controller\Generic\UserController->destroy('c34f1380-5ab5-11e8-a371-001c42dff143')
(vendor/symfony/http-kernel/HttpKernel.php:149)
at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
(vendor/symfony/http-kernel/HttpKernel.php:66)
at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
(vendor/symfony/http-kernel/Kernel.php:188)
at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
(public/index.php:37)
It throws the error on the 2nd foreach loop on line:
foreach ($role->getPermissions() as $perm)
It's strange, working the first time correctly and not the 2nd time. Also after fetching the object again to be sure. Without this it throws the exact same notice.
Thanks in advance!
All code is at github: https://github.com/djkevino/Support4Neo
Honestly, pretty confused by this code. The var_dump() die() stuff in destroy()... Also, took me a while to realize we are talking about code in the library, not your code that interacts with this library.
Can you avoid the issue like so?
//add this next line
if (!is_iterable($user->getPermrole())) continue;
foreach ($role->getPermissions() as $perm)
If you are not on PHP version 7.1 or greater you could simply check if the returned value is_null or test for instance of \Traversable and is_array...
is_array($foo) || (is_object($foo) && ($foo instanceof \Traversable ));
As stated in my comment, not sure if that role having no "permissions" is considered a valid state or not.
It looks like $role->getPermissions() can return a null result. So, make sure the result is not null before executing the inner foreach loop.
Since you seem to be testing if any of the user's roles has the desired permission, you do not need the $allowed variable at all. The inner foreach loop can just immediately return true once a match is found, avoiding unnecessary processing.
That is, try this:
public function allowToContinue($userUuid, $permissionUuid) {
$userRepo = $this->entityManager->getRepository(User::class);
$permRoleRepo = $this->entityManager->getRepository(PermRole::class);
$permissionRepo = $this->entityManager->getRepository(Permission::class);
$user = $userRepo->findOneBy(['uuid' => $userUuid]);
$permission = $permissionRepo->findOneBy(['uuid' => $permissionUuid]);
foreach ($user->getPermrole() as $userRole) {
var_dump($userRole);
$role = $permRoleRepo->findOneBy(['uuid' => $userRole->getUuid()]);
var_dump($role);
$rolePerms = $role->getPermissions();
if (!is_null($rolePerms)) {
foreach ($rolePerms as $perm) {
var_dump($perm->getUuid());
if ($perm->getUuid() === $permissionUuid) {
return true;
}
}
}
}
return false;
}
I'm currently working with the medoo.php framework, and although I would normally use their ticket area on github, it appears that no one actually uses that... so...
At any rate, when I'm running one of my files which uses "require" to call the framework, I get the following error:
Warning: Cannot use a scalar value as an array in /home/..../public_html/projects/friendcodes/medoo.min.php on line 759
However, when I inspect the code (the below is lines 752 to 764), I see that it is in fact supposed to check if $where is not set, and if it isn't, make it an array - however this php error begs to differ.
I'm guessing that $where is being set as a variable somewhere else, that's not an array, but there are over 100 occurrences of the variable in the framework, and 830 lines of code, which you probably don't want to see. (Let me know in a comment and I'll add it - again, this is directly from medoo's most two recent updates/releases.)
public function get($table, $columns, $where = null)
{
if (!isset($where))
{
$where = array();
}
$where['LIMIT'] = 1;
$data = $this->select($table, $columns, $where);
return isset($data[0]) ? $data[0] : false;
}
My main question is - How do I rectify this problem without breaking something in this framework which is extremely complex (for my level, at any rate)
Update: How silly of me! I found the problem. Just as people suggested, I was calling $where wrong.
I was calling it with:
$accountinfo = $database->get('xf_user_field_value', ['field_value'], 1);
Instead of
$accountinfo = $database->get('xf_user_field_value', ['field_value'], ["user_id"=>1]);
(Where the third arg is $where) Thanks for the help guys!
Right, first things first, we need to find out what is calling get that shouldn't be. WHICH IS THE ENTIRE PROBLEM. The problem isn't the function itself, the problem is something is calling it using an argument for $where which isn't an array. Changing a library to fix one faulty call is ridiculous.
Step 1: Temporarily edit the get function to include a print_r of the $where variable.
public function get($table, $columns, $where = null)
{
if(isset($where)) print_r($where);
if (!isset($where))
{
$where = array();
}
$where['LIMIT'] = 1;
$data = $this->select($table, $columns, $where);
return isset($data[0]) ? $data[0] : false;
}
This will show us before the error prints the value of $where, which will help you find the malformed get call.
If this fails, try using PHP's built-in backtrace to try to find the issue:
public function get($table, $columns, $where = null)
{
if(isset($where)) print_r(debug_backtrace());
if (!isset($where))
{
$where = array();
}
$where['LIMIT'] = 1;
$data = $this->select($table, $columns, $where);
return isset($data[0]) ? $data[0] : false;
}
The ->get() method is not called properly.
Cannot use a scalar value as an array
That warning is shown if $where is either true, a numeric value or a resource. Valid method calls include:
->get('table', '*')
->get('table', '*', array('WHERE' => 'foo = "bar"'))
Check the manual and fix your code.
EDIT 3: try moving $where['LIMIT'] = 1; inside of the isset statement, since you wouldn't want to pass LIMIT 1 to the query constructor if $where is passed by reference.
DISCLAIMER I have no knowledge of the medoo framework.
public function get($table, $columns, $where = null)
{
if (is_null($where))
{
$where = array('LIMIT'=>1);
}
$data = $this->select($table, $columns, $where);
return isset($data[0]) ? $data[0] : false;
}
how can I get a object from an array when this array is returned by a function?
class Item {
private $contents = array('id' => 1);
public function getContents() {
return $contents;
}
}
$i = new Item();
$id = $i->getContents()['id']; // This is not valid?
//I know this is possible, but I was looking for a 1 line method..
$contents = $i->getContents();
$id = $contents['id'];
You should use the 2-line version. Unless you have a compelling reason to squash your code down, there's no reason not to have this intermediate value.
However, you could try something like
$id = array_pop($i->getContents())
Keep it at two lines - if you have to access the array again, you'll have it there. Otherwise you'll be calling your function again, which will end up being uglier anyway.
I know this is an old question, but my one line soulution for this would be:
PHP >= 5.4
Your soulution should work with PHP >= 5.4
$id = $i->getContents()['id'];
PHP < 5.4:
class Item
{
private $arrContents = array('id' => 1);
public function getContents()
{
return $this->arrContents;
}
public function getContent($strKey)
{
if (false === array_key_exists($strKey, $this->arrContents)) {
return null; // maybe throw an exception?
}
return $this->arrContents[$strKey];
}
}
$objItem = new Item();
$intId = $objItem->getContent('id');
Just write a method to get the value by key.
Best regards.