Sky Blue Sofa Blog Block Copies in Concrete5 - Sky Blue Sofa Blog

Block Copies in Concrete5

Posted by Dave Rogers // December 9, 2013 // in Blog // 0 Comments

Copy Machine

A client of mine wanted some functionality that inserted an image into a slideshow from within the dashboard instead of editing the page and the slideshow block. Easy, I thought. I thought wrong. Well mostly right, but what I overlooked was a real pain.

Most of the time, the code worked flawlessly. The issue came when the client copied a page and then tried to insert an image into a slideshow on only one of those pages. Take this partial sitemap for example:

Screen_Shot_2013-12-09_at_3.44.22_PM.png

On this site, we have a page called 'Articles' with 3 pages below it. The first one, 'Article 1' is the original. The other two, 'Article 1 2' and 'Article 1 3' are copies of the original article.

Now if I try to insert an image into the slideshow block on 'Article 1', it works great, except for the fact that it also gets inserted into the slideshow block on both copies of the original. Here's the original code:

  1. function insertIntoSlideShow($block, $data) {
  2. $db = Loader::db();
  3.  
  4. $blockId = $block->getBlockID();
  5.  
  6. $sql = "UPDATE btSlideshowImg SET position=position+1 WHERE bID=?";
  7. $db->execute($sql, array($blockId));
  8.  
  9. $sql = "INSERT INTO btSlideshowImg (bID, fID, duration, position) VALUES (?, ?, ?, ?)";
  10. $v = array($blockId, $row['fileID'], $row['duration'], 0);
  11. $db->execute($sql, $v);
  12. }

How to Fix It?

I was banging my head for quite a few days trying to figure this one out. Then I discovered information revealing that the slideshow blocks in 'Article 1 2' and 'Article 1 3', do not belong to the page copies. They are, in fact, aliases of the original block. I think this is done to keep from adding cruft to the database. As soon as you go to one of the copied pages and edit the slideshow block, it stops being an alias and becomes a block of the page.

As soon as I realized this, the fix became clear. Here's the code that I used:

  1. function insertIntoSlideShow($collectionVersion, $block, $data) {
  2. $original_block = $block;
  3. $collection = Page::getByID($collectionVersion->getCollectionID());
  4. $block = $block->duplicate($collection);
  5. $original_block->deleteBlock();
  6. $db = Loader::db();
  7.  
  8. $blockId = $block->getBlockID();
  9.  
  10. $sql = "UPDATE btSlideshowImg SET position=position+1 WHERE bID=?";
  11. $db->execute($sql, array($blockId));
  12.  
  13. $sql = "INSERT INTO btSlideshowImg (bID, fID, duration, position) VALUES (?, ?, ?, ?)";
  14. $v = array($blockId, $row['fileID'], $row['duration'], 0);
  15. $db->execute($sql, $v);
  16. }

You'll see that I added a $collectionVersion variable when the function gets called, but the real magic lies in the first 4 lines of the updated function.

In essence:

  1. Create a reference to the original block
  2. Get a collection object for the new page. You can't just get the collection object of the block, because it will reference the original collection.
  3. Duplicate the block. This creates a new blockID and assigns it to the copied page.
  4. Delete the old block.

I hope this helps someone. My forehead can really use some TLC right now.

About the Author

Dave Rogers

Dave is the founder of Sky Blue Sofa Web Design. He enjoys working out, spending time with his wife and dogs and programming. He grew up and currently resides in the Illinois Quad Cities. You can find his personal blog at strength/reliance.com.

View Profile »

Comments

You must be logged in to leave a reply. Login »