Skip to content

Commit c391a7f

Browse files
committed
Merge branch 'release/3.5.21' into v3
2 parents 2662c88 + 84fc5fa commit c391a7f

35 files changed

+1105
-925
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# SEOmatic Changelog
22

3+
## 3.5.21 - 2025.10.06
4+
### Added
5+
* Added a `twigExtensionClasses` config setting to allow additional TwigExtension classes to be loaded in the Twig `SandboxView` that SEOmatic uses to render ([#1632](https://github.com/nystudio107/craft-seomatic/issues/1632))
6+
* Only allow users to pick SEO/Facebook/Twitter images from asset volumes that they had permission to access ([#1650](https://github.com/nystudio107/craft-seomatic/issues/1650))
7+
8+
### Changed
9+
* No longer block various AI bots via `robots.txt` by default ([#1635](https://github.com/nystudio107/craft-seomatic/issues/1635))
10+
* Handle setting the focal point for social images that are transformed ([#1626](https://github.com/nystudio107/craft-seomatic/issues/1626))
11+
12+
### Fixed
13+
* Fixed an issue with page footer text being untranslatable on 3 pages due to filter ordering ([#1651](https://github.com/nystudio107/craft-seomatic/issues/1651))
14+
* Don't overwrite the `dataLayer` if it already exists in the Google Tag Manager default script ([#1642](https://github.com/nystudio107/craft-seomatic/issues/1642))
15+
316
## 3.5.20 - 2025.08.17
417
### Changed
518
* Use `StringHelper::convertToUtf8()` instead of our homebrew solution

buildchain/package-lock.json

Lines changed: 612 additions & 558 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "nystudio107/craft-seomatic",
33
"description": "SEOmatic facilitates modern SEO best practices & implementation for Craft CMS 3. It is a turnkey SEO system that is comprehensive, powerful, and flexible.",
44
"type": "craft-plugin",
5-
"version": "3.5.20",
5+
"version": "3.5.21",
66
"keywords": [
77
"craft",
88
"cms",
@@ -32,7 +32,7 @@
3232
"craftcms/cms": "^3.2.0",
3333
"nystudio107/craft-plugin-vite": "^1.0.31",
3434
"nystudio107/craft-code-editor": "^1.0.0",
35-
"nystudio107/craft-twig-sandbox": "^3.0.5",
35+
"nystudio107/craft-twig-sandbox": "^3.0.6",
3636
"php-science/textrank": "^1.0.3",
3737
"davechild/textstatistics": "1.0.2",
3838
"sunra/php-simple-html-dom-parser": "^1.5.2"

docs/package-lock.json

Lines changed: 353 additions & 306 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Seomatic.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,12 @@ protected function installEventListeners()
481481
$seomaticTwigExtension = new SeomaticTwigExtension();
482482
self::$view->registerTwigExtension($seomaticTwigExtension);
483483
self::$sandboxView->registerTwigExtension($seomaticTwigExtension);
484+
// Register the additional TwigExtension classes
485+
foreach (Seomatic::$settings->twigExtensionClasses as $className) {
486+
if (class_exists($className)) {
487+
self::$sandboxView->registerTwigExtension(new $className());
488+
}
489+
}
484490
$request = Craft::$app->getRequest();
485491
// Add in our event listeners that are needed for every request
486492
$this->installGlobalEventListeners();

src/config.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,7 @@
174174
// string[] URL params that are allowed to be considered part of the unique URL used for the metadata cache
175175
'allowedUrlParams' => [
176176
],
177+
// class-string[] Array of TwigExtension classes to instantiate and add to the SandboxView
178+
'twigExtensionClasses' => [
179+
],
177180
];

src/controllers/SettingsController.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use nystudio107\seomatic\assetbundles\seomatic\SeomaticAsset;
2121
use nystudio107\seomatic\autocompletes\TrackingVarsAutocomplete;
2222
use nystudio107\seomatic\helpers\ArrayHelper;
23+
use nystudio107\seomatic\helpers\AssetHelper;
2324
use nystudio107\seomatic\helpers\DynamicMeta as DynamicMetaHelper;
2425
use nystudio107\seomatic\helpers\Field as FieldHelper;
2526
use nystudio107\seomatic\helpers\ImageTransform as ImageTransformHelper;
@@ -318,6 +319,7 @@ public function actionGlobal(string $subSection = 'general', string $siteHandle
318319
// Image selectors
319320
$bundleSettings = $metaBundle->metaBundleSettings;
320321
$variables['elementType'] = Asset::class;
322+
$variables['assetVolumeSources'] = AssetHelper::getAssetInputSources();
321323
$variables['seoImageElements'] = ImageTransformHelper::assetElementsFromIds(
322324
$bundleSettings->seoImageIds,
323325
$siteId
@@ -615,6 +617,7 @@ public function actionEditContent(
615617
$variables['currentSubSection'] = $subSection;
616618
$bundleSettings = $metaBundle->metaBundleSettings;
617619
$variables['elementType'] = Asset::class;
620+
$variables['assetVolumeSources'] = AssetHelper::getAssetInputSources();
618621
$variables['seoImageElements'] = ImageTransformHelper::assetElementsFromIds(
619622
$bundleSettings->seoImageIds,
620623
$siteId
@@ -794,6 +797,7 @@ public function actionSite(string $subSection = 'identity', string $siteHandle =
794797
);
795798
}
796799
$variables['elementType'] = Asset::class;
800+
$variables['assetVolumeSources'] = AssetHelper::getAssetInputSources();
797801

798802
// Render the template
799803
return $this->renderTemplate('seomatic/settings/site/' . $subSection, $variables);

src/fields/SeoSettings.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use craft\helpers\StringHelper;
2020
use nystudio107\seomatic\assetbundles\seomatic\SeomaticAsset;
2121
use nystudio107\seomatic\helpers\ArrayHelper;
22+
use nystudio107\seomatic\helpers\AssetHelper;
2223
use nystudio107\seomatic\helpers\Config as ConfigHelper;
2324
use nystudio107\seomatic\helpers\Field as FieldHelper;
2425
use nystudio107\seomatic\helpers\Migration as MigrationHelper;
@@ -347,7 +348,7 @@ public function getInputHtml($value, ElementInterface $element = null): string
347348

348349
/** @var MetaBundle $value */
349350
$variables['elementType'] = Asset::class;
350-
351+
$variables['assetVolumeSources'] = AssetHelper::getAssetInputSources();
351352
$variables['parentBundles'] = [];
352353
// Preview the containers so the preview is correct in the field
353354
if ($element !== null && $element->uri !== null) {

src/helpers/AssetHelper.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
/**
3+
* SEOmatic plugin for Craft CMS
4+
*
5+
* A turnkey SEO implementation for Craft CMS that is comprehensive, powerful,
6+
* and flexible
7+
*
8+
* @link https://nystudio107.com
9+
* @copyright Copyright (c) nystudio107
10+
*/
11+
12+
namespace nystudio107\seomatic\helpers;
13+
14+
use Craft;
15+
use craft\elements\Asset;
16+
use craft\helpers\ArrayHelper;
17+
18+
/**
19+
* @author nystudio107
20+
* @package Seomatic
21+
* @since 3.5.21
22+
*/
23+
class AssetHelper
24+
{
25+
/**
26+
* Return asset volume sources that can be accessed by the current user
27+
*
28+
* @return array
29+
*/
30+
public static function getAssetInputSources(): array
31+
{
32+
$sources = [];
33+
foreach (Craft::$app->getElementIndexes()->getSources(Asset::class) as $source) {
34+
if (isset($source['key'])) {
35+
$sources[] = $source['key'];
36+
}
37+
}
38+
39+
// Now enforce the showUnpermittedVolumes setting
40+
$assetsService = Craft::$app->getAssets();
41+
$userService = Craft::$app->getUser();
42+
return ArrayHelper::where($sources, function(string $source) use ($assetsService, $userService) {
43+
// If it's not a volume folder, let it through
44+
if (strpos($source, 'folder:') !== 0) {
45+
return true;
46+
}
47+
// Only show it if they have permission to view it
48+
$folder = $assetsService->getFolderByUid(explode(':', $source)[1]);
49+
$volume = $folder ? $folder->getVolume() : null;
50+
return $volume && $userService->checkPermission("viewVolume:{$volume->uid}");
51+
}, true, true, false);
52+
}
53+
}

src/helpers/ImageTransform.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ public static function socialTransform(
147147
}
148148
}
149149
try {
150+
if ($asset->getHasFocalPoint()) {
151+
$transform->position = $asset->getFocalPoint(true);
152+
}
150153
$url = $assets->getAssetUrl($asset, $transform, $generateNow);
151154
} catch (Exception $e) {
152155
$url = $asset->getUrl();

0 commit comments

Comments
 (0)