This is the documentation for concrete5 version 5.6 and earlier. View Current Documentation

Areas plays a key role by associating blocks to pages. The code samples I'm sharing here were made while I was working on the issue of areas going missing or cluttering the database during theme changes. If you change themes and your new theme doesn't have the same areas as your old theme, where do the areas go? The answer is the areas, and the blocks they contain stay in the database. So the goal here is to show a list of all areas and their content blocks, and give the option to delete the area.

We start by extending the core Areas model.

class AreaManager extends Concrete5_Model_Area {

We can use the static function from Model Area to get a list of all areas in C5.

$areaHandles = AreaManager::getHandleList();
foreach( $areaHandles as $ah ) {
  // $ah is the Area Handle such as "Main"
}

I'm only going to share the PHP code here focused on Areas but once you load all areas you can loop through them and use the Area handle to load the Area model, or you can use that Area handle for use in various block or collection methods.

What we're going to do here is make a new method in our AreaManager class that gets all the pages that have the given area handle.

public function getAreaPages() {
  $db = Loader::db();
  $r = $db->query("select cID from Areas where arHandle = ?", parent::getAreaHandle() );
  $areaPages = array();
  while ($row = $r->fetchRow()) {
    $areaPages[] = Page::getByID( $row['cID'] );
  }
  return $areaPages;
}

In this function we load all the collection ID's associated with the current handle. Notice that we use the parent method getAreaHandle to get the current handle. This handle must be passed to the AreaManager when you initiate the class because the parent Concrete5_Model_Area constructor requires it. So to use the AreaManager class we initiate with:

$am = new AreaManager($ah);

Remember that getHandleList() can be used to load a list of all handles so generally you will call that static method to get the list, then you can load individual areas using it's area handle.

So now we can load all our areas, and load all our pages that use those areas. What's next? Blocks!! In the code below we load all the count of how many blocks are in each area.

foreach( $areaHandles as $ah ) {
$am = new AreaManager($ah);
$areaPages = $am->getAreaPages();
    foreach( $areaPages as $p ) {
      print $am->getTotalBlocksInArea($p) . "";
    }
}

Note that just like in a theme you can also use display() method as in $am->display to show the content of the area. In the example above we're working toward making a data style table, we don't want to show the content we just want the number of blocks for reference.

Now let's look at how to blast away existing areas and their content.

// delete all blocks from an area on a page
protected function clearArea(Page $page, $arHandle) {
  if( $arHandle ) {
        $blocks = $page->getBlocks( $arHandle );
    foreach($blocks as $b) {
          $b->deleteBlock(); 
    }
  }
}

Here we make a method clearArea that will delete all blocks from an a given area on a given page. We must pass a page object (not a cID) plus the area handle.

So we'll use this clearArea method inside our next method to handle our deletion of blocks. Now let's create the function that lays waste to the area.

public function deleteArea($cid) {
  $db = Loader::db();
  $arHandle = parent::getAreaHandle();

  $r = $db->query("select cID from Areas where arHandle = ?", array( $arHandle) );
  while ($row = $r->fetchRow()) {
    $page = Page::getByID( $row['cID'] );
    $this->clearArea($page, $arHandle);

       $db->query("delete from Areas where arHandle = ?", array( $arHandle) );
 }

So here we get the area handle and use that to get a list of all the pages using that handle. We then delete all blocks using $this->clearArea. Finally we delete the area itself. Note this only does a thorough job on regular areas, for global areas we would need to also remove the stacks, page paths and possibly some other records as well.

Hopefully if you're doing some work around areas this how to has been a helpful introduction to extending the core Area library. There are certainly many other things you might do with Areas. One of the interesting parts of this aspect of C5 is that if you load Areas directly you can get at the content in a different way than you can through pages. For instance instead of loading all sidebar blocks for 1 page, you can load all sidebar blocks for the entire site.

Loading Conversation