From 9f8ec810005288921f4e91e52ba06ed5527537fe Mon Sep 17 00:00:00 2001 From: Dennis Ruiter Date: Wed, 26 Jan 2022 10:00:46 +0100 Subject: [PATCH] fix/pinned-highlighted - Replaced onAfterWrite for ArticlesPage that used a write/publish cycle to reflect two properties to the ArticlesPage class this has been replaced with direct DB queries that achieve the same result at a fraction of the time. - Added two custom GridFieldActions for linking/unlinking pinned/highlighted that also reflect these properties onto the ArticlePage class. --- ...iclesGridFieldAddExistingAutocompleter.php | 51 +++++++++ .../ArticlesGridFieldDeleteAction.php | 52 +++++++++ src/Pages/ArticlesPage.php | 103 ++++++++++++------ 3 files changed, 171 insertions(+), 35 deletions(-) create mode 100644 src/GridFieldActions/ArticlesGridFieldAddExistingAutocompleter.php create mode 100644 src/GridFieldActions/ArticlesGridFieldDeleteAction.php diff --git a/src/GridFieldActions/ArticlesGridFieldAddExistingAutocompleter.php b/src/GridFieldActions/ArticlesGridFieldAddExistingAutocompleter.php new file mode 100644 index 0000000..24c7653 --- /dev/null +++ b/src/GridFieldActions/ArticlesGridFieldAddExistingAutocompleter.php @@ -0,0 +1,51 @@ +getFieldToUpdate($gridField)) { + $IDToUpdate = $data['relationID']; + + // Safety check for possible injection + if (!is_numeric($IDToUpdate)) { + return parent::handleAction($gridField, $actionName, $arguments, $data); + } + + $item = ArticlePage::get_by_id($IDToUpdate); + + if (!$item) { + return parent::handleAction($gridField, $actionName, $arguments, $data); + } + + DB::query("UPDATE TheWebmen_ArticlePage SET $fieldToUpdate = 1 WHERE ID = $IDToUpdate"); + + if ($item->isPublished()) { + DB::query("UPDATE TheWebmen_ArticlePage_Live SET $fieldToUpdate = 1 WHERE ID = $IDToUpdate"); + } + } + + parent::handleAction($gridField, $actionName, $arguments, $data); + } + + private function getFieldToUpdate(GridField $gridField): ?string + { + switch ($gridField->getList()->getJoinTable()) { + case 'TheWebmen_ArticlesPage_PinnedArticles': + return 'Pinned'; + + case 'TheWebmen_ArticlesPage_HighlightedArticles': + return 'Highlighted'; + + default: + return null; + } + } +} diff --git a/src/GridFieldActions/ArticlesGridFieldDeleteAction.php b/src/GridFieldActions/ArticlesGridFieldDeleteAction.php new file mode 100644 index 0000000..45e1b85 --- /dev/null +++ b/src/GridFieldActions/ArticlesGridFieldDeleteAction.php @@ -0,0 +1,52 @@ +getFieldToUpdate($gridField)) { + $IDToUpdate = $arguments['RecordID']; + + // Safety check for possible injection + if (!is_numeric($IDToUpdate)) { + return parent::handleAction($gridField, $actionName, $arguments, $data); + } + + /** @var ArticlePage $item */ + $item = $gridField->getList()->byID($IDToUpdate); + + DB::query("UPDATE TheWebmen_ArticlePage SET $fieldToUpdate = 0 WHERE ID = $IDToUpdate"); + + if ($item->isPublished()) { + DB::query("UPDATE TheWebmen_ArticlePage_Live SET $fieldToUpdate = 0 WHERE ID = $IDToUpdate"); + } + } + + parent::handleAction($gridField, $actionName, $arguments, $data); + } + + private function getFieldToUpdate(GridField $gridField): ?string + { + switch ($gridField->getList()->getJoinTable()) { + case 'TheWebmen_ArticlesPage_PinnedArticles': + return 'Pinned'; + + case 'TheWebmen_ArticlesPage_HighlightedArticles': + return 'Highlighted'; + + default: + return null; + } + } +} diff --git a/src/Pages/ArticlesPage.php b/src/Pages/ArticlesPage.php index f34c7a5..074046e 100755 --- a/src/Pages/ArticlesPage.php +++ b/src/Pages/ArticlesPage.php @@ -10,16 +10,20 @@ use SilverStripe\Forms\GridField\GridFieldAddNewButton; use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor; use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor; +use SilverStripe\Forms\GridField\GridFieldDeleteAction; use SilverStripe\Forms\GridField\GridFieldEditButton; use SilverStripe\Forms\NumericField; use SilverStripe\Lumberjack\Forms\GridFieldConfig_Lumberjack; use SilverStripe\Lumberjack\Forms\GridFieldSiteTreeAddNewButton; use SilverStripe\ORM\DataList; +use SilverStripe\ORM\DB; use SilverStripe\ORM\HasManyList; use SilverStripe\ORM\ManyManyList; use SilverStripe\Versioned\GridFieldArchiveAction; use Symbiote\GridFieldExtensions\GridFieldOrderableRows; use TheWebmen\Articles\Controllers\ArticlesPageController; +use TheWebmen\Articles\GridFieldActions\ArticlesGridFieldAddExistingAutocompleter; +use TheWebmen\Articles\GridFieldActions\ArticlesGridFieldDeleteAction; use TheWebmen\Articles\Models\Author; use TheWebmen\Articles\Models\Tag; @@ -197,8 +201,16 @@ private function getGridConfig(string $sortColumn): GridFieldConfig_RelationEdit $gridfieldConfig->removeComponentsByType(GridFieldArchiveAction::class); $gridfieldConfig->removeComponentsByType(GridFieldEditButton::class); + // Custom delete action that properly reflects the pinned/highlighted property to the removed relation + $gridfieldConfig->removeComponentsByType(GridFieldDeleteAction::class); + $gridfieldConfig->addComponent(new ArticlesGridFieldDeleteAction()); + + // Custom add action that properly reflects the pinned/highlighted property to the added relation + $gridfieldConfig->removeComponentsByType(GridFieldAddExistingAutocompleter::class); + $gridfieldConfig->addComponent(new ArticlesGridFieldAddExistingAutocompleter()); + /** @var GridFieldAddExistingAutocompleter $autocompleter */ - $autocompleter = $gridfieldConfig->getComponentByType(GridFieldAddExistingAutocompleter::class); + $autocompleter = $gridfieldConfig->getComponentByType(ArticlesGridFieldAddExistingAutocompleter::class); $autocompleter ->setSearchList( ArticlePage::get()->filter( @@ -263,42 +275,63 @@ public function getControllerName(): string protected function onAfterWrite() { - $articlePages = ArticlePage::get()->filter('ParentID', $this->ID); - - $articlePages->each( - function (ArticlePage $articlePage) { - $pinned = $articlePage->Pinned; - $highlighted = $articlePage->Highlighted; - - if (!$highlighted && in_array($articlePage->ID, $this->HighlightedArticles()->column('ID'))) { - $articlePage->Highlighted = true; - } - - if ($highlighted && !in_array($articlePage->ID, $this->HighlightedArticles()->column('ID'))) { - $articlePage->Highlighted = false; - } - - if (!$pinned && in_array($articlePage->ID, $this->PinnedArticles()->column('ID'))) { - $articlePage->Pinned = true; - } - - if ($pinned && !in_array($articlePage->ID, $this->PinnedArticles()->column('ID'))) { - $articlePage->Pinned = false; - } - - try { - $isModifiedOnDraft = $articlePage->isModifiedOnDraft(); - $articlePage->write(); - - if (!$isModifiedOnDraft) { - $articlePage->publishRecursive(); - } - } catch (\Exception $exception) { - Injector::inst()->get('LoggingService')->exception($exception); - } - } + $parentID = $this->ID; + + DB::query(" + UPDATE TheWebmen_ArticlePage SET Highlighted = 1 WHERE ID IN ( + SELECT TheWebmen_ArticlePageID FROM TheWebmen_ArticlesPage_HighlightedArticles WHERE TheWebmen_ArticlesPageID = $parentID + ) AND ID IN (SELECT ID FROM SiteTree WHERE ParentID = $parentID) + "); + + DB::query(" + UPDATE TheWebmen_ArticlePage SET Highlighted = 0 WHERE ID NOT IN ( + SELECT TheWebmen_ArticlePageID FROM TheWebmen_ArticlesPage_HighlightedArticles WHERE TheWebmen_ArticlesPageID = $parentID + ) AND ID IN (SELECT ID FROM SiteTree WHERE ParentID = $parentID)" + ); + + DB::query(" + UPDATE TheWebmen_ArticlePage SET Pinned = 1 WHERE ID IN ( + SELECT TheWebmen_ArticlePageID FROM TheWebmen_ArticlesPage_PinnedArticles WHERE TheWebmen_ArticlesPageID = $parentID + ) AND ID IN (SELECT ID FROM SiteTree WHERE ParentID = $parentID) + "); + + DB::query(" + UPDATE TheWebmen_ArticlePage SET Pinned = 0 WHERE ID NOT IN ( + SELECT TheWebmen_ArticlePageID FROM TheWebmen_ArticlesPage_PinnedArticles WHERE TheWebmen_ArticlesPageID = $parentID + ) AND ID IN (SELECT ID FROM SiteTree WHERE ParentID = $parentID)" ); parent::onAfterWrite(); } + + public function onAfterPublish() + { + $parentID = $this->ID; + + DB::query(" + UPDATE TheWebmen_ArticlePage_Live SET Highlighted = 1 WHERE ID IN ( + SELECT TheWebmen_ArticlePageID FROM TheWebmen_ArticlesPage_HighlightedArticles WHERE TheWebmen_ArticlesPageID = $parentID + ) AND ID IN (SELECT ID FROM SiteTree_Live WHERE ParentID = $parentID) + "); + + DB::query(" + UPDATE TheWebmen_ArticlePage_Live SET Highlighted = 0 WHERE ID NOT IN ( + SELECT TheWebmen_ArticlePageID FROM TheWebmen_ArticlesPage_HighlightedArticles WHERE TheWebmen_ArticlesPageID = $parentID + ) AND ID IN (SELECT ID FROM SiteTree_Live WHERE ParentID = $parentID)" + ); + + DB::query(" + UPDATE TheWebmen_ArticlePage_Live SET Pinned = 1 WHERE ID IN ( + SELECT TheWebmen_ArticlePageID FROM TheWebmen_ArticlesPage_PinnedArticles WHERE TheWebmen_ArticlesPageID = $parentID + ) AND ID IN (SELECT ID FROM SiteTree_Live WHERE ParentID = $parentID) + "); + + DB::query(" + UPDATE TheWebmen_ArticlePage_Live SET Pinned = 0 WHERE ID NOT IN ( + SELECT TheWebmen_ArticlePageID FROM TheWebmen_ArticlesPage_PinnedArticles WHERE TheWebmen_ArticlesPageID = $parentID + ) AND ID IN (SELECT ID FROM SiteTree_Live WHERE ParentID = $parentID)" + ); + + parent::onAfterPublish(); + } }