MetaStatements.php 8.51 KB
Newer Older
1
<?php
Tino Goratsch's avatar
Tino Goratsch committed
2

3
/**
4
 * Copyright (c) by the ACP3 Developers.
Tino Goratsch's avatar
Tino Goratsch committed
5
 * See the LICENSE file at the top-level module directory for licensing details.
6 7 8 9 10 11
 */

namespace ACP3\Modules\ACP3\Seo\Helper;

use ACP3\Core\Controller\AreaEnum;
use ACP3\Core\Http\RequestInterface;
12
use ACP3\Core\Modules;
13
use ACP3\Core\Router\RouterInterface;
14
use ACP3\Core\Settings\SettingsInterface;
15
use ACP3\Modules\ACP3\Seo\Cache as SeoCache;
16
use ACP3\Modules\ACP3\Seo\Installer\Schema;
17 18 19 20 21 22 23

class MetaStatements
{
    /**
     * @var \ACP3\Core\Http\RequestInterface
     */
    protected $request;
24 25 26 27
    /**
     * @var RouterInterface
     */
    private $router;
28
    /**
29
     * @var \ACP3\Core\Settings\SettingsInterface
30 31 32 33 34 35 36
     */
    protected $config;
    /**
     * @var \ACP3\Modules\ACP3\Seo\Cache
     */
    protected $seoCache;

37 38 39 40
    /**
     * @var null|array
     */
    protected $aliasesCache;
41 42 43 44 45 46 47 48 49 50 51 52 53
    /**
     * @var string
     */
    protected $nextPage = '';
    /**
     * @var string
     */
    protected $previousPage = '';
    /**
     * @var string
     */
    protected $canonicalUrl = '';
    /**
54
     * @var string
55
     */
56
    protected $metaDescriptionPostfix = '';
57 58 59
    /**
     * @var string
     */
60
    private $metaRobots = '';
61 62 63 64
    /**
     * @var bool
     */
    private $isActive;
65

66 67 68 69 70 71 72
    private static $robotSettingsMaps = [
        1 => 'index,follow',
        2 => 'index,nofollow',
        3 => 'noindex,follow',
        4 => 'noindex,nofollow',
    ];

73 74 75
    /**
     * MetaStatements constructor.
     *
76 77 78 79
     * @param \ACP3\Core\Http\RequestInterface      $request
     * @param RouterInterface                       $router
     * @param Modules                               $modules
     * @param \ACP3\Modules\ACP3\Seo\Cache          $seoCache
80
     * @param \ACP3\Core\Settings\SettingsInterface $config
81 82 83
     */
    public function __construct(
        RequestInterface $request,
84
        RouterInterface $router,
85
        Modules $modules,
86
        SeoCache $seoCache,
87
        SettingsInterface $config
88 89 90 91
    ) {
        $this->request = $request;
        $this->seoCache = $seoCache;
        $this->config = $config;
92
        $this->isActive = $modules->isActive(Schema::MODULE_NAME);
93
        $this->router = $router;
94 95
    }

96 97
    /**
     * @param string $metaRobots
98
     *
99 100
     * @return $this
     */
101
    public function setPageRobotsSettings(string $metaRobots)
102 103 104 105 106 107
    {
        $this->metaRobots = $metaRobots;

        return $this;
    }

108
    /**
109
     * Returns the meta tags of the current page.
110
     *
111
     * @return array
112
     */
113
    public function getMetaTags(): array
114
    {
115
        if ($this->isActive) {
116 117 118 119
            if (!$this->isInAdmin() && empty($this->canonicalUrl)) {
                $this->canonicalUrl = $this->router->route($this->request->getQuery());
            }

120 121 122 123 124 125 126 127 128 129 130
            return [
                'description' => $this->isInAdmin() ? '' : $this->getPageDescription(),
                'keywords' => $this->isInAdmin() ? '' : $this->getPageKeywords(),
                'robots' => $this->isInAdmin() ? 'noindex,nofollow' : $this->getPageRobotsSetting(),
                'previous_page' => $this->previousPage,
                'next_page' => $this->nextPage,
                'canonical' => $this->canonicalUrl,
            ];
        }

        return [];
131 132
    }

133 134 135
    /**
     * @return bool
     */
136
    private function isInAdmin(): bool
137 138 139 140
    {
        return $this->request->getArea() === AreaEnum::AREA_ADMIN;
    }

141
    /**
142
     * Returns the SEO description of the current page.
143 144 145
     *
     * @return string
     */
146
    public function getPageDescription(): string
147 148 149 150 151 152 153 154 155
    {
        $description = $this->getDescription($this->request->getUriWithoutPages());
        if (empty($description)) {
            $description = $this->getDescription($this->request->getFullPath());
        }
        if (empty($description)) {
            $description = $this->getDescription($this->request->getModule());
        }
        if (empty($description)) {
156
            $description = $this->getSeoSettings()['meta_description'];
157 158 159 160 161 162 163 164 165 166
        }

        $postfix = '';
        if (!empty($description) && !empty($this->metaDescriptionPostfix)) {
            $postfix .= ' - ' . $this->metaDescriptionPostfix;
        }

        return $description . $postfix;
    }

167 168 169
    /**
     * @return array
     */
170
    protected function getSeoSettings(): array
171 172 173 174
    {
        return $this->config->getSettings(Schema::MODULE_NAME);
    }

175
    /**
176
     * Returns the SEO description of the given page.
177 178 179 180 181
     *
     * @param string $path
     *
     * @return string
     */
182
    public function getDescription(string $path): string
183 184 185 186 187
    {
        return $this->getSeoInformation($path, 'description');
    }

    /**
188
     * Returns the SEO keywords of the current page.
189 190 191
     *
     * @return string
     */
192
    public function getPageKeywords(): string
193 194 195 196 197 198 199 200 201
    {
        $keywords = $this->getKeywords($this->request->getUriWithoutPages());
        if (empty($keywords)) {
            $keywords = $this->getKeywords($this->request->getFullPath());
        }
        if (empty($keywords)) {
            $keywords = $this->getKeywords($this->request->getModule());
        }

Tino Goratsch's avatar
Tino Goratsch committed
202
        return \strtolower(!empty($keywords) ? $keywords : $this->getSeoSettings()['meta_keywords']);
203 204 205
    }

    /**
206
     * Returns the SEO keywords of the given page.
207 208 209 210 211
     *
     * @param string $path
     *
     * @return string
     */
212
    public function getKeywords(string $path): string
213 214 215 216
    {
        return $this->getSeoInformation($path, 'keywords');
    }

217
    /**
218
     * Returns the meta title of the given page.
219 220 221 222 223
     *
     * @param string $path
     *
     * @return string
     */
224
    public function getTitle(string $path): string
225 226 227 228
    {
        return $this->getSeoInformation($path, 'title');
    }

229 230 231 232 233 234 235
    /**
     * @param string $path
     * @param string $key
     * @param string $defaultValue
     *
     * @return string
     */
236
    public function getSeoInformation(string $path, string $key, string $defaultValue = ''): string
237
    {
238 239 240 241
        if (!$this->isActive) {
            return '';
        }

242 243 244 245 246
        // Lazy load the cache
        if ($this->aliasesCache === null) {
            $this->aliasesCache = $this->seoCache->getCache();
        }

Tino Goratsch's avatar
Tino Goratsch committed
247
        $path .= !\preg_match('/\/$/', $path) ? '/' : '';
248 249 250 251 252

        return !empty($this->aliasesCache[$path][$key]) ? $this->aliasesCache[$path][$key] : $defaultValue;
    }

    /**
253
     * Returns the SEO robots setting for the current page.
254 255 256
     *
     * @return string
     */
257
    public function getPageRobotsSetting(): string
258
    {
259 260 261 262
        if (!empty($this->metaRobots)) {
            return $this->metaRobots;
        }

263 264 265 266 267 268 269 270
        $robots = $this->getRobotsSetting($this->request->getUriWithoutPages());
        if (empty($robots)) {
            $robots = $this->getRobotsSetting($this->request->getFullPath());
        }
        if (empty($robots)) {
            $robots = $this->getRobotsSetting($this->request->getModule());
        }

Tino Goratsch's avatar
Tino Goratsch committed
271
        return \strtolower(!empty($robots) ? $robots : $this->getRobotsSetting());
272 273 274
    }

    /**
275
     * Returns the SEO robots settings for the given page.
276 277 278 279 280
     *
     * @param string $path
     *
     * @return string
     */
281
    public function getRobotsSetting(string $path = ''): string
282 283
    {
        if ($path === '') {
284
            return \strtr($this->getSeoSettings()['robots'], $this->getRobotsMap());
285 286 287 288 289
        }

        $robot = $this->getSeoInformation($path, 'robots', 0);

        if ($robot == 0) {
290
            $robot = $this->getSeoSettings()['robots'];
291 292
        }

293 294 295 296 297 298
        return \strtr($robot, $this->getRobotsMap());
    }

    public function getRobotsMap(): array
    {
        return self::$robotSettingsMaps;
299 300 301
    }

    /**
302
     * Sets a SEO description postfix for te current page.
303
     *
304
     * @param string $value
305 306 307
     *
     * @return $this
     */
308
    public function setDescriptionPostfix(string $value)
309
    {
310
        $this->metaDescriptionPostfix = $value;
311 312 313 314 315

        return $this;
    }

    /**
316
     * Sets the canonical URL for the current page.
317 318 319 320 321
     *
     * @param string $path
     *
     * @return $this
     */
322
    public function setCanonicalUri(string $path)
323 324 325 326 327 328 329
    {
        $this->canonicalUrl = $path;

        return $this;
    }

    /**
330
     * Sets the next page (useful for pagination).
331 332 333 334 335
     *
     * @param string $path
     *
     * @return $this
     */
336
    public function setNextPage(string $path)
337 338 339 340 341 342 343
    {
        $this->nextPage = $path;

        return $this;
    }

    /**
344
     * Sets the previous page (useful for pagination).
345 346 347 348 349
     *
     * @param string $path
     *
     * @return $this
     */
350
    public function setPreviousPage(string $path)
351 352 353 354 355 356
    {
        $this->previousPage = $path;

        return $this;
    }
}