Blocks in Area

Permalink
Hi,

It is possible to know from a blockType view or controller the number of other similier blockType present in this Area ?
If yes it is possible to know if this block is te first, the last ?

Thank you a lot !

Seb

sebastienj
 
JohntheFish replied on at Permalink Reply
JohntheFish
In 5.6.2.1 you can do
$list_of_block_id = $page->getBlockIDs('Main');

Before 5.6.2.1 you needed to do
$list_of_block_obj = $page->getBlocks('Main');

Both return arrays in block order on the page that you can then loop through for blocks of a type.
sebastienj replied on at Permalink Reply
sebastienj
Thank you John !

And do you know how to retrieve the areaHandle where the block live from a the blockController ?

Thank a lot !

Seb
JohntheFish replied on at Permalink Reply
JohntheFish
I am afraid you have to do it the other way round. An area knows what blocks are in it. A block controller does not know what area it is in and can actually be in multiple areas and even pages if copied through the clipboard.

I needed to do lots of that sort of thing for the on_block_load processing that adds to Magic Data. I did it the hard way and looked for the block ID by listing all possible areas I was interested in (with some local memoizing for speed). It was that experience that got me refactoring the core to provide getBlockIDs() as a more efficient interface, but still limited to working that way round.

I guess that from a block controller it could also be achieved by crawling back up a stack backtrace and pulling out the relevant parameters. I don't know how efficient that would be and it could also be a bit fragile.
sebastienj replied on at Permalink Reply
sebastienj
Thank you John, you help me a lot !
Mainio replied on at Permalink Reply
Mainio
I believe this is actually possible from the block type controller with some DB action but it's really awkward and hard to get. I once tried to do something similar, here's an example (modified for your use case):

$blocksOnSameArea = 0;
if (is_object($this->block)) {
  $btID = $this->block->getBlockTypeID();
  $cID = $this->block->getBlockCollectionID();
  $arHandle = $this->block->getAreaHandle();
  $db = Loader::db();
  $sql = "SELECT COUNT(cvb.bID) FROM CollectionVersionBlocks cvb" .
    " INNER JOIN CollectionVersions cv ON cv.cID = cvb.cID AND cv.cvID = cvb.cvID" .
    " INNER JOIN Blocks b ON b.bID = cvb.bID" .
    " WHERE b.btID =? AND arHandle =? AND cvb.cID =? AND cv.cvIsApproved = 1";
  $blocksOnSameArea = intval($db->GetOne($sql, array($btID, $arHandle, $cID)));
}
echo t("There are %d block(s) of the same type within this area on the approved version of this page.", $blocksOnSameArea);


That gets you the number of blocks on the approved version of the page and in the same area that this block is on. Obviously, it shows you "incorrect" number when you edit the page and before you hit the "Publish my changes" button.

What I did instead is that I just put a variable in the global space and incremented that each time when the block was displayed (in my case I didn't have to care about the area but I would guess that would work also when you are aware of the target area). I thought it was a bit more reliable for the use case I had.
sebastienj replied on at Permalink Reply
sebastienj
Thank you Mainio, i will try that.