Jump to:

10928 Posts in 2612 Topics by 1809 members

All other Modules

SilverStripe Forums » All other Modules » Subsites Module access content from pages in Main.

Discuss all other Modules here.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1
Go to End
Author Topic: 1784 Views
  • micahsheets
    Avatar
    Community Member
    164 Posts

    Subsites Module access content from pages in Main. Link to this post

    I have some pages in the Main site that I need to access the Content of from all the subsites. At this point It seems that the $disable_subsite_filter = false; in Subsite.php blocks access to DataObject::get('SiteTree',..... for any page not in the current subsite even SubsiteID = 0 pages.

    How can I access pages in SubsiteID = 0 from other subsites?

  • UncleCheese
    Avatar
    4085 Posts

    Re: Subsites Module access content from pages in Main. Link to this post

    Hi, Micah,

    I did this on a recent project. Took a little bit of hacking, but my approach was to set up a relationship of SiteTree -> MM -> Subsites and each page has a "Publication" tab where you click off which subsites can access the content on this page. "Global" is also an option.

    I then had to hack the augmentSQL() function in SiteTreeSubsites to make it aware of the new filtering rules (or lack thereof).

    Here are the major changes to SiteTreeSubsites.php:

       function extraStatics() {
          if(!method_exists('DataObjectDecorator', 'load_extra_statics')) {
             if($this->owner->class != 'SiteTree') return null;
          }
          return array(
           'db' => array(
           'GlobalContent' => 'Boolean'
           ),
             'has_one' => array(
                'Subsite' => 'Subsite', // The subsite that this page belongs to
                'MasterPage' => 'SiteTree', // Optional; the page that is the content master
             ),
             'many_many' => array(
              'Subsites' => 'Subsite'
             )
          );
       }

       function augmentSQL(SQLQuery &$query) {
          if(Subsite::$disable_subsite_filter) return;
          
          // If you're querying by ID, ignore the sub-site - this is a bit ugly...
          if(!$query->where || (strpos($query->where[0], ".\"ID\" = ") === false && strpos($query->where[0], ".`ID` = ") === false && strpos($query->where[0], ".ID = ") === false && strpos($query->where[0], "ID = ") !== 0)) {

             if($context = DataObject::context_obj()) $subsiteID = (int) $context->SubsiteID;
             else $subsiteID = (int) Subsite::currentSubsiteID();

             
             // The foreach is an ugly way of getting the first key
             foreach($query->from as $tableName => $info) {
          $query->from['SiteTree_Subsites'] = "LEFT JOIN SiteTree_Subsites ON SiteTree_Subsites.SiteTreeID = `$tableName`.ID";
          $query->from['Subsites'] = "LEFT JOIN Subsite ON Subsite.ID = SiteTree_Subsites.SubsiteID";

                $where = "(`$tableName`.SubsiteID IN ($subsiteID)) OR (`$tableName`.GlobalContent = 1) OR `Subsite`.ID = $subsiteID";
                
                if(defined('Database::USE_ANSI_SQL')) {
                   $where = "\"$tableName\".\"SubsiteID\" IN ($subsiteID)";
                }
                
                // The tableName should be SiteTree or SiteTree_Live...
                if(strpos($tableName,'SiteTree') === false) break;
                $query->where[] = $where;
                break;
             }
          }
       }

       function updateCMSFields(&$fields) {
          if($this->owner->MasterPageID) {
             $fields->insertFirst(new HeaderField('This page\'s content is copied from a master page: ' . $this->owner->MasterPage()->Title, 2));
          }
          
          // replace readonly link prefix
          $subsite = $this->owner->Subsite();
          if($subsite && $subsite->ID) {
             $baseUrl = 'http://' . $subsite->domain() . '/';
             $fields->removeByName('BaseUrlLabel');
             $fields->addFieldToTab(
                'Root.Content.Metadata',
                new LabelField('BaseUrlLabel',$baseUrl),
                'URLSegment'
             );
          }
          if($this->isMainSite()) {
           $fields->addFieldToTab("Root.Content.Publication", new CheckboxField('GlobalContent','This page can be viewed by all subsites'));
    $map = ($subs = DataObject::get("Subsite")) ? $subs->toDropdownMap() : array();
           $fields->addFieldToTab("Root.Content.Publication", new CheckboxSetField('Subsites','This page is only visible on the following subsites',$map));
          }
       }
       

    And to Subsite.php;

       static $belongs_many_many = array(
        'SiteTree' => 'SiteTree'
       );

    That should be it. I also hacked the Subsite module to support multiple domains, not just subdomains, if you're interested in that, too.

  • micahsheets
    Avatar
    Community Member
    164 Posts

    Re: Subsites Module access content from pages in Main. Link to this post

    Wow, that is a lot of code. I will have to take some time to look into it. Thanks for sharing your hard work.

  • infoclipper
    Avatar
    Community Member
    5 Posts

    Re: Subsites Module access content from pages in Main. Link to this post

    UncleCheese: I would be definitely be interested in the domain hack, if you wouldn't mind sharing.

  • UncleCheese
    Avatar
    4085 Posts

    Re: Subsites Module access content from pages in Main. Link to this post

    I've attached my Subsites.php and my SiteTreeSubsites.php. These should give you the content syndication plus the ability to use domains instead of subdomains.

    A note about the domain hack. It's not perfect. The Subsites module will yell at you if you leave the subdomain blank on create, but if you put in a junk value and then go back and remove it on edit, you can get it to retain the null value.

    I believe these are the only files I modified. If they don't work for you, let me know and I'll look around.

    1784 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.