diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a01604a --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Composer +/composer.lock +/vendor/ + +# PhpUnit +/.phpunit.result.cache +/phpunit.xml + +# IDE +/.idea diff --git a/README.md b/README.md index 0d2087e..900101a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ --- -> Working with **Contao 4.9** and up to **Contao 4.13** (PHP ^7.4 and PHP 8) +> Working with **Contao 4.13** and **Contao 5.1** (PHP ^8.1) --- diff --git a/composer.json b/composer.json index 37bd695..7f41870 100644 --- a/composer.json +++ b/composer.json @@ -10,15 +10,29 @@ "name": "Oveleon", "homepage": "https://oveleon.de/", "role": "Developer" + }, + { + "name": "Sebastian Zoglowek", + "homepage": "https://github.com/zoglo", + "role": "Developer" + }, + { + "name": "Fabian Ekert", + "homepage": "https://github.com/eki89", + "role": "Developer" } ], "require": { - "php": "^7.4 || ^8.0", - "contao/core-bundle":"^4.9", - "oveleon/contao-recommendation-bundle":"^1.2.1" + "php": "^8.1", + "contao/core-bundle": "^4.13 || ^5.1", + "oveleon/contao-recommendation-bundle": "^1.3" }, "require-dev": { - "contao/manager-plugin": "^2.0" + "contao/manager-plugin": "^2.3.1", + "contao/test-case": "^5.1", + "phpunit/phpunit": "^9.5", + "symfony/http-client": "^5.4 || ^6.0", + "symfony/phpunit-bridge": "^5.4 || ^6.0" }, "conflict": { "contao/core": "*", @@ -29,19 +43,25 @@ "Oveleon\\ContaoGoogleRecommendationBundle\\": "src/" }, "classmap": [ - "src/Resources/contao/" + "contao/" ], "exclude-from-classmap": [ - "src/Resources/contao/config/", - "src/Resources/contao/dca/", - "src/Resources/contao/languages/", - "src/Resources/contao/templates/" + "contao/config/", + "contao/dca/", + "contao/languages/", + "contao/templates/" ] }, "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-main": "1.3.x-dev" }, "contao-manager-plugin": "Oveleon\\ContaoGoogleRecommendationBundle\\ContaoManager\\Plugin" + }, + "config": { + "allow-plugins": { + "php-http/discovery": true, + "contao/manager-plugin": true + } } } diff --git a/config/services.yaml b/config/services.yaml new file mode 100644 index 0000000..523486d --- /dev/null +++ b/config/services.yaml @@ -0,0 +1,9 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: true + + Oveleon\ContaoGoogleRecommendationBundle\: + resource: '../src/' + exclude: '../src/{Model,DependencyInjection,Resources}' diff --git a/contao/config/config.php b/contao/config/config.php new file mode 100644 index 0000000..691e7c7 --- /dev/null +++ b/contao/config/config.php @@ -0,0 +1,9 @@ + true, 'inputType' => 'text', - 'eval' => array('maxlength'=>255, 'tl_class'=>'w50'), + 'eval' => ['maxlength'=>255, 'tl_class'=>'w50'], 'sql' => "varchar(255) NOT NULL default ''" -); +]; // Extend the default palette -Contao\CoreBundle\DataContainer\PaletteManipulator::create() - ->addLegend('google_legend', 'expert_legend', Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_BEFORE) - ->addField(array('googleAuthorUrl'), 'google_legend', Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_APPEND) +PaletteManipulator::create() + ->addLegend('google_legend', 'expert_legend', PaletteManipulator::POSITION_BEFORE) + ->addField(array('googleAuthorUrl'), 'google_legend', PaletteManipulator::POSITION_APPEND) ->applyToPalette('default', 'tl_recommendation') ; diff --git a/contao/dca/tl_recommendation_archive.php b/contao/dca/tl_recommendation_archive.php new file mode 100644 index 0000000..deac179 --- /dev/null +++ b/contao/dca/tl_recommendation_archive.php @@ -0,0 +1,73 @@ + 'key=syncAllArchives', + 'icon' => 'sync.svg', + 'attributes' => 'onclick="if(!confirm(\'' . ($GLOBALS['TL_LANG']['tl_recommendation_archive']['syncAllConfirm'] ?? null) . '\'))return false;Backend.getScrollOffset()"', +]; + +// Add operations +$GLOBALS['TL_DCA']['tl_recommendation_archive']['list']['operations']['startSync'] = [ + 'href' => 'key=startSync', + 'icon' => 'sync.svg', + 'attributes' => 'onclick="if(!confirm(\'' . ($GLOBALS['TL_LANG']['tl_recommendation_archive']['syncConfirm'] ?? null) . '\'))return false;Backend.getScrollOffset()"', + 'button_callback' => [RecommendationArchiveListener::class, 'addSyncButton'], +]; + +// Add subpalettes +$GLOBALS['TL_DCA']['tl_recommendation_archive']['fields']['syncWithGoogle'] = [ + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => ['submitOnChange'=>true], + 'sql' => "char(1) NOT NULL default ''" +]; + +$GLOBALS['TL_DCA']['tl_recommendation_archive']['fields']['googleApiToken'] = [ + 'exclude' => true, + 'inputType' => 'text', + 'eval' => ['doNotCopy'=>true, 'mandatory'=>true, 'maxlength'=>255, 'tl_class'=>'w50'], + 'sql' => "varchar(255) NOT NULL default ''" +]; + +$GLOBALS['TL_DCA']['tl_recommendation_archive']['fields']['googlePlaceId'] = [ + 'exclude' => true, + 'inputType' => 'text', + 'eval' => ['doNotCopy'=>true, 'mandatory'=>true, 'maxlength'=>255, 'tl_class'=>'w50'], + 'sql' => "varchar(255) NOT NULL default ''" +]; + +$GLOBALS['TL_DCA']['tl_recommendation_archive']['fields']['syncLanguage'] = [ + 'exclude' => true, + 'inputType' => 'select', + 'options_callback' => static function () + { + return array_keys($GLOBALS['TL_LANG']['tl_recommendation_languages']); + }, + 'reference' => &$GLOBALS['TL_LANG']['tl_recommendation_languages'], + 'eval' => ['doNotCopy'=>true, 'includeBlankOption'=>true, 'chosen'=>true,'tl_class'=>'w50'], + 'sql' => "varchar(5) NOT NULL default ''" +]; + +$GLOBALS['TL_DCA']['tl_recommendation_archive']['palettes']['__selector__'][] = 'syncWithGoogle'; +$GLOBALS['TL_DCA']['tl_recommendation_archive']['subpalettes']['syncWithGoogle'] = 'googleApiToken,googlePlaceId,syncLanguage'; + +// Extend the default palette +PaletteManipulator::create() + ->addLegend('google_legend', 'protected_legend') + ->addField(['syncWithGoogle'], 'google_legend', PaletteManipulator::POSITION_APPEND) + ->applyToPalette('default', 'tl_recommendation_archive') +; diff --git a/src/Resources/contao/languages/de/tl_recommendation.xlf b/contao/languages/de/tl_recommendation.xlf similarity index 88% rename from src/Resources/contao/languages/de/tl_recommendation.xlf rename to contao/languages/de/tl_recommendation.xlf index 159b60a..66ab3e5 100644 --- a/src/Resources/contao/languages/de/tl_recommendation.xlf +++ b/contao/languages/de/tl_recommendation.xlf @@ -1,5 +1,5 @@ - + Google author url diff --git a/src/Resources/contao/languages/de/tl_recommendation_archive.xlf b/contao/languages/de/tl_recommendation_archive.xlf similarity index 96% rename from src/Resources/contao/languages/de/tl_recommendation_archive.xlf rename to contao/languages/de/tl_recommendation_archive.xlf index 9f96b54..a8ce8f5 100644 --- a/src/Resources/contao/languages/de/tl_recommendation_archive.xlf +++ b/contao/languages/de/tl_recommendation_archive.xlf @@ -1,5 +1,5 @@ - + Sync all archives diff --git a/src/Resources/contao/languages/de/tl_recommendation_languages.xlf b/contao/languages/de/tl_recommendation_languages.xlf similarity index 99% rename from src/Resources/contao/languages/de/tl_recommendation_languages.xlf rename to contao/languages/de/tl_recommendation_languages.xlf index af37184..01d0798 100644 --- a/src/Resources/contao/languages/de/tl_recommendation_languages.xlf +++ b/contao/languages/de/tl_recommendation_languages.xlf @@ -1,5 +1,5 @@ - + Afrikaans diff --git a/src/Resources/contao/languages/en/tl_recommendation.xlf b/contao/languages/en/tl_recommendation.xlf similarity index 86% rename from src/Resources/contao/languages/en/tl_recommendation.xlf rename to contao/languages/en/tl_recommendation.xlf index 69ac9bc..457ad89 100644 --- a/src/Resources/contao/languages/en/tl_recommendation.xlf +++ b/contao/languages/en/tl_recommendation.xlf @@ -1,5 +1,5 @@ - + Google author url diff --git a/src/Resources/contao/languages/en/tl_recommendation_archive.xlf b/contao/languages/en/tl_recommendation_archive.xlf similarity index 95% rename from src/Resources/contao/languages/en/tl_recommendation_archive.xlf rename to contao/languages/en/tl_recommendation_archive.xlf index 5c4d876..2c02329 100644 --- a/src/Resources/contao/languages/en/tl_recommendation_archive.xlf +++ b/contao/languages/en/tl_recommendation_archive.xlf @@ -1,5 +1,5 @@ - + Sync all archives diff --git a/src/Resources/contao/languages/en/tl_recommendation_languages.xlf b/contao/languages/en/tl_recommendation_languages.xlf similarity index 98% rename from src/Resources/contao/languages/en/tl_recommendation_languages.xlf rename to contao/languages/en/tl_recommendation_languages.xlf index b7cf2d4..d0646e6 100644 --- a/src/Resources/contao/languages/en/tl_recommendation_languages.xlf +++ b/contao/languages/en/tl_recommendation_languages.xlf @@ -1,5 +1,5 @@ - + Afrikaans diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..c62af56 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,21 @@ + + + + + ./src + + + + + + + + + + ./tests + + + + + + diff --git a/src/Resources/public/icons/sync_disabled.svg b/public/icons/sync_disabled.svg similarity index 100% rename from src/Resources/public/icons/sync_disabled.svg rename to public/icons/sync_disabled.svg diff --git a/src/ContaoGoogleRecommendationBundle.php b/src/ContaoGoogleRecommendationBundle.php index f009048..1e3eacd 100644 --- a/src/ContaoGoogleRecommendationBundle.php +++ b/src/ContaoGoogleRecommendationBundle.php @@ -1,7 +1,7 @@ - */ class ContaoGoogleRecommendationBundle extends Bundle { + public function getPath(): string + { + return \dirname(__DIR__); + } } diff --git a/src/ContaoManager/Plugin.php b/src/ContaoManager/Plugin.php index 999622e..8345ec3 100644 --- a/src/ContaoManager/Plugin.php +++ b/src/ContaoManager/Plugin.php @@ -17,11 +17,6 @@ use Oveleon\ContaoGoogleRecommendationBundle\ContaoGoogleRecommendationBundle; use Oveleon\ContaoRecommendationBundle\ContaoRecommendationBundle; -/** - * Plugin for the Contao Manager. - * - * @author Fabian Ekert - */ class Plugin implements BundlePluginInterface { /** diff --git a/src/Cron/GetGoogleReviewsCron.php b/src/Cron/GetGoogleReviewsCron.php new file mode 100644 index 0000000..b0a6258 --- /dev/null +++ b/src/Cron/GetGoogleReviewsCron.php @@ -0,0 +1,29 @@ +getGoogleReviews(); + } +} diff --git a/src/DependencyInjection/ContaoGoogleRecommendationExtension.php b/src/DependencyInjection/ContaoGoogleRecommendationExtension.php new file mode 100644 index 0000000..9c985b5 --- /dev/null +++ b/src/DependencyInjection/ContaoGoogleRecommendationExtension.php @@ -0,0 +1,26 @@ +load('services.yaml'); + } +} diff --git a/src/EventListener/DataContainer/RecommendationArchiveListener.php b/src/EventListener/DataContainer/RecommendationArchiveListener.php new file mode 100644 index 0000000..d5dfe18 --- /dev/null +++ b/src/EventListener/DataContainer/RecommendationArchiveListener.php @@ -0,0 +1,39 @@ +'.Image::getHtml($icon, $label).' '; + } +} diff --git a/src/GooglePlacesApi.php b/src/GooglePlacesApi.php new file mode 100644 index 0000000..9a0f517 --- /dev/null +++ b/src/GooglePlacesApi.php @@ -0,0 +1,157 @@ + 'newest', + 'place_id' => $objArchive->googlePlaceId, + 'fields' => 'reviews', + 'key' => $objArchive->googleApiToken, + ]; + + if ($objArchive->syncLanguage) + { + $arrParams['language'] = $objArchive->syncLanguage; + } + else + { + $arrParams['reviews_no_translations'] = 'true'; + } + + $strSyncUrl = 'https://maps.googleapis.com/maps/api/place/details/json?' . http_build_query($arrParams); + $client = HttpClient::create(); + $arrContent = $client->request('POST', $strSyncUrl)->toArray(); + $objContent = (object) $arrContent; + + System::loadLanguageFile('tl_recommendation'); + + if ($objContent && $objContent->status !== 'OK') + { + System::getContainer()->get('monolog.logger.contao')?->error('Recommendations for Archive with ID ' . $objArchive->id . ' could not be synced - Reason: ' . ($objContent->error_message ?? $objContent->status ?? 'Connection with Google Api could not be established.')); + + if (!$blnCron) + { + // Display an error if api call was not successful + Message::addError(sprintf($GLOBALS['TL_LANG']['tl_recommendation']['archiveSyncFailed'], $objArchive->id, ($objContent->error_message ?? $objContent->status ?? 'Connection with Google Api could not be established.'))); + } + + continue; + } + + if ($objContent && $objContent->result && (is_array($arrReviews = $objContent->result['reviews']) ?? null)) + { + $time = time(); + $objRecommendations = RecommendationModel::findByPid($objArchive->id); + + foreach ($arrReviews as $review) + { + // Skip if author url or text is empty or record already exists + if (!$review['author_url'] || !$review['text'] || (!(null === $objRecommendations) && in_array($review['author_url'], $objRecommendations->fetchEach('googleAuthorUrl')))) + { + continue; + } + + // Save the record + (new RecommendationModel())->setRow([ + 'tstamp' => $time, + 'pid' => $objArchive->id, + 'author' => $review['author_name'], + 'date' => $review['time'], + 'time' => $review['time'], + 'text' => '

' . $review['text'] . '

', + 'rating' => $review['rating'], + 'imageUrl' => $review['profile_photo_url'], + 'googleAuthorUrl' => $review['author_url'], + 'published' => 1 + ])->save(); + } + + if (!$blnCron) + { + Message::addInfo(sprintf($GLOBALS['TL_LANG']['tl_recommendation']['archiveSyncSuccess'], $objArchive->id)); + } + + // Invalidate cache tag + System::getContainer()->get('fos_http_cache.cache_manager')->invalidateTags(['contao.db.tl_recommendation_archive.' . $objArchive->id]); + } + } + } + + /** + * Sync all archives manually + */ + public function syncAllArchives(): void + { + $this->getGoogleReviews(null, true); + Controller::redirect(System::getReferer()); + } + + /** + * Sync selected archive with Google + */ + public function syncWithGoogle(): void + { + $this->getGoogleReviews([Input::get('id')]); + Controller::redirect(System::getReferer()); + } +} + +class_alias(GooglePlacesApi::class, 'GooglePlacesApi'); diff --git a/src/Resources/contao/classes/GooglePlacesApi.php b/src/Resources/contao/classes/GooglePlacesApi.php deleted file mode 100644 index e82bf75..0000000 --- a/src/Resources/contao/classes/GooglePlacesApi.php +++ /dev/null @@ -1,182 +0,0 @@ - - * @author Sebastian Zoglowek - */ -class GooglePlacesApi extends Frontend -{ - public function getGoogleReviews(?array $arrIds = null, bool $manualSync = false) - { - // Check if method is called by cronjob - $blnCron = false; - - if (null === $arrIds) - { - $recTable = RecommendationArchiveModel::getTable(); - - $objRecommendationArchives = RecommendationArchiveModel::findBy([ - $recTable . ".syncWithGoogle=?" - ], [1]); - - if (!$manualSync) - { - $blnCron = true; - } - } - else - { - $objRecommendationArchives = RecommendationArchiveModel::findMultipleByIds($arrIds); - } - - if (null === $objRecommendationArchives) - return; - - foreach ($objRecommendationArchives as $objRecommendationArchive) - { - $arrParams = [ - 'reviews_sort' => 'newest', - 'place_id' => $objRecommendationArchive->googlePlaceId, - 'fields' => 'reviews', - 'key' => $objRecommendationArchive->googleApiToken, - ]; - - if ($objRecommendationArchive->syncLanguage) { - $arrParams['language'] = $objRecommendationArchive->syncLanguage; - } else { - $arrParams['reviews_no_translations'] = 'true'; - } - - $strSyncUrl = 'https://maps.googleapis.com/maps/api/place/details/json?' . http_build_query($arrParams); - $client = HttpClient::create(); - $arrContent = $client->request('POST', $strSyncUrl)->toArray(); - $objContent = (object)$arrContent; - - System::loadLanguageFile('tl_recommendation'); - - if ($objContent && $objContent->status !== 'OK') - { - $logger = System::getContainer()->get('monolog.logger.contao'); - $logger->log( - LogLevel::ERROR, - 'Recommendations for Archive with ID ' . $objRecommendationArchive->id . ' could not be synced - Reason: ' . ($objContent->error_message ?? $objContent->status ?? 'Connection with Google Api could not be established.'), - ['contao' => new ContaoContext(__METHOD__, TL_ERROR)] - ); - - // Display an error if api call was not successful - if (!$blnCron) - { - Message::addError(sprintf($GLOBALS['TL_LANG']['tl_recommendation']['archiveSyncFailed'], $objRecommendationArchive->id, ($objContent->error_message ?? $objContent->status ?? 'Connection with Google Api could not be established.'))); - } - - continue; - } - - if ($objContent && $objContent->result && (is_array($arrReviews = $objContent->result['reviews']) ?? null)) - { - $time = time(); - - $objRecommendations = RecommendationModel::findByPid($objRecommendationArchive->id); - - foreach ($arrReviews as $review) - { - // Skip if author url or text is empty or record already exists - if (!$review['author_url'] || !$review['text'] || $this->recordExists($objRecommendations, $review['author_url'])) - continue; - - // Prepare the record - $arrData = [ - 'tstamp' => $time, - 'pid' => $objRecommendationArchive->id, - 'author' => $review['author_name'], - 'date' => $review['time'], - 'time' => $review['time'], - 'text' => '

' . $review['text'] . '

', - 'rating' => $review['rating'], - 'imageUrl' => $review['profile_photo_url'], - 'googleAuthorUrl' => $review['author_url'], - 'published' => 1 - ]; - - $objRecommendation = new RecommendationModel(); - $objRecommendation->setRow($arrData)->save(); - } - - // Sync happened successfully - if (!$blnCron) - { - Message::addInfo(sprintf($GLOBALS['TL_LANG']['tl_recommendation']['archiveSyncSuccess'], $objRecommendationArchive->id)); - } - - //Invalidate archive tag - $this->invalidateRecommendationArchiveTag($objRecommendationArchive); - } - } - } - - /** - * Sync all archives manually - */ - public function syncAllArchives() - { - $this->getGoogleReviews(null, true); - $this->redirect($this->getReferer()); - } - - /** - * Sync selected archive with Google - */ - public function syncWithGoogle() - { - $this->getGoogleReviews([Input::get('id')]); - $this->redirect($this->getReferer()); - } - - /** - * Check if a record exists - * - * @param RecommendationModel $objRecommendations - * @param string $authorUrl - * - * @return boolean - */ - protected function recordExists($objRecommendations, $authorUrl): bool - { - if (null === $objRecommendations) - return false; - - $arrUrls = $objRecommendations->fetchEach('googleAuthorUrl'); - - return in_array($authorUrl, $arrUrls); - } - - /** - * Invalidates the recommendation cache tag - */ - public function invalidateRecommendationArchiveTag($objRecommendationArchive) - { - /** @var FOS\HttpCacheBundle\CacheManager $cacheManager */ - $cacheManager = System::getContainer()->get('fos_http_cache.cache_manager'); - $cacheManager->invalidateTags(['contao.db.tl_recommendation_archive.' . $objRecommendationArchive->id]); - } -} diff --git a/src/Resources/contao/config/config.php b/src/Resources/contao/config/config.php deleted file mode 100644 index 2a3656a..0000000 --- a/src/Resources/contao/config/config.php +++ /dev/null @@ -1,10 +0,0 @@ - 'key=syncAllArchives', - 'icon' => 'sync.svg', - 'attributes' => 'onclick="if(!confirm(\'' . ($GLOBALS['TL_LANG']['tl_recommendation_archive']['syncAllConfirm'] ?? null) . '\'))return false;Backend.getScrollOffset()"', -); - -// Add operations -$GLOBALS['TL_DCA']['tl_recommendation_archive']['list']['operations']['startSync'] = array -( - 'href' => 'key=startSync', - 'icon' => 'sync.svg', - 'attributes' => 'onclick="if(!confirm(\'' . ($GLOBALS['TL_LANG']['tl_recommendation_archive']['syncConfirm'] ?? null) . '\'))return false;Backend.getScrollOffset()"', - 'button_callback' => array('tl_recommendation_archive_google', 'addSyncButton'), -); - -// Add subpalettes -$GLOBALS['TL_DCA']['tl_recommendation_archive']['fields']['syncWithGoogle'] = array -( - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array('submitOnChange'=>true), - 'sql' => "char(1) NOT NULL default ''" -); -$GLOBALS['TL_DCA']['tl_recommendation_archive']['fields']['googleApiToken'] = array -( - 'exclude' => true, - 'inputType' => 'text', - 'eval' => array('doNotCopy'=>true, 'mandatory'=>true, 'maxlength'=>255, 'tl_class'=>'w50'), - 'sql' => "varchar(255) NOT NULL default ''" -); -$GLOBALS['TL_DCA']['tl_recommendation_archive']['fields']['googlePlaceId'] = array -( - 'exclude' => true, - 'inputType' => 'text', - 'eval' => array('doNotCopy'=>true, 'mandatory'=>true, 'maxlength'=>255, 'tl_class'=>'w50'), - 'sql' => "varchar(255) NOT NULL default ''" -); -$GLOBALS['TL_DCA']['tl_recommendation_archive']['fields']['syncLanguage'] = array -( - 'exclude' => true, - 'inputType' => 'select', - 'options_callback' => static function () - { - return array_keys($GLOBALS['TL_LANG']['tl_recommendation_languages']); - }, - 'reference' => &$GLOBALS['TL_LANG']['tl_recommendation_languages'], - 'eval' => array('doNotCopy'=>true, 'includeBlankOption'=>true, 'chosen'=>true,'tl_class'=>'w50'), - 'sql' => "varchar(5) NOT NULL default ''" -); - -$GLOBALS['TL_DCA']['tl_recommendation_archive']['palettes']['__selector__'][] = 'syncWithGoogle'; -$GLOBALS['TL_DCA']['tl_recommendation_archive']['subpalettes']['syncWithGoogle'] = 'googleApiToken,googlePlaceId,syncLanguage'; - -// Extend the default palette -Contao\CoreBundle\DataContainer\PaletteManipulator::create() - ->addLegend('google_legend', 'protected_legend', Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_AFTER) - ->addField(array('syncWithGoogle'), 'google_legend', Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_APPEND) - ->applyToPalette('default', 'tl_recommendation_archive') -; - -class tl_recommendation_archive_google extends Contao\Backend -{ - /** - * Returns the google sync button - * - * @param array $row - * @param string $href - * @param string $label - * @param string $title - * @param string $icon - * @param string $attributes - * - * @return string - */ - public function addSyncButton($row, $href, $label, $title, $icon, $attributes) - { - if (!$row['syncWithGoogle']) - { - $icon = 'bundles/contaogooglerecommendation/icons/sync_disabled.svg'; - return Contao\Image::getHtml($icon, $label); - } - - return ''.Contao\Image::getHtml($icon, $label).' '; - } -} diff --git a/tests/ContaoManager/PluginTest.php b/tests/ContaoManager/PluginTest.php new file mode 100644 index 0000000..7a87a04 --- /dev/null +++ b/tests/ContaoManager/PluginTest.php @@ -0,0 +1,28 @@ +createMock(ParserInterface::class); + + /** @var BundleConfig $config */ + $config = (new Plugin())->getBundles($parser)[0]; + + $this->assertInstanceOf(BundleConfig::class, $config); + $this->assertSame(ContaoGoogleRecommendationBundle::class, $config->getName()); + $this->assertSame([ContaoRecommendationBundle::class], $config->getLoadAfter()); + $this->assertSame(['google-recommendation'], $config->getReplace()); + } +}