Skip to content

Commit 47c48b1

Browse files
committed
Support fetching multiple resourceIds at once.
Still needs some work to cope with multiple different modules in an array of external IDs being searched for at once.
1 parent 6250553 commit 47c48b1

File tree

2 files changed

+65
-15
lines changed

2 files changed

+65
-15
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,14 @@ The following methods are supported and will return an XML-RPC response:
9090
* searchRead()
9191
* read()
9292

93-
The following helper functions return a native PHp type insead:
93+
The following helper functions return a native PHP type insead:
9494

9595
* searchArray - array
9696
* searchReadArray - array
9797
* readArray - array
9898
* searchCount - integer
9999
* getResourceId - integer
100+
* getResourceId2 - array
100101

101102
(I'm torn between this approach and a more fluent approach such as
102103
`$client->firstOnly()->asArray()->read(...)`)

src/OdooClient.php

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -474,47 +474,96 @@ public function version()
474474
*/
475475
public function getResourceId(string $externalId, string $model = null)
476476
{
477+
$resourceIds = $this->getResourceIds([$externalId], $model);
478+
479+
return collect($resourceIds)->first();
480+
}
481+
482+
/**
483+
* Get multiple resource IDs at once.
484+
*
485+
* @param array $externalIds each either "name" or "module.name"
486+
* @param string $module optional, but recommended
487+
* @return int|null
488+
*
489+
* FIXME: all external IDs must have the same "module" at the moment.
490+
*/
491+
public function getResourceIds(
492+
array $externalIds,
493+
string $model = null,
494+
$offset = 0,
495+
$limit = self::DEFAULT_LIMIT,
496+
$order = ''
497+
) {
477498
$criteria = [];
478499

479500
if ($model !== null) {
480501
$criteria[] = ['model', '=', 'res.partner'];
481502
}
482503

483-
if (strpos($externalId, '.') !== false) {
484-
list ($module, $name) = explode('.', $externalId, 2);
504+
$moduleList = [];
485505

486-
$criteria[] = ['module', '=', $module];
487-
} else {
488-
$name = $externalId;
506+
foreach($externalIds as $externalId) {
507+
if (strpos($externalId, '.') !== false) {
508+
list ($module, $name) = explode('.', $externalId, 2);
509+
} else {
510+
$name = $externalId;
511+
$module = '{none}';
512+
}
513+
514+
if (! array_key_exists($module, $moduleList)) {
515+
$moduleList[$module] = [];
516+
}
517+
518+
$moduleList[$module][] = $name;
489519
}
490520

491-
$criteria[] = ['name', '=', $name];
521+
// TODO: work out how to represent the boolean OR operator
522+
// for multiple modules fetched at once.
523+
// Each set of conditions in this loop should be ORed with
524+
// every other set of conditions in this loop.
525+
// So we should be able to search for "foo.bar_123" and "fing.bing_456"
526+
// in one query, giving us conceptually:
527+
// ((module = foo and name = bar_123) or (module = fing and name = bing_456))
528+
529+
foreach($moduleList as $module => $externalIds) {
530+
if ($module !== '{none}') {
531+
$criteria[] = ['module', '=', $module];
532+
}
533+
534+
$criteria[] = ['name', 'in', $externalIds];
535+
}
492536

493-
$irModelDataIds = $this->searchArray('ir.model.data', $criteria);
494-
$irModelDataId = collect($irModelDataIds)->first();
537+
$irModelDataIds = $this->searchArray(
538+
'ir.model.data',
539+
$criteria,
540+
$offset,
541+
$limit,
542+
$order
543+
);
495544

496-
if ($irModelDataId === null) {
545+
if (empty($irModelDataIds)) {
497546
// No matches found, so give up now.
498547
return;
499548
}
500549

501-
// Now read the full record to get the resource ID.
550+
// Now read the full records to get the resource IDs.
502551

503552
$irModelDataArray = $this->readArray(
504553
'ir.model.data',
505-
[$irModelDataId]
554+
$irModelDataIds
506555
);
507-
$irModelData = collect($irModelDataArray)->first();
556+
$irModelData = collect($irModelDataArray);
508557

509558
if ($irModelData === null) {
510559
// We could not find the record.
511560
// (We really should have, since we just looked it up)
512561
return;
513562
}
514563

515-
// Return the resource ID.
564+
// Return the resource IDs.
516565

517-
return $irModelData['res_id'];
566+
return $irModelData->pluck('res_id')->toArray();
518567
}
519568

520569
/**

0 commit comments

Comments
 (0)