TerIndexer.php 10.5 KB
Newer Older
1
<?php
2
namespace T3o\TerFe2\Solr\IndexQueue;
3

4
/*
5
 * This file is part of the TYPO3 CMS project.
6
 *
7 8 9
 * It is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, either version 2
 * of the License, or any later version.
10
 *
11 12
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
13
 *
14 15
 * The TYPO3 project - inspiring people to share!
 */
16

17
use ApacheSolrForTypo3\Solr\IndexQueue\Item;
18
use ApacheSolrForTypo3\Solr\System\Solr\Document\Document;
19
use T3o\TerFe2\Utility\VersionUtility;
20 21
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
22 23

/**
24
 * Class \T3o\TerFe2\Solr\IndexQueue\TerIndexer
25 26 27 28 29
 *
 * @author Sascha Egerer <sascha@sascha-egerer.de>
 * @author Thomas Löffler <thomas.loeffler@typo3.org>
 * @author Tomas Norre Mikkelsen <tomasnorre@gmail.com>
 */
Markus Sommer's avatar
Markus Sommer committed
30 31
class TerIndexer extends \ApacheSolrForTypo3\Solr\IndexQueue\Indexer
{
32 33

    /**
34
     * @var \TYPO3\CMS\Extbase\Object\ObjectManager
35 36 37 38
     */
    protected $objectManager;

    /**
39
     * @var \T3o\TerFe2\Domain\Repository\ExtensionRepository
40 41 42
     */
    protected $extensionRepository;

43
    public function __construct(array $options = [])
Markus Sommer's avatar
Markus Sommer committed
44
    {
45 46
        parent::__construct($options);

47
        $this->objectManager = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
48
        $this->extensionRepository = $this->objectManager->get(\T3o\TerFe2\Domain\Repository\ExtensionRepository::class);
49

Markus Sommer's avatar
Markus Sommer committed
50
        $this->extensionRepository->setShowInsecure(false);
51 52 53
    }

    /**
54 55 56 57 58
     * Converts an item array (record) to a Solr document by mapping the
     * record's fields onto Solr document fields as configured in TypoScript.
     *
     * @param Item $item An index queue item
     * @param int $language Language Id
59
     * @return \ApacheSolrForTypo3\Solr\System\Solr\Document\Document The Solr document converted from the record
60
     */
61
    protected function itemToDocument(Item $item, $language = 0): Document
62 63 64 65
    {
        $document = null;

        $itemRecord = $this->getFullItemRecord($item, $language);
66
        if ($itemRecord !== null) {
Markus Sommer's avatar
Markus Sommer committed
67 68 69 70
            $itemIndexingConfiguration = $this->getItemTypeConfiguration(
                $item,
                $language
            );
71 72 73 74 75

            $document = $this->getBaseDocument($item, $itemRecord);
            $document = $this->addDocumentFieldsFromTyposcript($document, $itemIndexingConfiguration, $itemRecord);
            $document = $this->addSpecialFields($document, $itemRecord);
        }
76

77 78
        return $document;
    }
79

80
    /**
81
     * @param \ApacheSolrForTypo3\Solr\System\Solr\Document\Document $document
82
     * @param array $itemRecord
83
     * @return \ApacheSolrForTypo3\Solr\System\Solr\Document\Document
84
     */
85
    public function addSpecialFields(Document $document, array $itemRecord): Document
86 87 88
    {
        $extension = $this->extensionRepository->findByUid($itemRecord['uid']);

89
        if ($extension instanceof \T3o\TerFe2\Domain\Model\Extension && $extension->getLastVersion() instanceof \T3o\TerFe2\Domain\Model\Version) {
90 91 92
            $typo3Dependency = $this->getDependencyVersionForPackage($extension, 'typo3');
            $document->setField('extensionMinTYPO3Version_tIntS', $typo3Dependency['minimum']);
            $document->setField('extensionMaxTYPO3Version_tIntS', $typo3Dependency['maximum']);
93

94 95 96 97 98
            $dependencyString = '';
            $dependencyString .= $typo3Dependency['minimum'] > 0 ? VersionNumberUtility::convertIntegerToVersionNumber($typo3Dependency['minimum']) : '';
            $dependencyString .= $typo3Dependency['maximum'] > 0 ? ' - ' . VersionNumberUtility::convertIntegerToVersionNumber($typo3Dependency['maximum']) : '';
            $document->setField('extensionDependency_stringS', $dependencyString ?: 'N/A');

99 100
            // is last version insecure
            $document->setField('insecure_boolS', $extension->getLastVersion()->getReviewState() === -1);
101
            $document->setField('outdated_boolS', $extension->getLastVersion()->getReviewState() === -2);
Thomas Löffler's avatar
Thomas Löffler committed
102

Thomas Löffler's avatar
Thomas Löffler committed
103 104 105
            // composer support
            $document->setField('supportsComposer_boolS', false);
            $document->setField('composerName_stringS', '');
106
            if ($extension->getComposerName()) {
Thomas Löffler's avatar
Thomas Löffler committed
107
                $document->setField('supportsComposer_boolS', true);
108
                $document->setField('composerName_stringS', $extension->getComposerName());
Thomas Löffler's avatar
Thomas Löffler committed
109 110
            }

Thomas Löffler's avatar
Thomas Löffler committed
111
            // does this extension supports different versions?
112 113 114 115 116 117 118 119 120
            $supportMaintainedVersions = [];
            $supportDevVersion = '';
            $supportOlderVersions = [];

            $ltsVersionService = GeneralUtility::makeInstance(\T3o\TerFe2\Service\LTSVersionService::class);
            foreach ($ltsVersionService->getCurrentStableVersions(true) as $versionNumber) {
                if (VersionUtility::doesExtensionSupportTypo3Version($extension, $versionNumber)) {
                    $supportMaintainedVersions[] = $ltsVersionService->getVersionLabelOfRelease($versionNumber) . ' LTS';
                }
Thomas Löffler's avatar
Thomas Löffler committed
121
            }
122 123
            if ($ltsVersionService->getLatestDevelopmentVersion() !== $ltsVersionService->getLatestLTS() && VersionUtility::doesExtensionSupportTypo3Version($extension, $ltsVersionService->getLatestDevelopmentVersion(true))) {
                $supportDevVersion = $ltsVersionService->getLatestDevelopmentVersion() . '-dev';
Thomas Löffler's avatar
Thomas Löffler committed
124
            }
125 126 127 128 129 130 131 132 133 134 135

            foreach ($ltsVersionService->getOldLTSVersions() as $versionNumber) {
                if (VersionUtility::doesExtensionSupportTypo3Version($extension, $versionNumber)) {
                    $supportOlderVersions[] = $ltsVersionService->getVersionLabelOfRelease($versionNumber) . ' LTS';
                }
            }

            $document->setField('typo3support_stringM', $supportMaintainedVersions);
            $facetVersions = $supportMaintainedVersions;
            if ($supportDevVersion) {
                $facetVersions = array_merge($supportMaintainedVersions, [$supportDevVersion]);
136
            }
137 138 139
            $document->setField('typo3supportfacets_stringM', $facetVersions);
            $document->setField('typo3supportdev_stringS', $supportDevVersion);
            $document->setField('typo3supportold_stringM', $supportOlderVersions);
Thomas Löffler's avatar
Thomas Löffler committed
140

141 142 143
            $extensionIcon = $this->getExtensionIcon($itemRecord['ext_key'], $extension->getLastVersion()->getVersionString());
            $document->setField('extensionIcon_stringS', $extensionIcon);

Thomas Löffler's avatar
Thomas Löffler committed
144 145 146
            // add extension likes count
            $document->setField('likes_intS', $extension->getLikes());

Thomas Löffler's avatar
Thomas Löffler committed
147
            // add documentation link
148 149
            /** @var \T3o\TerFe2\Service\DocumentationService $documentationService */
            $documentationService = GeneralUtility::makeInstance(\T3o\TerFe2\Service\DocumentationService::class);
150
            $documentationLink = $documentationService->getDocumentationLink($extension->getExtKey(), $extension->getLastVersion()->getVersionString(), true);
Thomas Löffler's avatar
Thomas Löffler committed
151
            $document->setField('extensionDocumentationLink_stringS', $documentationLink);
152

153 154 155 156 157
            // use external manual if given
            if ($extension->getExternalManual()) {
                $document->setField('extensionDocumentationLink_stringS', $extension->getExternalManual());
            }

158 159 160 161 162 163
            // has manual
            $document->setField('hasManual_boolS', false);
            if ($documentationLink || $extension->getExternalManual()) {
                $document->setField('hasManual_boolS', true);
            }

164
            // get multiple authors
Thomas Löffler's avatar
Thomas Löffler committed
165 166 167
            $authors = [];
            if ($extension->getLastVersion() && $extension->getLastVersion()->getAuthor()) {
                $authors = GeneralUtility::trimExplode(',', $extension->getLastVersion()->getAuthor()->getName());
168 169 170 171
                if ($extension->getLastVersion()->getAuthor()->getCompany()) {
                    // Add company name to author
                    $authors[] = $extension->getLastVersion()->getAuthor()->getCompany();
                }
Thomas Löffler's avatar
Thomas Löffler committed
172
            }
173
            $document->setField('author_textWstM', $authors);
174 175
        }

176
        return $document;
177 178 179 180 181
    }

    /**
     * get the minimum dependency of an extension for a given $relationName (extension, php version, TYPO3 version...)
     *
182
     * @param \T3o\TerFe2\Domain\Model\Extension $extension
183
     * @param string $relationName The dependency to get the version from (e.g. "typo3" to get the minimum typo3 version)
Thomas Löffler's avatar
Thomas Löffler committed
184
     * @return array
185
     */
Markus Sommer's avatar
Markus Sommer committed
186 187
    protected function getDependencyVersionForPackage(\T3o\TerFe2\Domain\Model\Extension $extension, $relationName)
    {
188
        $versions = [
189 190
            'minimum' => 0,
            'maximum' => 0
191
        ];
192 193 194

        foreach ($extension->getLastVersion()->getSoftwareRelations() as $relation) {
            if ($relation->getRelationType() === 'depends' && $relation->getRelationKey() === $relationName) {
195
                $versions = [
196 197
                    'minimum' => $relation->getMinimumVersion(),
                    'maximum' => $relation->getMaximumVersion()
198
                ];
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
                break;
            }
        }

        return $versions;
    }

    /**
     * get the relative path for the extension icon
     * could be png or gif
     *
     * @param $extensionKey
     * @param $extensionVersion
     * @return string
     */
Markus Sommer's avatar
Markus Sommer committed
214 215
    protected function getExtensionIcon($extensionKey, $extensionVersion)
    {
216 217 218
        $fileTypesToCheck = [
            'svg',
            'png',
219
            'gif'
220
        ];
221 222 223 224

        $iconPath = 'fileadmin/ter/';
        $icon = '';

225 226 227 228 229 230 231
        foreach ($fileTypesToCheck as $fileType) {
            $iconFile = $this->generateIconFileName(
                $extensionKey,
                $extensionVersion,
                $fileType
            );
            if (file_exists(PATH_site . $iconPath . $iconFile)) {
232
                $icon = \T3o\TerFe2\Utility\FileUtility::getRelativeUrlFromAbsolutePath($iconPath . $iconFile);
233 234
                break;
            }
235 236 237 238 239 240 241 242 243 244 245 246 247
        }

        return $icon;
    }

    /**
     * generate the path to an extension icon for a specific version
     *
     * @param $extension
     * @param $version
     * @param $fileType
     * @return string
     */
Markus Sommer's avatar
Markus Sommer committed
248 249
    protected function generateIconFileName($extension, $version, $fileType)
    {
250 251 252 253 254 255 256
        if (empty($extension) || empty($version) || empty($fileType)) {
            return '';
        }
        $extension = strtolower($extension);
        $fileType = strtolower(trim($fileType, '. '));
        return $extension[0] . '/' . $extension[1] . '/' . $extension . '_' . $version . '.' . $fileType;
    }
257
}