/**
  * Check catalogue URL's before we get to the CMS (if it exists)
  * 
  * @param SS_HTTPRequest $request
  * @param DataModel|null $model
  * @return SS_HTTPResponse
  */
 public function handleRequest(SS_HTTPRequest $request, DataModel $model)
 {
     $this->request = $request;
     $this->setDataModel($model);
     $catalogue_enabled = Catalogue::config()->enable_frontend;
     $this->pushCurrent();
     // Create a response just in case init() decides to redirect
     $this->response = new SS_HTTPResponse();
     $this->init();
     // If we had a redirection or something, halt processing.
     if ($this->response->isFinished()) {
         $this->popCurrent();
         return $this->response;
     }
     // If DB is not present, build
     if (!DB::isActive() || !ClassInfo::hasTable('CatalogueProduct') || !ClassInfo::hasTable('CatalogueCategory')) {
         return $this->response->redirect(Director::absoluteBaseURL() . 'dev/build?returnURL=' . (isset($_GET['url']) ? urlencode($_GET['url']) : null));
     }
     $urlsegment = $request->param('URLSegment');
     $this->extend('onBeforeInit');
     $this->init();
     $this->extend('onAfterInit');
     // Find link, regardless of current locale settings
     if (class_exists('Translatable')) {
         Translatable::disable_locale_filter();
     }
     $filter = array('URLSegment' => $urlsegment, 'Disabled' => 0);
     if ($catalogue_enabled && ($object = CatalogueProduct::get()->filter($filter)->first())) {
         $controller = $this->controller_for($object);
     } elseif ($catalogue_enabled && ($object = CatalogueCategory::get()->filter($filter)->first())) {
         $controller = $this->controller_for($object);
     } elseif (class_exists('ModelAsController')) {
         // If CMS installed
         $controller = ModelAsController::create();
     } else {
         $controller = Controller::create();
     }
     if (class_exists('Translatable')) {
         Translatable::enable_locale_filter();
     }
     $result = $controller->handleRequest($request, $model);
     $this->popCurrent();
     return $result;
 }
 public function run($request)
 {
     $products = 0;
     $categories = 0;
     // First load all products
     $items = CatalogueProduct::get();
     foreach ($items as $item) {
         // Just write product, on before write should deal with the rest
         $item->write();
         $products++;
     }
     // Then all categories
     $items = CatalogueCategory::get();
     foreach ($items as $item) {
         // Just write category, on before write should deal with the rest
         $item->write();
         $categories++;
     }
     echo "Wrote {$products} products and {$categories} categories.\n";
 }
<?php

// If subsites is installed
if (class_exists('Subsite')) {
    CatalogueProduct::add_extension('SubsiteCatalogueExtension');
    CatalogueCategory::add_extension('SubsiteCatalogueExtension');
    TaxRate::add_extension('SubsiteCatalogueExtension');
    CatalogueAdmin::add_extension('SubsiteMenuExtension');
}
// Setup google sitemaps
$catalogue_enabled = Catalogue::config()->enable_frontend;
if ($catalogue_enabled && class_exists("GoogleSitemap")) {
    GoogleSitemap::register_dataobject('CatalogueProduct');
    GoogleSitemap::register_dataobject('CatalogueCategory');
}
 public function onBeforeWrite()
 {
     parent::onBeforeWrite();
     // Only call on first creation, ir if title is changed
     if ($this->ID == 0 || $this->isChanged('Title') || !$this->URLSegment) {
         // Set the URL Segment, so it can be accessed via the controller
         $filter = URLSegmentFilter::create();
         $t = $filter->filter($this->Title);
         // Fallback to generic name if path is empty (= no valid, convertable characters)
         if (!$t || $t == '-' || $t == '-1') {
             $t = "category-{$this->ID}";
         }
         // Ensure that this object has a non-conflicting URLSegment value.
         $existing_cats = CatalogueCategory::get()->filter('URLSegment', $t)->count();
         $existing_products = CatalogueProduct::get()->filter('URLSegment', $t)->count();
         $existing_pages = class_exists('SiteTree') ? SiteTree::get()->filter('URLSegment', $t)->count() : 0;
         $count = (int) $existing_cats + (int) $existing_products + (int) $existing_pages;
         $this->URLSegment = $count ? $t . '-' . ($count + 1) : $t;
     }
 }
 public function requireDefaultRecords()
 {
     parent::requireDefaultRecords();
     $records = CatalogueProduct::get()->filter("ClassName", "CatalogueProduct");
     if ($records->exists()) {
         // Alter any existing recods that might have the wrong classname
         foreach ($records as $product) {
             $product->ClassName = "Product";
             $product->write();
         }
         DB::alteration_message("Updated {$records->count()} Product records", 'obsolete');
     }
 }
 /**
  * Get a full list of products, filtered by a category if provided.
  *
  * @param ParentCategoryID the ID of the parent category
  */
 public function Products($ParentCategoryID = 0)
 {
     return CatalogueProduct::get()->filter(array("ParentID" => $ParentCategoryID, "Disabled" => 0));
 }