Last active
October 11, 2020 00:38
-
-
Save Wiejeben/b6c3f069ffd790f12af960f0b6b6d706 to your computer and use it in GitHub Desktop.
Generates and stores SEOmatic OpenGraph image from Twig file via spatie/browsershot.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace modules\jobs; | |
use Craft; | |
use craft\elements\Asset; | |
use craft\elements\Entry; | |
use craft\queue\BaseJob; | |
use craft\web\View; | |
use nystudio107\seomatic\models\MetaBundle; | |
use Spatie\Browsershot\Browsershot; | |
/** | |
* Generates and stores SEOmatic OpenGraph image from Twig file. | |
*/ | |
class GenerateProductOpenGraphImage extends BaseJob | |
{ | |
public $description = 'Generates product OpenGraph image'; | |
/** @var int */ | |
public $productId; | |
/** @var string */ | |
public $volumeHandle = 'opengraph'; | |
/** @var string */ | |
public $template = '_products/opengraph.twig'; | |
/** @var string */ | |
public $seomaticFieldHandle = 'seo'; | |
public function __construct(int $productId) | |
{ | |
$this->productId = $productId; | |
parent::__construct(); | |
} | |
/** | |
* @param \craft\queue\QueueInterface|\yii\queue\Queue $queue | |
* @return mixed|void | |
* @throws \Spatie\Browsershot\Exceptions\CouldNotTakeBrowsershot | |
* @throws \Throwable | |
* @throws \Twig\Error\LoaderError | |
* @throws \Twig\Error\RuntimeError | |
* @throws \Twig\Error\SyntaxError | |
* @throws \craft\errors\ElementNotFoundException | |
* @throws \craft\errors\InvalidFieldException | |
* @throws \yii\base\Exception | |
*/ | |
public function execute($queue) | |
{ | |
$entry = Entry::find()->id($this->productId)->anyStatus()->one(); | |
if (! $entry) { | |
return; | |
} | |
/** @var MetaBundle $meta */ | |
$meta = $entry->getFieldValue($this->seomaticFieldHandle); | |
// Already has an image | |
if (! empty($meta->metaBundleSettings->seoImageIds)) { | |
return; | |
} | |
$volume = Craft::$app->getVolumes()->getVolumeByHandle($this->volumeHandle); | |
if (! $volume) { | |
return; | |
} | |
$folder = Craft::$app->getAssets()->getRootFolderByVolumeId($volume->id); | |
if (! $folder) { | |
return; | |
} | |
$fileName = $entry->id . '.png'; | |
// Check if file already exists | |
$asset = Asset::find()->volumeId($volume->id)->folderId($folder->id)->filename($fileName)->one(); | |
if ($asset) { | |
// Assign existing asset to entry | |
$this->applyAssetToEntry($entry, $asset); | |
return; | |
} | |
$tempFilePath = tempnam(sys_get_temp_dir(), 'opengraph_') . '.png'; | |
// Generate image | |
$html = Craft::$app->getView()->renderTemplate($this->template, [ | |
'entry' => $entry | |
], View::TEMPLATE_MODE_SITE); | |
Browsershot::html($html)->windowSize(1200, 630)->save($tempFilePath); | |
// Store asset | |
$asset = new Asset(); | |
$asset->title = $entry->productStyleCode; | |
$asset->tempFilePath = $tempFilePath; | |
$asset->filename = $fileName; | |
$asset->newFolderId = $folder->id; | |
$asset->volumeId = $folder->volumeId; | |
$asset->setScenario(Asset::SCENARIO_CREATE); | |
Craft::$app->getElements()->saveElement($asset); | |
$this->applyAssetToEntry($entry, $asset); | |
} | |
/** | |
* Applies asset to SEOmatic image field inside entry. | |
* | |
* @param Entry $entry | |
* @param Asset $asset | |
* @throws \Throwable | |
* @throws \craft\errors\ElementNotFoundException | |
* @throws \craft\errors\InvalidFieldException | |
* @throws \yii\base\Exception | |
*/ | |
protected function applyAssetToEntry(Entry $entry, Asset $asset): void | |
{ | |
/** @var MetaBundle $meta */ | |
$meta = $entry->getFieldValue($this->seomaticFieldHandle); | |
$meta->metaBundleSettings->seoImageTransform = false; | |
$meta->metaBundleSettings->seoImageIds = [$asset->id]; | |
$entry->setFieldValue($this->seomaticFieldHandle, $meta); | |
Craft::$app->getElements()->saveElement($entry); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment