Is it possible to delete fields with * RECURSION * when using toArray () in Propel?

I use Propel 2. I moisten objects through relationships, for example:

$return = OrderQuery::create() ->joinWith('Customer') ->joinWith('Status') ->find() ->toArray(TableMap::TYPE_PHPNAME, true, [], true); 

The resulting array will look something like this:

 { "Id": 1, "CustomerId": 1, "StatusId": 1, "Initiated": "2016-01-01T01:01:01+00:00", "Customer": { "Id": 1, "Forname": "Test", "Surname": "Smith", "Orders": [ "*RECURSION*" ] } "Status": { "Id": 1, "Title": "title 1", "Priority": 1, "Orders": [ "*RECURSION*" ] }, } 

I want to delete fields where the value is *RECURSION* . I tried using the $alreadyDumpedObjects (3) parameter for toArray() , but that didn't seem to help. I could also do some kind of array form coming with unset() calls, but I hope there is a better way, maybe with formatting or something else?

For bonus points, I would really like to remove the columns that define the foreign key relationship. For example, CustomerId will go, but Customer will remain.

+7
php propel propel2
source share
4 answers

The answer seems to be very simple.

If I use a standard ArrayFormatter like this:

 $return = OrderQuery::create() ->setFormatter('Propel\Runtime\Formatter\ArrayFormatter'); ->joinWith('Customer') ->joinWith('Status') ->find() ->toArray(); 

ArrayCollection returned, which when called toArray() exactly matches my original result, except for the recursion fields.

Please note: when receiving a single result, for example, using ->findPk(1) , it returns an associative array, so you should not explicitly use ->toArray() .

+1
source share

Note for brevity: this answer contains some really useful information, but there is a solution, despite this answer, saying no.


The RECURSION string is rather hardcoded in propel (in src / Propel / Generator / Builder / Orm / ObjectBuilder.php):

 if (isset(\$alreadyDumpedObjects['$objectClassName'][\$this->hashCode()])) { return '*RECURSION*'; } 

I assume you can override the constructor of objects, but I doubt what you are looking for. So the only other viable way is that you did not want to do iterate over the array and use unset. Something like that:

 $array = StudyQuery::create() ->leftJoinWithInstitute() ->find() ->toArray(); var_dump($array); echo PHP_EOL . PHP_EOL . PHP_EOL; var_dump(cleanupData($array)); /** * @param array $array * * @return array */ function cleanupData(array $array) { $relationsFound = []; foreach ($array as $key => $item) { if ($item === ["*RECURSION*"] || $item == "*RECURSION*") { unset($array[$key]); } elseif (is_array($item)) { $array[$key] = cleanupData($item); $relationsFound[] = $key; } } foreach ($relationsFound as $relation) { $key = $relation . 'Id'; if (isset($array[$key])) { unset($array[$key]); } } return $array; } 

It should also filter out *** Id fields if this relation is present (if the PHPName for the relation matches the column name).

+3
source share

When you call the toArray method in the Propel ObjectCollection, it calls toArray for each element in the collection (query result). Thus, there are two ways to achieve what you are trying to do: 1) Overwrite the toArray method in the Customer and Status model classes or in the CustomerCollection and StatusCollection (a quick & dirty solution, as it is applied every time you use the toArray method. ..). 2) Extend the ArrayFormatter class to define โ€œskip Customer and Status strategyโ€ in the format method, and then add it as the used formatter (using the setFormatter method in the collection) only when you need this particular behavior.

Some links: http://propelorm.org/documentation/reference/model-criteria.html#using-an-alternative-collection-class

http://propelorm.org/documentation/reference/model-criteria.html#using-an-alternative-formatter

+2
source share

You tried to call:

 unset($return['Customer']['Orders']); unset($return['Status']['Orders']); 
0
source share

All Articles