1*04fd306cSNickeau<?php 2*04fd306cSNickeau 3*04fd306cSNickeau 4*04fd306cSNickeaunamespace ComboStrap\Meta\Field; 5*04fd306cSNickeau 6*04fd306cSNickeauuse ComboStrap\ExceptionCompile; 7*04fd306cSNickeauuse ComboStrap\LogUtility; 8*04fd306cSNickeauuse ComboStrap\MarkupPath; 9*04fd306cSNickeauuse ComboStrap\Meta\Api\Metadata; 10*04fd306cSNickeauuse ComboStrap\Meta\Api\MetadataInteger; 11*04fd306cSNickeauuse ComboStrap\Meta\Store\MetadataDbStore; 12*04fd306cSNickeauuse ComboStrap\Meta\Store\MetadataDokuWikiStore; 13*04fd306cSNickeauuse ComboStrap\Sqlite; 14*04fd306cSNickeau 15*04fd306cSNickeau/** 16*04fd306cSNickeau * Class BacklinkCount 17*04fd306cSNickeau * @package ComboStrap 18*04fd306cSNickeau * Internal backlink count 19*04fd306cSNickeau */ 20*04fd306cSNickeauclass BacklinkCount extends MetadataInteger 21*04fd306cSNickeau{ 22*04fd306cSNickeau const PROPERTY_NAME = 'backlink_count'; 23*04fd306cSNickeau 24*04fd306cSNickeau public static function createFromResource(MarkupPath $page) 25*04fd306cSNickeau { 26*04fd306cSNickeau return (new BacklinkCount()) 27*04fd306cSNickeau ->setResource($page); 28*04fd306cSNickeau } 29*04fd306cSNickeau 30*04fd306cSNickeau static public function getDescription(): string 31*04fd306cSNickeau { 32*04fd306cSNickeau return "The number of backlinks"; 33*04fd306cSNickeau } 34*04fd306cSNickeau 35*04fd306cSNickeau static public function getLabel(): string 36*04fd306cSNickeau { 37*04fd306cSNickeau return "Backlink Count"; 38*04fd306cSNickeau } 39*04fd306cSNickeau 40*04fd306cSNickeau public static function getName(): string 41*04fd306cSNickeau { 42*04fd306cSNickeau return self::PROPERTY_NAME; 43*04fd306cSNickeau } 44*04fd306cSNickeau 45*04fd306cSNickeau static public function getPersistenceType(): string 46*04fd306cSNickeau { 47*04fd306cSNickeau return Metadata::DERIVED_METADATA; 48*04fd306cSNickeau } 49*04fd306cSNickeau 50*04fd306cSNickeau static public function isMutable(): bool 51*04fd306cSNickeau { 52*04fd306cSNickeau return false; 53*04fd306cSNickeau } 54*04fd306cSNickeau 55*04fd306cSNickeau public function buildFromReadStore(): Metadata 56*04fd306cSNickeau { 57*04fd306cSNickeau 58*04fd306cSNickeau $storeClass = get_class($this->getReadStore()); 59*04fd306cSNickeau switch ($storeClass) { 60*04fd306cSNickeau case MetadataDokuWikiStore::class: 61*04fd306cSNickeau $resource = $this->getResource(); 62*04fd306cSNickeau if (!($resource instanceof MarkupPath)) { 63*04fd306cSNickeau LogUtility::msg("Backlink count is not yet supported on the resource type ({$resource->getType()}"); 64*04fd306cSNickeau return $this; 65*04fd306cSNickeau } 66*04fd306cSNickeau $backlinks = $resource->getBacklinks(); 67*04fd306cSNickeau $this->value = sizeof($backlinks); 68*04fd306cSNickeau return $this; 69*04fd306cSNickeau case MetadataDbStore::class: 70*04fd306cSNickeau $this->value = $this->calculateBacklinkCount(); 71*04fd306cSNickeau return $this; 72*04fd306cSNickeau default: 73*04fd306cSNickeau LogUtility::msg("The store ($storeClass) does not support backlink count"); 74*04fd306cSNickeau return $this; 75*04fd306cSNickeau } 76*04fd306cSNickeau 77*04fd306cSNickeau 78*04fd306cSNickeau } 79*04fd306cSNickeau 80*04fd306cSNickeau /** 81*04fd306cSNickeau * Sqlite is much quicker than the Dokuwiki Internal Index 82*04fd306cSNickeau * We use it every time that we can 83*04fd306cSNickeau * 84*04fd306cSNickeau * @return int|null 85*04fd306cSNickeau */ 86*04fd306cSNickeau private function calculateBacklinkCount(): ?int 87*04fd306cSNickeau { 88*04fd306cSNickeau 89*04fd306cSNickeau $sqlite = Sqlite::createOrGetSqlite(); 90*04fd306cSNickeau /** @noinspection SqlResolve */ 91*04fd306cSNickeau $request = $sqlite 92*04fd306cSNickeau ->createRequest() 93*04fd306cSNickeau ->setQueryParametrized("select count(1) from PAGE_REFERENCES where REFERENCE = ? ", [$this->getResource()->getPathObject()->toAbsoluteId()]); 94*04fd306cSNickeau $count = 0; 95*04fd306cSNickeau try { 96*04fd306cSNickeau $count = $request 97*04fd306cSNickeau ->execute() 98*04fd306cSNickeau ->getFirstCellValue(); 99*04fd306cSNickeau } catch (ExceptionCompile $e) { 100*04fd306cSNickeau LogUtility::error($e->getMessage(), self::PROPERTY_NAME, $e); 101*04fd306cSNickeau } finally { 102*04fd306cSNickeau $request->close(); 103*04fd306cSNickeau } 104*04fd306cSNickeau return intval($count); 105*04fd306cSNickeau 106*04fd306cSNickeau } 107*04fd306cSNickeau 108*04fd306cSNickeau 109*04fd306cSNickeau public function setFromStoreValueWithoutException($value): Metadata 110*04fd306cSNickeau { 111*04fd306cSNickeau /** 112*04fd306cSNickeau * not used because 113*04fd306cSNickeau * the data is not stored in the database 114*04fd306cSNickeau * We overwrite and build the value {@link BacklinkCount::buildFromReadStore()} 115*04fd306cSNickeau */ 116*04fd306cSNickeau return $this; 117*04fd306cSNickeau } 118*04fd306cSNickeau 119*04fd306cSNickeau 120*04fd306cSNickeau} 121