diff --git a/README.md b/README.md index 0bc14cd..5edce40 100644 --- a/README.md +++ b/README.md @@ -38,12 +38,11 @@ be deleted through the CMS. ```yaml Heyday\MenuManager\MenuSet: - default_sets: - - Main - - Footer + default_sets: + - Main + - Footer ``` - ### Creating MenuItems Once you have saved your MenuSet you can add MenuItems. @@ -73,7 +72,7 @@ Page as well the link will be overwritten by the Page you chose. #### IsNewWindow -Can be used as a check to see if 'target="_blank"' should be added to links. +Can be used as a check to see if 'target="\_blank"' should be added to links. ### Disable creating Menu Sets in the CMS @@ -82,7 +81,7 @@ disable the ability to create new Menu Sets in the CMS: ```yml Heyday\MenuManager\MenuAdmin: - enable_cms_create: false + enable_cms_create: false ``` _Note: Non-default Menu Sets can still be deleted, to help tidy unwanted CMS @@ -91,28 +90,28 @@ content._ ### Usage in template ```html - <% loop $MenuSet('YourMenuName').MenuItems %> - {$MenuTitle} - <% end_loop %> +<% loop $MenuSet('YourMenuName').MenuItems %> +{$MenuTitle} +<% end_loop %> ``` -To loop through *all* MenuSets and their items: +To loop through _all_ MenuSets and their items: - <% loop $MenuSets %> - <% loop $MenuItems %> - $MenuTitle - <% end_loop %> - <% end_loop %> + <% loop $MenuSets %> + <% loop $MenuItems %> + $MenuTitle + <% end_loop %> + <% end_loop %> Optionally you can also limit the number of MenuSets and MenuItems that are looped through. The example below will fetch the top 4 MenuSets (as seen in Menu Management), and the top 5 MenuItems for each: - <% loop $MenuSets.Limit(4) %> - <% loop $MenuItems.Limit(5) %> - $MenuTitle - <% end_loop %> - <% end_loop %> + <% loop $MenuSets.Limit(4) %> + <% loop $MenuItems.Limit(5) %> + $MenuTitle + <% end_loop %> + <% end_loop %> #### Enabling partial caching @@ -120,17 +119,15 @@ The example below will fetch the top 4 MenuSets (as seen in Menu Management), an can be enabled with your menu to speed up rendering of your templates. ```html - <% with $MenuSet('YourMenuName') %> - <% cached 'YourMenuNameCacheKey', $LastEdited, $MenuItems.max('LastEdited'), $MenuItems.count %> - <% if $MenuItems %> - - <% end_if %> - <% end_cached %> - <% end_with %> +<% with $MenuSet('YourMenuName') %> <% cached 'YourMenuNameCacheKey', +$LastEdited, $MenuItems.max('LastEdited'), $MenuItems.count %> <% if $MenuItems +%> + +<% end_if %> <% end_cached %> <% end_with %> ``` ### Allow sorting of MenuSets @@ -139,16 +136,29 @@ By default menu sets cannot be sorted, however, you can set your configuration t ```yaml Heyday\MenuManager\MenuSet: - allow_sorting: true + allow_sorting: true ``` +## Subsite Support -### Code guidelines +If you're using SilverStripe Subsites, you can make MenuManager subsite aware +via applying an extension to the MenuSet. -This project follows the standards defined in: +_app/\_config/menus.yml_ -* [PSR-1](http://www.php-fig.org/psr/psr-1/) -* [PSR-2](http://www.php-fig.org/psr/psr-2/) +``` +Heyday\MenuManager\MenuSet: + create_menu_sets_per_subsite: true + extensions: + - Heyday\MenuManager\Extensions\MenuSubsiteExtension +Heyday\MenuManager\MenuItem: + extensions: + - Heyday\MenuManager\Extensions\MenuSubsiteExtension +``` +## Code guidelines +This project follows the standards defined in: +- [PSR-1](http://www.php-fig.org/psr/psr-1/) +- [PSR-2](http://www.php-fig.org/psr/psr-2/) diff --git a/_config/extensions.yml b/_config/extensions.yml new file mode 100644 index 0000000..fdc21e0 --- /dev/null +++ b/_config/extensions.yml @@ -0,0 +1,13 @@ +--- +Name: menu-manager#extensions +Only: + classexists: '\SilverStripe\Subsites\Model\Subsite' +--- +SilverStripe\Subsites\Model\Subsite: + has_many: + - MenuSets => 'Heyday\MenuManager\MenuSet' + cascade_deletes: + - MenuSets +Heyday\MenuManager\MenuAdmin: + extensions: + - SilverStripe\Subsites\Extensions\SubsiteMenuExtension diff --git a/src/Extensions/MenuSubsiteExtension.php b/src/Extensions/MenuSubsiteExtension.php new file mode 100644 index 0000000..4fdbe34 --- /dev/null +++ b/src/Extensions/MenuSubsiteExtension.php @@ -0,0 +1,67 @@ + 'SilverStripe\Subsites\Model\Subsite' + ]; + + public function updateCMSFields(FieldList $fields) + { + $fields->replaceField('SubsiteID', new HiddenField('SubsiteID')); + } + + public function onBeforeWrite() + { + if (!$this->owner->SubsiteID) { + $this->owner->SubsiteID = \SilverStripe\Subsites\State\SubsiteState::singleton()->getSubsiteId(); + } + } + + + public function requireDefaultRecords() + { + if ($this->owner->config()->get('create_menu_sets_per_subsite')) { + $subsites = \SilverStripe\Subsites\Model\Subsite::get(); + $names = $this->owner->getDefaultSetNames(); + + if ($names) { + foreach ($subsites as $subsite) { + $state = \SilverStripe\Subsites\State\SubsiteState::singleton(); + + $state->withState(function () use ($subsite, $names) { + \SilverStripe\Subsites\State\SubsiteState::singleton()->setSubsiteId($subsite->ID); + + foreach ($names as $name) { + $existingRecord = MenuSet::get() + ->filter([ + 'Name' => $name, + 'SubsiteID' => $subsite->ID + ]) + ->first(); + + if (!$existingRecord) { + $set = MenuSet::create(); + $set->Name = $name; + $set->SubsiteID = $subsite->ID; + $set->write(); + } + } + }); + } + } + } + } +} diff --git a/src/MenuAdmin.php b/src/MenuAdmin.php index e983a80..f33ecd0 100644 --- a/src/MenuAdmin.php +++ b/src/MenuAdmin.php @@ -4,8 +4,6 @@ use SilverStripe\Admin\ModelAdmin; use SilverStripe\Core\Config\Config; -use SilverStripe\Forms\FieldList; -use SilverStripe\Forms\Form; use SilverStripe\Forms\GridField\GridField; use SilverStripe\Forms\GridField\GridFieldAddNewButton; use SilverStripe\Forms\GridField\GridFieldImportButton; @@ -80,4 +78,20 @@ public function getEditForm($id = null, $fields = null) return $form; } + + + public function getList() + { + $list = parent::getList(); + + if ($this->modelClass === MenuSet::class) { + if (class_exists('\SilverStripe\Subsites\State\SubsiteState')) { + $list = $list->filter([ + 'SubsiteID' => \SilverStripe\Subsites\State\SubsiteState::singleton()->getSubsiteId() + ]); + } + } + + return $list; + } } diff --git a/src/MenuManagerTemplateProvider.php b/src/MenuManagerTemplateProvider.php index 3ba1f48..ebf6aac 100644 --- a/src/MenuManagerTemplateProvider.php +++ b/src/MenuManagerTemplateProvider.php @@ -36,7 +36,7 @@ public static function MenuSet($name): ?MenuSet /** * @return MenuSet|null */ - public static function MenuSets(): ?MenuSet + public static function MenuSets(): ?DataList { return MenuSet::get(); } @@ -54,8 +54,18 @@ public function findMenuSetByName(string $name): ?DataObject if (empty($name)) { throw new InvalidArgumentException("Please pass in the name of the MenuSet you're trying to find"); } + $result = MenuSet::get()->filter('Name', $name); + + if ($result->exists() && $result->first()->hasExtension('Heyday\MenuManager\Extensions\MenuSubsiteExtension')) { + $result = $result->where(sprintf( + 'SubsiteID = %s', + \SilverStripe\Subsites\State\SubsiteState::singleton()->getSubsiteId() + )); + } + $this->extend('updateFindMenuSetByName', $result); + return $result->first(); } } diff --git a/src/MenuSet.php b/src/MenuSet.php index 0146044..47a80d6 100644 --- a/src/MenuSet.php +++ b/src/MenuSet.php @@ -4,6 +4,7 @@ use SilverStripe\Forms\FieldList; use SilverStripe\Forms\GridField\GridField; +use SilverStripe\Forms\GridField\GridFieldAddExistingAutocompleter; use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor; use SilverStripe\Forms\TabSet; use SilverStripe\Forms\TextareaField; @@ -37,6 +38,10 @@ class MenuSet extends DataObject implements PermissionProvider 'MenuItems' ]; + private static array $cascade_duplicates = [ + 'MenuItems' + ]; + private static array $searchable_fields = [ 'Name', 'Description' @@ -70,7 +75,6 @@ public function validate() * Use an index for the Name field instead https://docs.silverstripe.org/en/4/developer_guides/model/indexes/ */ if ($existing && $existing->ID !== $this->ID) { - // MenuSets must have a unique Name $result->addError( _t( __CLASS__ . 'AlreadyExists', @@ -177,19 +181,34 @@ public function requireDefaultRecords(): void { parent::requireDefaultRecords(); - foreach ($this->getDefaultSetNames() as $name) { - $existingRecord = MenuSet::get() - ->filter('Name', $name) - ->first(); + if ($this->createDefaultMenuSets()) { + DB::alteration_message(sprintf( + "MenuSets created (%s)", + implode(', ', $this->getDefaultSetNames()) + ), 'created'); + } + } - if (!$existingRecord) { - $set = MenuSet::create(); - $set->Name = $name; - $set->write(); - DB::alteration_message("MenuSet '$name' created", 'created'); + public function createDefaultMenuSets() + { + if ($this->getDefaultSetNames()) { + foreach ($this->getDefaultSetNames() as $name) { + $existingRecord = MenuSet::get() + ->filter('Name', $name) + ->first(); + + if (!$existingRecord) { + $set = MenuSet::create(); + $set->Name = $name; + $set->write(); + } } + + return true; } + + return false; } @@ -214,7 +233,7 @@ public function getCMSFields(): FieldList ); $config->addComponent(new GridFieldOrderableRows('Sort')); - + $config->removeComponentsByType(GridFieldAddExistingAutocompleter::class); $fields->addFieldToTab( 'Root.Meta', TextareaField::create('Description', _t(__CLASS__ . '.DB_Description', 'Description')) @@ -268,7 +287,7 @@ public function onBeforeDelete() * * @return string[] */ - protected function getDefaultSetNames() + public function getDefaultSetNames() { return $this->config()->get('default_sets') ?: []; }