Passed
Pull Request — master (#70)
by Alexander
03:07
created

AbstractPlugin::pi_linkTP_fallback()   B

Complexity

Conditions 8
Paths 128

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 8
c 1
b 0
f 0
dl 0
loc 11
rs 8.2111
cc 8
nc 128
nop 4
1
<?php
2
3
/**
4
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
5
 *
6
 * This file is part of the Kitodo and TYPO3 projects.
7
 *
8
 * @license GNU General Public License version 3 or later.
9
 * For the full copyright and license information, please read the
10
 * LICENSE.txt file that was distributed with this source code.
11
 */
12
13
namespace Kitodo\Dlf\Common;
14
15
use Psr\Log\LoggerAwareInterface;
16
use Psr\Log\LoggerAwareTrait;
17
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
18
use TYPO3\CMS\Core\Database\ConnectionPool;
19
use TYPO3\CMS\Core\Service\MarkerBasedTemplateService;
20
use TYPO3\CMS\Core\Utility\GeneralUtility;
21
use TYPO3\CMS\Core\Utility\HttpUtility;
22
23
/**
24
 * Abstract plugin class for the 'dlf' extension
25
 *
26
 * @author Sebastian Meyer <[email protected]>
27
 * @package TYPO3
28
 * @subpackage dlf
29
 * @access public
30
 * @abstract
31
 */
32
abstract class AbstractPlugin extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin implements LoggerAwareInterface
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Frontend\Plugin\AbstractPlugin was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
33
{
34
    use LoggerAwareTrait;
35
36
    public $extKey = 'dlf';
37
    public $prefixId = 'tx_dlf';
38
    public $scriptRelPath = 'Classes/Common/AbstractPlugin.php';
39
    // Plugins are cached by default (@see setCache()).
40
    public $pi_USER_INT_obj = false;
41
    public $pi_checkCHash = true;
42
43
    /**
44
     * This holds the current document
45
     *
46
     * @var \Kitodo\Dlf\Common\Document
47
     * @access protected
48
     */
49
    protected $doc;
50
51
    /**
52
     * This holds the plugin's parsed template
53
     *
54
     * @var string
55
     * @access protected
56
     */
57
    protected $template = '';
58
59
    /**
60
     * This holds the plugin's service for template
61
     *
62
     * @var \TYPO3\CMS\Core\Service\MarkerBasedTemplateService
63
     * @access protected
64
     */
65
    protected $templateService;
66
67
    /**
68
     * Read and parse the template file
69
     *
70
     * @access protected
71
     *
72
     * @param string $part: Name of the subpart to load
73
     *
74
     * @return void
75
     */
76
    protected function getTemplate($part = '###TEMPLATE###')
77
    {
78
        $this->templateService = GeneralUtility::makeInstance(MarkerBasedTemplateService::class);
79
        if (!empty($this->conf['templateFile'])) {
80
            // Load template file from configuration.
81
            $templateFile = $this->conf['templateFile'];
82
        } else {
83
            // Load default template from extension.
84
            $templateFile = 'EXT:' . $this->extKey . '/Resources/Private/Templates/' . Helper::getUnqualifiedClassName(get_class($this)) . '.tmpl';
85
        }
86
        // Substitute strings like "EXT:" in given template file location.
87
        $fileResource = $GLOBALS['TSFE']->tmpl->getFileName($templateFile);
88
        $this->template = $this->templateService->getSubpart(file_get_contents($fileResource), $part);
89
    }
90
91
    /**
92
     * All the needed configuration values are stored in class variables
93
     * Priority: Flexforms > TS-Templates > Extension Configuration > ext_localconf.php
94
     *
95
     * @access protected
96
     *
97
     * @param array $conf: Configuration array from TS-Template
98
     *
99
     * @return void
100
     */
101
    protected function init(array $conf)
102
    {
103
        // Read FlexForm configuration.
104
        $flexFormConf = [];
105
        $this->cObj->readFlexformIntoConf($this->cObj->data['pi_flexform'], $flexFormConf);
106
        if (!empty($flexFormConf)) {
107
            $conf = Helper::mergeRecursiveWithOverrule($flexFormConf, $conf);
108
        }
109
        // Read plugin TS configuration.
110
        $pluginConf = $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_dlf_' . strtolower(Helper::getUnqualifiedClassName(get_class($this))) . '.'];
111
        if (is_array($pluginConf)) {
112
            $conf = Helper::mergeRecursiveWithOverrule($pluginConf, $conf);
113
        }
114
        // Read general TS configuration.
115
        $generalConf = $GLOBALS['TSFE']->tmpl->setup['plugin.'][$this->prefixId . '.'];
116
        if (is_array($generalConf)) {
117
            $conf = Helper::mergeRecursiveWithOverrule($generalConf, $conf);
118
        }
119
        // Read extension configuration.
120
        if (isset($GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][$this->extKey]) && is_array($GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][$this->extKey])) {
121
            $extConf = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get($this->extKey);
122
            if (is_array($extConf)) {
123
                $conf = Helper::mergeRecursiveWithOverrule($extConf, $conf);
124
            }
125
        }
126
        $this->conf = $conf;
0 ignored issues
show
Bug Best Practice introduced by
The property conf does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
127
        // Set default plugin variables.
128
        $this->pi_setPiVarDefaults();
129
        // Load translation files.
130
        $this->pi_loadLL('EXT:' . $this->extKey . '/Resources/Private/Language/' . Helper::getUnqualifiedClassName(get_class($this)) . '.xml');
131
    }
132
133
    /**
134
     * Loads the current document into $this->doc
135
     *
136
     * @access protected
137
     *
138
     * @return void
139
     */
140
    protected function loadDocument()
141
    {
142
        // Check for required variable.
143
        if (
144
            !empty($this->piVars['id'])
145
            && !empty($this->conf['pages'])
146
        ) {
147
            // Should we exclude documents from other pages than $this->conf['pages']?
148
            $pid = (!empty($this->conf['excludeOther']) ? intval($this->conf['pages']) : 0);
149
            // Get instance of \Kitodo\Dlf\Common\Document.
150
            $this->doc = Document::getInstance($this->piVars['id'], $pid);
151
            if (!$this->doc->ready) {
152
                // Destroy the incomplete object.
153
                $this->doc = null;
154
                $this->logger->error('Failed to load document with UID ' . $this->piVars['id']);
0 ignored issues
show
Bug introduced by
The method error() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

154
                $this->logger->/** @scrutinizer ignore-call */ 
155
                               error('Failed to load document with UID ' . $this->piVars['id']);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
155
            } else {
156
                // Set configuration PID.
157
                $this->doc->cPid = $this->conf['pages'];
158
            }
159
        } elseif (!empty($this->piVars['recordId'])) {
160
            $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
161
                ->getQueryBuilderForTable('tx_dlf_documents');
162
163
            // Get UID of document with given record identifier.
164
            $result = $queryBuilder
165
                ->select('tx_dlf_documents.uid AS uid')
166
                ->from('tx_dlf_documents')
167
                ->where(
168
                    $queryBuilder->expr()->eq('tx_dlf_documents.record_id', $queryBuilder->expr()->literal($this->piVars['recordId'])),
169
                    Helper::whereExpression('tx_dlf_documents')
170
                )
171
                ->setMaxResults(1)
172
                ->execute();
173
174
            if ($resArray = $result->fetch()) {
175
                $this->piVars['id'] = $resArray['uid'];
0 ignored issues
show
Bug Best Practice introduced by
The property piVars does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
176
                // Set superglobal $_GET array and unset variables to avoid infinite looping.
177
                $_GET[$this->prefixId]['id'] = $this->piVars['id'];
178
                unset($this->piVars['recordId'], $_GET[$this->prefixId]['recordId']);
179
                // Try to load document.
180
                $this->loadDocument();
181
            } else {
182
                $this->logger->error('Failed to load document with record ID "' . $this->piVars['recordId'] . '"');
183
            }
184
        } else {
185
            $this->logger->error('Invalid UID ' . $this->piVars['id'] . ' or PID ' . $this->conf['pages'] . ' for document loading');
186
        }
187
    }
188
189
    /**
190
     * The main method of the PlugIn
191
     *
192
     * @access public
193
     *
194
     * @param string $content: The PlugIn content
195
     * @param array $conf: The PlugIn configuration
196
     *
197
     * @abstract
198
     *
199
     * @return string The content that is displayed on the website
200
     */
201
    abstract public function main($content, $conf);
202
203
    /**
204
     * Parses a string into a Typoscript array
205
     *
206
     * @access protected
207
     *
208
     * @param string $string: The string to parse
209
     *
210
     * @return array The resulting typoscript array
211
     */
212
    protected function parseTS($string = '')
213
    {
214
        $parser = GeneralUtility::makeInstance(\TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser::class);
215
        $parser->parse($string);
216
        return $parser->setup;
217
    }
218
219
    /**
220
     * Link string to the current page.
221
     * @see \TYPO3\CMS\Frontend\Plugin\AbstractPlugin->pi_linkTP()
222
     *
223
     * @access public
224
     *
225
     * @param string $str: The content string to wrap in <a> tags
226
     * @param array $urlParameters: Array with URL parameters as key/value pairs
227
     * @param bool $cache: Should the "no_cache" parameter be added?
228
     * @param int $altPageId: Alternative page ID for the link.
229
     *
230
     * @return string The input string wrapped in <a> tags
231
     */
232
    public function pi_linkTP($str, $urlParameters = [], $cache = false, $altPageId = 0)
233
    {
234
        $conf = [];
235
        if (!$cache) {
236
            $conf['no_cache'] = true;
237
        }
238
        $conf['parameter'] = $altPageId ?: ($this->pi_tmpPageId ?: 'current');
239
        $conf['additionalParams'] = $this->conf['parent.']['addParams'] . HttpUtility::buildQueryString($urlParameters, '&', true) . $this->pi_moreParams;
240
        // Add additional configuration for absolute URLs.
241
        $conf['forceAbsoluteUrl'] = !empty($this->conf['forceAbsoluteUrl']) ? 1 : 0;
242
        $conf['forceAbsoluteUrl.']['scheme'] = !empty($this->conf['forceAbsoluteUrl']) && !empty($this->conf['forceAbsoluteUrlHttps']) ? 'https' : 'http';
243
        return $this->cObj->typoLink($str, $conf);
244
    }
245
246
    /**
247
     * Wraps the input string in a <div> tag with the class attribute set to the class name
248
     * @see \TYPO3\CMS\Frontend\Plugin\AbstractPlugin->pi_wrapInBaseClass()
249
     *
250
     * @access public
251
     *
252
     * @param string $content: HTML content to wrap in the div-tags with the class of the plugin
253
     *
254
     * @return string HTML content wrapped, ready to return to the parent object.
255
     */
256
    public function pi_wrapInBaseClass($content)
257
    {
258
        if (!$this->frontendController->config['config']['disableWrapInBaseClass']) {
259
            // Use class name instead of $this->prefixId for content wrapping because $this->prefixId is the same for all plugins.
260
            $content = '<div class="tx-dlf-' . strtolower(Helper::getUnqualifiedClassName(get_class($this))) . '">' . $content . '</div>';
261
            if (!$this->frontendController->config['config']['disablePrefixComment']) {
262
                $content = "\n\n<!-- BEGIN: Content of extension '" . $this->extKey . "', plugin '" . Helper::getUnqualifiedClassName(get_class($this)) . "' -->\n\n" . $content . "\n\n<!-- END: Content of extension '" . $this->extKey . "', plugin '" . Helper::getUnqualifiedClassName(get_class($this)) . "' -->\n\n";
263
            }
264
        }
265
        return $content;
266
    }
267
268
    /**
269
     * Sets some configuration variables if the plugin is cached.
270
     *
271
     * @access protected
272
     *
273
     * @param bool $cache: Should the plugin be cached?
274
     *
275
     * @return void
276
     */
277
    protected function setCache($cache = true)
278
    {
279
        if ($cache) {
280
            // Set cObject type to "USER" (default).
281
            $this->pi_USER_INT_obj = false;
282
            $this->pi_checkCHash = true;
283
            if (count($this->piVars)) {
284
                // Check cHash or disable caching.
285
                $GLOBALS['TSFE']->reqCHash();
286
            }
287
        } else {
288
            // Set cObject type to "USER_INT".
289
            $this->pi_USER_INT_obj = true;
290
            $this->pi_checkCHash = false;
291
            // Plugins are of type "USER" by default, so convert it to "USER_INT".
292
            $this->cObj->convertToUserIntObject();
293
        }
294
    }
295
}
296