implode_escape(self::hiddenTypes()) . ')'; } /** * One active row per type that this agent must have, lowest id. * * @return int[] */ public static function idsFor(array $aAgent): array { $aTypes = self::typesFor($aAgent); if (!$aTypes) return []; $aIds = []; $aSeen = []; foreach ((new BxDolAiQuery())->getActiveToolsByTypes($aTypes) as $aRow) { $sType = (string)$aRow['type']; if (isset($aSeen[$sType])) continue; $aSeen[$sType] = true; $aIds[] = (int)$aRow['id']; } return $aIds; } /** * Every row of a locked type, including inactive copies, so a stored id cannot grant one. * * @return int[] */ public static function hiddenIds(): array { $aTypes = self::hiddenTypes(); if (!$aTypes) return []; return (new BxDolAiQuery())->getToolIdsByTypes($aTypes); } /** * Stored ids minus locked ones, plus the ids this agent always has. * * @return int[] */ public static function resolveIds(array $aAgent): array { $aIds = []; if (!empty($aAgent['tools'])) { foreach (explode(',', (string)$aAgent['tools']) as $sToolId) { $iToolId = (int)trim($sToolId); if ($iToolId > 0) $aIds[$iToolId] = $iToolId; } } foreach (self::hiddenIds() as $iHidden) unset($aIds[$iHidden]); foreach (self::idsFor($aAgent) as $iId) $aIds[$iId] = $iId; return array_values($aIds); } public static function stripCsv(string $sTools): string { $sTools = trim($sTools); if ($sTools === '') return ''; $aHidden = array_flip(self::hiddenIds()); $aKeep = []; foreach (explode(',', $sTools) as $sId) { $iId = (int)trim($sId); if ($iId <= 0 || isset($aHidden[$iId])) continue; $aKeep[$iId] = $iId; } return implode(',', $aKeep); } } /** @} */