Object could not be converted into string - php

code:
public function atualizarPorLocal( $acao, $novasRedes )
{
$em = $this->getEntityManager();
$apagaObj = $em->getRepository( 'CommonBundle:AcaoRede' )->findBy( array( 'acao'=>$acao ) );
foreach ( $apagaObj as $acao){
if (!empty($acao))
$em->remove($acao);
}
$em->flush();
foreach ( $novasRedes as $idRede )
{
$new = new AcaoRede();
$new->setAcao( $em->getRepository( 'CommonBundle:Acao' )->find( $acao ) );
$new->setRede( $em->getRepository( 'CommonBundle:Rede' )->find( $idRede ) );
$em->persist( $new );
}
$em->flush();
}
erro:
PHP Catchable fatal error: Object of class \CommonBundle\Entity\AcaoRede could not be converted to string in vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 2794, referer: /app_dev.php/modulo/editar/col_soft
what can I do to work around this error?

You have to use Acao's id
$new->setAcao( $em->getRepository( 'CommonBundle:Acao' )->find( $acao->getId() ) );
Doctrine's find method is expecting id field, so it tries to convert your $acao to string using __toString() method. You have to pass $acao->getId() to make it work

variable $acao was assuming a different value when entered in the second foreach
solved this problem by changing the name of the variable.
foreach ( $apagaObj as $acaoObj){
if (!empty($acaoObj))
$em->remove($acaoObj);
}

Related

Laravel - Removing object inside of array based on key value - array_filter

I'm having trouble removing an object inside of this array.
First I get the $id that is to be removed from the array.
But when I'm filtering throw the array its appending keys to it.
So the logic ll no longer work on the rest of the application.
How can I maintain the same syntax on the options object after removing the object inside of the cart array ?
public function destroy( $id, Request $request )
{
$user = $this->user ;
$data = array_filter( $user->options->cart , function ( $option ) use ( $id ) {
if ( $option->product_id == $id ) {
return false;
}
return json_encode($option);
});
//dd($user->options->cart);
//dd($data);
$user->options = (object)['cart' => $data ];
$user->save() ;
return response()->json( $user , 200 ) ;
}
Solved :
public function destroy( $id, Request $request )
{
$user = $this->user ;
$data = array_filter( $user->options->cart , function ( $option ) use ( $id ) {
if ( $option->product_id == $id ) {
return false;
}
return true;
});
$user->options = ['cart' => array_values( $data ) ];
$user->save() ;
return response()->json( $user , 200 ) ;
}
}
if i understood u right , u want to rearrange the array after u do your logic plus keeping the structure , i would suggest you to use array_values
$new_data= array_values($data);
and if u got an error that its not an array although i doubt that just use the toArray() method
$new_data= array_values($data->toArray());
It seems like (object)['cart' => $data ] is somehow changing your array.
Setting the property directly should work:
$user->options->cart = $data;
Also, return json_encode($option); doesn't have any real effect except making the execution slower. You can just return true;.
Looking at your JSON encoding, I see that your options object on the bottom left is an object that contains a property, cart, which is an array. Your options object on the bottom right is an object that contains a property, cart, which is an object that contains a property for each numeric index.
I'm not at all certain, but I think the problem might be that the array_filter function preserves the array keys:
If the callback function returns TRUE, the current value from array is returned into the result array. Array keys are preserved.
I suggest you try using some approach that does not try to preserve array keys so that your filtered array has contiguous, numeric values.
public function destroy( $id, Request $request )
{
foreach($this->user->options->cart as $key => $cart_item) {
if ($cart_item->product_id == $id) {
unset($this->user->options->cart[$key]);
}
}
$user->save() ;
return response()->json( $user , 200 ) ;
}
EDIT: I am not privy to the details of your implementation (I don't know what type of object $user is or what $user->save or $response->json() might do) but this code will remove an array element by product_id:
$arr = array(
(object)["product_id" => 819, "name" => "I am 819"],
(object)["product_id" => 820, "name" => "I am 820"],
(object)["product_id" => 821, "name" => "I am 821"],
(object)["product_id" => 822, "name" => "I am 822"]
);
foreach($arr as $key => $v) {
if ($v->product_id == 820) {
unset($arr[$key]);
}
}
var_dump($arr);

Laravel : Can't use `Input::get('foobar')` as an action's default parameter value

I'm trying to do the following in my controller:
public function moveMessagesToArchive( $message_ids = Input::get('message_ids') )
{
$json = json_encode( $message_ids);
echo $json;
}
And it keeps throwing the following error:
syntax error, unexpected '(', expecting ')'
at the function signature. What's causing the problem here?
Update
While, I wait for the reason I've written the following work around:
public function moveMessagesToArchive( $message_ids = array() )
{
$ids = array();
if ( ( count($message_ids) !== 0 ) && is_array($message_ids) ) {
$ids = $message_ids;
} else if ( Input::get('message_ids') ) {
$ids = Input::get('message_ids');
} else {
return false;
}
$json = json_encode( $ids );
echo $json;
}
It is not possible in PHP. According to the documentation
The default value must be a constant expression, not (for example) a variable, a class member or a function call.
Reference Example 4
What you are trying to do is not, and never has been supported by php.
Nothing at all to do with Laravel.

PHP error syntax error, unexpected T_FUNCTION in

/CustomPostType.php on line 165
// Initialise class variables as blank
$metaKeys = $this->get_meta_keys();
foreach( $metaKeys as $key )
if( !empty( $key ) )
$this->$key = null;
$this->ID = null;
The below code is what fixed the syntax error.
public function get_meta_keys( $objectName) {
$getClassVars = get_class_vars( $objectName );
return array_keys( $getClassVars);
}
There is syntax error in the code. It should be like this :
public function get_meta_keys( $objectName) {
$getClassVars = get_class_vars( $objectName );
return array_keys( $getClassVars);
}
Point to correct :
Correct function signature. Add argument in the function get_meta_keys().
Err, your code doesn't even look like it validates to me.
public function get_meta_keys( $objectName ) {
$getClassVars = get_class_vars( $objectName );
return array_keys( $getClassVars() );
}
Put semicolon at the end of the function call and also you need to format your code first.
public function get_meta_keys( )
{
$getClassVars = get_class_vars( $objectName );
return array_keys( $getClassVars() );
}

Stored Javascript in MongoDB

I am trying to store a query in MongoDB by using stored javascript.
It looks something like this right now:
$collection = $db->$app_id;
$query = $collection->find( $filterQuery );
$db->system->js->save(array(
"_id" => "qo8qu0",
"value" => new MongoCode("function() { return array($query) }")
));
Then I execute it:
echo "<pre>";
print_r($test = $db->execute("qo8qu0()"));
echo "</pre>";
However, I am getting this error:
Catchable fatal error: Object of class MongoCursor could not be converted to string in /var/www/dev/classes/EmailMessaging.php on line 91
Line 91 is this line (like above),
"value" => new MongoCode("function() { return array($filterQuery) }")
If I use count( $filterQuery ); instead of find( $filterQuery );
It works and returns the right number.
How can I make it work so it returns the array when using find?
Thank you
It is because of evaluation of your code. It is evaluating this:
$query = $collection->find( $filterQuery );
So that $query is a MongoCursor and then you are attempting to concatenate that class into a string:
new MongoCode("function() { return array($query) }")
You need to do the entire thing witthin eval like so:
return $this->execute('function(){ return db.collection.find(filter); }', array('filter'=>array('_id'=>1)));
count works because it returns an int which can be added to the string.
Edit
A way:
$db->system->js->save(array(
"_id" => "qo8qu0",
"value" => new MongoCode("function() { return db.collection.find(filter).toArray() }")
));
And then in your app:
$test = $db->execute("qo8qu0()", array('filter'=>array('_id'=>1)))

Property chaining and isset in configuration object [duplicate]

This question already has answers here:
Search nested object for property
(4 answers)
Closed 2 years ago.
I couldn't find a question that was quite like mine, but if you can find one feel free to let me know..
I'm trying to figure out how to effectively create an neat configuration object.
I want the object (or a config manager of some sort) to be able to convert an array or INI file into a parent/child grouping of objects.
Eg:
$config_array = array (
'somecategory' => array ( 'key' => 'somevalue' ),
'anothercategory' => array ( 'key' => 'anothervalue', 'key2' => 'anothervalue2' ),
);
$config = new Configuration_Array( $config_array );
echo $config->somecategory->key; // prints: 'somevalue'
I have effectively done this with the following code:
class Configuration_Array extends Configuration
{
protected $_child_class = 'Configuration_Array';
protected $_objects = null;
protected $_config = null;
public function __construct( $config_array = null, $child_class = null ) {
if ( null !== $config_array ) {
$this->setConfig( $config_array );
}
if ( null !== $child_class ) {
$this->setChildClass( $child_class );
}
}
public function __get( $name ) {
$name = strtolower( $name );
if ( ! isset ( $this->_objects[ $name ] ) ) {
$this->_createObject( $name );
}
return $this->_objects[ $name ];
}
public function __isset( $name ) {
$name = strtolower( $name );
return ( ( isset ( $this->_objects[ $name ] ) ) or $this->_can_create_object( $name ) );
}
public function reset() {
$this->_objects = null;
}
public function toArray() {
if ( ! is_array ( $this->_config ) ) {
throw new Exception( 'No configuration has been set' );
}
return $this->_config;
}
public function setConfig( $config ) {
if ( null === $config ) {
return $this->reset();
}
if ( ! is_array ( $config ) ) {
throw new Exception( 'Configuration is not a valid array' );
}
$this->_config = $config;
}
public function loadConfig( $path ) {
if ( ! is_string ( $path ) ) {
throw new Exception( 'Configuration Path "' . $path . '" is not a valid string' );
}
if ( ! is_readable ( $path ) ) {
throw new Exception( 'Configuration file "' . $path . '" is not readable' );
}
$this->setConfig( include( $path ) );
}
public function setChildClass( $class_name ) {
if ( ! is_string ( $class_name ) ) {
throw new Exception( 'Configuration Child Class is not a valid string' );
}
if ( ! class_exists ( $class_name ) ) {
throw new Exception( 'Configuration Child Class does not exist' );
}
$this->_child_class = $class_name;
}
public function getChildClass() {
if ( ! isset ( $this->_child_class ) ) {
throw new Exception( 'Configuration Child Class has not been set' );
}
return $this->_child_class;
}
protected function _createObject( $name ) {
$name = strtolower( $name );
if ( ! isset ( $this->_config[ $name ] ) ) {
throw new Exception( 'No configuration has been set for object "' . $name . '"' );
}
$child_class = $this->getChildClass();
if ( is_array ( $this->_config[ $name ] ) ) {
$child = new $child_class( $this->_config[ $name ], $child_class );
} else {
$child = $this->_config[ $name ];
}
return ( $this->_objects[ $name ] = $child );
}
protected function _can_create_object( $name ) {
$name = strtolower( $name );
return isset ( $this->_config[ $name ] );
}
}
The Problem
Most of this works perfectly, but I am having some trouble figuring out how I can use isset effectively. With property chaining, isset only works on the last value in the chain, eg:
if ( isset ( $config->somecategory->key ) ) {
Which uses the object returned by $config->somecategory and checks whether it holds an object called 'key'
This means that if $config->somecategory doesn't exist, an exception is thrown. The user would have to do this to check effectively:
if ( isset ( $config->somecategory ) and isset ( $config->somecategory->key ) ) {
But that seems quite annoying.
An array on the other hand doesn't need to be checked at each level; PHP can check the entire thing:
if ( isset ( $config[ 'somecategory' ][ 'key' ] ) ) { // No error/exception
What I'm looking for is a way to implement my class so I can treat my objects sort of the same way I'd treat an array:
if ( isset ( $config->somecategory->key ) ) {
In a way that wouldn't throw an exception if 'somecategory' doesn't exist...
Ideas?
Since PHP 7 it's possible to use a not well documented feature of null coalesce operator for this purpose.
$config_array = [
'somecategory' => [ 'key' => 'somevalue' ],
'anothercategory' => [ 'key' => 'anothervalue', 'key2' => 'anothervalue2' ],
];
// Quickly convert to object
$json = json_encode($config_array);
$config = json_decode($json);
echo $config->somecategory->key ?? null; // prints: 'somevalue'
echo $config->somecategory->missing_key ?? null; // no errors but also doesn't print anything
echo $config->somecategory->missing_key->go->crazy->with->chains ?? null; // no errors but also doesn't print anything
Here is an online example in action
Unfortunately there is not version of isset which checks your property chain correctly. Even writing your own method will not help as passing the chain as parameter to your method already fails if somecategory is already unset.
You can implement the magic method for accessing unset properties (maybe in a base class common to your config objects). This will create a dummy object of class UnsetProperty and return that.
Your class to $config->someCategory->key will deliver a UnsetProperty for $config->someCategory. This object will also delivery a new UnsetProperty for $obj->key. If you implement a method IsSet() in UnsetProperty returning false and in other properties returning true you can simplyfy your check to:
if($config->someCategory->key->IsSet()) ...
This will need a lot of to do so I am not sure if you do not like to go with the chained isset-calls.
if((isset($config->someCategory)) and (isset($config->someCategory->key))) ...
Depends on style and how many nested levels you have.
Hope you get the idea behind the possibility.
Take a look at Zend_Config. It operates almost exactly as you describe.
You could use it directly or simply as an instructional guide to build your own.
Maybe something like this?
The only problem is, you would have to call isEmpty to check if a configuration is given, and get to get the final value. (Like can be seen in the 3 test cases at the bottom)
<?php
// set debug
error_reporting(E_ALL ^ E_STRICT);
ini_set('display_errors', 'on');
class Config
{
protected $data;
public function __construct($data = null) {
$this->data = $data;
}
public function __get($name) {
return isset($this->data[$name]) ? new Config($this->data[$name]) : new Config();
}
public function isEmpty() {
return empty($this->data);
}
public function get() {
return $this->data;
}
}
$test = new Config(array(
'foo' => array(
'bar' => array(
'barfoo' => 1
)
)
));
// test 1
if (!$test->foo->bar->isEmpty()) {
print_r($test->foo->bar->get());
}
// test 2
if (!$test->foo->bar->foobar->isEmpty()) {
print_r($test->foo->bar->foobar->get());
}
// test 3
if (!$test->foo->bar->barfoo->isEmpty()) {
print_r($test->foo->bar->barfoo->get());
}
Example:
http://codepad.org/9EZ2Hqf8

Categories