<?php
 class vB_BbCodeDataCache { use vB_Trait_NoSerialize; private $bbcodeInstances = []; private array $lookupMap = []; private array $nodeidMap = []; private array $newlyAdded = []; private $nodeid = 0; public function __construct(vB_BbCodeHelper $bbcodeHelper, public ?vB_Interface_UrlCache $urlCache = null, $nodeids = null) { if (!empty($nodeids)) { $assertor = vB::getDbAssertor(); $query = $assertor->assertQuery('bbcode_data', ['nodeid' => $nodeids]); $urlsToPrefetch = []; foreach ($query AS $__row) { $__class = vB_BbCode::determineClassname($__row['bbcode_type']); if (!$__class) { continue; } if ($__class::USES_DATA_STORAGE) { $__instance = $__class::restoreFromDBRecord($bbcodeHelper, $__row); $this->registerInstance($__instance, $__row['nodeid'], $__row['hash']); $__url = $__instance->data['url'] ?? null; if ($__url) { $urlsToPrefetch[] = $__url; } } } if (count($urlsToPrefetch) AND $urlCache) { $urlCache->prefetchCachedUrls($urlsToPrefetch); } } } private function registerInstance(vB_BbCode $instance, int $nodeid, string $hash) : int { $classname = $instance::getCanonicalClassname(); $this->bbcodeInstances[] = $instance; $lastKey = array_key_last($this->bbcodeInstances); $this->lookupMap[$nodeid][$classname][$hash] = $lastKey; $this->nodeidMap[$nodeid][] = $lastKey; return $lastKey; } public function getBbcodeInstance(vB_BbCodeHelper $bbcodeHelper, int $nodeid, string $typeOrClass, string $data, ?string $option = null) : ?vB_BbCode { $class = vB_BbCode::determineClassname($typeOrClass); if (!$class) { return null; } $type = $class::getCanonicalClassname(); $hash = $class::getHash($bbcodeHelper, $data, $option); if (!isset($this->lookupMap[$nodeid][$type][$hash])) { $instance = $class::generateFreshFromDataAndOption($bbcodeHelper, $data, $option); $instance->nodeid = $nodeid; $addedkey = $this->registerInstance($instance, $nodeid, $hash); $this->newlyAdded[] = $addedkey; } $key = $this->lookupMap[$nodeid][$type][$hash] ?? null; return $this->bbcodeInstances[$key] ?? null; } public function cleanExisting($nodeid) { if (empty($nodeid)) { return; } foreach ($this->nodeidMap[$nodeid] ?? [] AS $__key) { unset($this->bbcodeInstances[$__key]); } $this->lookupMap[$nodeid] = []; $this->nodeidMap[$nodeid] = []; $assertor = vB::getDbAssertor(); $assertor->delete('bbcode_data', ['nodeid' => $nodeid]); } public function saveChanges() { $data = []; foreach ($this->bbcodeInstances AS $__bbcode) { if ($__bbcode::USES_DATA_STORAGE) { if ($__bbcode->modified AND $__bbcode->nodeid AND $__bbcode->hash) { $data[] = $__bbcode->getInsertData(); } } } $assertor = vB::getDbAssertor(); if (!empty($data)) { $assertor->assertQuery('bulkUpsertBbCodeData', ['data' => $data]); } } } 