Skip to content

Commit 54df593

Browse files
authored
Merge pull request #10 from trms/bulletin-blocks
add bulletin block functionality and documentation
2 parents b07feed + a7a992c commit 54df593

File tree

9 files changed

+236
-10
lines changed

9 files changed

+236
-10
lines changed

README.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ composer install trms/carousel
3030

3131
[Bulletins](#bulletin)
3232

33+
[Bulletin & Template Blocks](#bulletinblock)
34+
3335
[Groups](#group)
3436

3537
[Media](#media)
@@ -247,6 +249,91 @@ A template is the starting point for a standard Bulletin and is comprised of a b
247249
|PreviewImageUrl|string|A low resolution rendering of the template|
248250
|FullImageUrl|string|A full resolution rendering of the template|
249251

252+
### BulletinBlock
253+
`TRMS\Carousel\Models\BulletinBlock`
254+
255+
A BulletinBlock is an area of content within a `Bulletin` or a `Template`. Blocks can be `Text`, `Picture`, `Video`, or `WebPicture`. Text blocks are just that, blocks containing text. Picture and Video blocks will take a Media Object. WebPicture blocks take the URL of an image. There are many properties on a block some of which apply to only one of the four `BlockType`s. Many have several properties that are used to make an effect, like a drop shadow or a text glow.
256+
#### Methods
257+
|Method|Parameters|Returns|Description|
258+
|------|----------|-------|-----------|
259+
|setMedia|Media Object|self - chainable|Sets the Media to be used in this model and sets the `blockType` to the corresponding Media type.|
260+
|getMedia|none|Media Object|Gets the related Media model.|
261+
#### Properties
262+
|Property|type|Description|
263+
|--------|----|-----------|
264+
BlockType|enumerable|Indicates the type of the block: `Rectangle`, `Ellipse`, `Text`, `Picture`, `WebPicture`, `Video`|
265+
Name|string|The name of the block|
266+
|**Size and Position**|
267+
X|int|The x coordinate of the upper left corner of the block.|
268+
Y|int|The y coordinate of the upper left corner of the block.|
269+
Width|int|The width in pixels of the block.|
270+
Height|int|The height in pixels of the block.|
271+
RotateDegrees:|int|The rotation of the block in degrees|
272+
|**Text Basic**|
273+
Text|string|The text to be displayed in a text block|
274+
AutoSizeText|boolean|If the block should auto size the text to fill the available block. If false the `TextSize` will be used|
275+
TextSize|int|The font size in points|
276+
|**Text Style**|
277+
TextFont|string|The font name of an installed font. (this is a relationship, getting the installed fonts is not currently supported in this package)|
278+
TextBold|boolean|Bold styling|
279+
TextItalic|boolean|Italic styling|
280+
TextStrikeout|boolean|Strikeout styling|
281+
TextUnderline|boolean|Underline styling|
282+
|**Text Color**|
283+
TextColor|css color value|The text color|
284+
TextColorOpacity|float 0-1|The opacity of the text|
285+
|**Text Alignment**|
286+
TextHorizAlignment|enumerable|The horizontal alignment of the text: `Near`,`Far`,`Center`|
287+
TextVertAlignment|enumerable|The horizontal alignment of the text: `Near`,`Far`,`Center`|
288+
TextRightToLeft|boolean|Draw the text right to left|
289+
TextWrap|boolean|Should the text line wrap|
290+
|**Text Gradient Fill**|
291+
TextGradient|boolean|Enable text gradient|
292+
TextGradientColor|css color value|The color of the gradient|
293+
TextGradientMode|enumerable|The direction of the gradient: `Horizontal`,`Vertical`,`ForwardDiagonal`,`BackwardDiagonal`|
294+
TextGradientOpacity|float 0-1|The opacity of the gradient|
295+
|**Text Stroke**|
296+
TextOutline|boolean|Enable text stroke|
297+
TextOutlineColor|css color value|The color of the stroke|
298+
TextOutlineOpacity|float 0-1|The opacity of the stroke|
299+
|**Text Drop Shadow**|
300+
TextShadow|boolean|Enable text shadow|
301+
TextShadowColor|css color value|The color of the shadow|
302+
TextShadowDepth|int|Value in pixels of the shadow depth|
303+
TextShadowOpacity|float 0-1|The opacity of the shadow|
304+
|**Text Glow**|
305+
TextGlow|boolean|Enable text glow|
306+
TextGlowColor|css color value|The color of the text glow|
307+
|**Block Color Fill**|
308+
RectColor|css color value|The background fill of the block|
309+
RectColorOpacity|float 0-1|The opacity of the fill|
310+
|**Block Gradient**|
311+
RectGradient||boolean|Enable block gradient|
312+
RectGradientColor|css color value|The color of the gradient|
313+
RectGradientMode|enumerable|The direction of the gradient: `Horizontal`,`Vertical`,`ForwardDiagonal`,`BackwardDiagonal`|
314+
RectGradientOpacity|float 0-1|The opacity of the gradient|
315+
|**Block Stroke**|
316+
RectOutline|boolean|Enable block stroke|
317+
RectOutlineColor|css color value|The color of the stroke|
318+
RectOutlineWidth|int|The width in pixels of the stroke|
319+
RectOutlineOpacity|float 0-1|The opacity of the stroke|
320+
|**Block Drop Shadow**|
321+
RectShadow|boolean|Enable block shadow|
322+
RectShadowColor|css color value|The color of the shadow|
323+
RectShadowDepth|int|Value in pixels of the shadow depth|
324+
RectShadowOpacity|float 0-1|The opacity of the shadow|
325+
|**Block Reflection**|
326+
Reflection|boolean|Enable block reflection|
327+
ReflectionOffset|int|Value in pixels of the reflection offset|
328+
ReflectionHeight|int|Value in pixels of the reflection height|
329+
ReflectionOpacity|float 0-1|The opacity of the reflection|
330+
|**Picture Block**|
331+
HorizAlignment|enumerable|The horizontal position of the image in the block: `Left`,`Center`,`Right`|
332+
VertAlignment|enumerable|The vertical position of the image in the block: `Top`,`Center`,`Bottom`|
333+
MaintainAspectRatio|boolean|Should the image stretch to fill the block|
334+
|**Web Picture Block**|
335+
ImageURL|string|URL of a remote image asset|
336+
250337
### Group
251338
`TRMS\Carousel\Models\Group`
252339

Tests/BulletinBlockTest.php

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
use TRMS\Carousel\Models\BulletinBlock;
3+
use TRMS\Carousel\Models\Media;
4+
use TRMS\Carousel\Exceptions\CarouselModelException;
5+
6+
use TRMS\Carousel\Server\API;
7+
8+
use GuzzleHttp\Handler\MockHandler;
9+
use GuzzleHttp\HandlerStack;
10+
use GuzzleHttp\Psr7\Response;
11+
use GuzzleHttp\Psr7\Request;
12+
13+
class BulletinBlockTest extends PHPUnit_Framework_TestCase
14+
{
15+
function test_you_can_set_a_picture_media_relationship_and_it_will_set_the_block_params_accordingly()
16+
{
17+
$block = new BulletinBlock();
18+
$picture = new Media(['id'=>'1','Type'=>'Picture']);
19+
$video = new Media(['id'=>'2','Type'=>'Video']);
20+
21+
$block->setMedia($picture);
22+
23+
$this->assertEquals($picture->id, $block->MediaID);
24+
$this->assertEquals($picture, $block->MediaObject);
25+
$this->assertEquals('Picture',$block->BlockType);
26+
27+
$block->setMedia($video);
28+
29+
$this->assertEquals($video->id, $block->MediaID);
30+
$this->assertEquals($video, $block->MediaObject);
31+
$this->assertEquals('Video',$block->BlockType);
32+
}
33+
34+
function test_a_Sound_media_cannot_be_added_to_a_block_and_throws_an_exception()
35+
{
36+
$block = new BulletinBlock();
37+
$sound = new Media(['id'=>'1','Type'=>'Sound']);
38+
39+
try{
40+
$block->setMedia($sound);
41+
} catch(CarouselModelException $e){
42+
return;
43+
}
44+
45+
$this->fail('the exception was not thrown');
46+
}
47+
48+
function test_a_Background_media_cannot_be_added_to_a_block_and_throws_an_exception()
49+
{
50+
$block = new BulletinBlock();
51+
$background = new Media(['id'=>'1','Type'=>'Background']);
52+
53+
try{
54+
$block->setMedia($background);
55+
} catch(CarouselModelException $e){
56+
return;
57+
}
58+
59+
$this->fail('the exception was not thrown');
60+
}
61+
62+
function test_you_can_get_the_background_media_relationship()
63+
{
64+
$block = new BulletinBlock();
65+
$picture = new Media(['id'=>'1','Type'=>'Picture']);
66+
67+
$block->setMedia($picture);
68+
$media = $block->getMedia();
69+
70+
$this->assertEquals($picture,$media);
71+
}
72+
73+
function test_if_the_media_object_has_not_been_resolved_an_api_request_will_be_made()
74+
{
75+
$mock = new MockHandler([
76+
new Response(200,[],json_encode(['id'=>'12'])),
77+
]);
78+
$handler = HandlerStack::create($mock);
79+
80+
$api = new API();
81+
$api->addMockHandler($handler);
82+
83+
$block = new BulletinBlock(['BlockType'=>'Picture','MediaID'=>'12']);
84+
$block->setApi($api);
85+
$media = $block->getMedia();
86+
87+
$this->assertInstanceOf(Media::class, $media);
88+
$this->assertEquals('12',$media->id);
89+
}
90+
91+
function test_using_getMedia_on_a_non_media_using_block_will_return_null()
92+
{
93+
$block = new BulletinBlock();
94+
$block->BlockType === 'Text';
95+
96+
$media = $block->getMedia();
97+
98+
$this->assertEquals(null, $media);
99+
100+
$block->BlockType === 'Rectangle';
101+
102+
$this->assertEquals(null, $media);
103+
}
104+
}

Tests/BulletinTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ function test_bulletin_blocks_serialize_correctly()
3232

3333
$bulletin->Blocks = [$block1, $block2];
3434

35-
$this->assertEquals(['BlockType'=>'Text','Text'=>'foobarbaz'], $bulletin->toArray()['Blocks'][0]);
36-
$this->assertEquals(['BlockType'=>'Rectangle'], $bulletin->toArray()['Blocks'][1]);
35+
$this->assertArraySubset(['BlockType'=>'Text','Text'=>'foobarbaz'], $bulletin->toArray()['Blocks'][0]);
36+
$this->assertArraySubset(['BlockType'=>'Rectangle'], $bulletin->toArray()['Blocks'][1]);
3737
}
3838

3939
function test_the_resolvePartial_method_will_get_partial_bulletins_from_the_api()
@@ -48,6 +48,7 @@ function test_the_resolvePartial_method_will_get_partial_bulletins_from_the_api(
4848

4949
$this->assertEquals(2, count($bulletin->Blocks));
5050
$this->assertInstanceOf(BulletinBlock::class, $bulletin->Blocks[0]);
51+
$this->assertInstanceOf(API::class, $bulletin->Blocks[0]->getApi());
5152
$this->assertEquals(false, $bulletin->PartialBulletin);
5253
\Mockery::close();
5354
}

Tests/TemplateTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ function test_template_blocks_serialize_correctly()
1414

1515
$template->Blocks = [$block1, $block2];
1616

17-
$this->assertEquals(['BlockType'=>'Text','Text'=>'foobarbaz'], $template->toArray()['Blocks'][0]);
18-
$this->assertEquals(['BlockType'=>'Rectangle'], $template->toArray()['Blocks'][1]);
17+
$this->assertArraySubset(['BlockType'=>'Text','Text'=>'foobarbaz'], $template->toArray()['Blocks'][0]);
18+
$this->assertArraySubset(['BlockType'=>'Rectangle'], $template->toArray()['Blocks'][1]);
1919
}
2020

2121
}

src/Models/BulletinBlock.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,34 @@
11
<?php namespace TRMS\Carousel\Models;
22

3+
use TRMS\Carousel\Exceptions\CarouselModelException;
4+
35
class BulletinBlock extends CarouselModel
46
{
7+
public $BlockType = 'Text';
8+
public $Name = 'My Awesome Block';
9+
510
public function getSaveEndpoint()
611
{
7-
throw new CarouselModelException('Bulletin Blocks cannot be directly saved');
12+
throw new CarouselModelException('Bulletin Blocks cannot be directly saved but are part of a Bulletin or Template');
13+
}
14+
15+
public function setMedia(Media $media)
16+
{
17+
if($media->Type === 'Sound' || $media->Type === 'Background'){
18+
throw new CarouselModelException('Sound and Background Media cannot be added to a block.');
19+
}
20+
$this->setBelongsTo('Media', $media);
21+
$this->BlockType = $media->Type;
22+
}
23+
24+
public function getMedia()
25+
{
26+
if($this->BlockType !== 'Picture' && $this->BlockType !== 'Video'){
27+
return null;
28+
}
29+
if($media = $this->getBelongsTo('Media',Media::class)){
30+
return $media;
31+
}
32+
throw new CarouselModelException("use setMedia method to set the block's media relationship");
833
}
934
}

src/Models/BulletinOrder.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@
33
use TRMS\Carousel\Exceptions\CarouselModelException;
44
use TRMS\Carousel\Models\BulletinOrderEntry;
55

6+
use TRMS\Carousel\Server\API;
7+
68
class BulletinOrder extends CarouselModel
79
{
810
protected $endpoint = 'orderentries';
911

10-
public function __construct(string $ZoneID, Array $props)
12+
public function __construct(string $ZoneID, Array $props, API $api=null)
1113
{
14+
if($api){
15+
$this->setApi($api);
16+
}
1217
$this->ZoneID = $ZoneID;
1318
$this->setOrderEntries($props);
1419
}

src/Models/CarouselModel.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ abstract class CarouselModel implements SaveableInterface
1212

1313
public function __construct(Array $props = [],API $api=null)
1414
{
15-
$this->setProps($props);
16-
1715
if($api){
1816
$this->setApi($api);
1917
}
18+
$this->setProps($props);
19+
2020
}
2121

2222
public function setProps(Array $props)

src/Models/Traits/HasBlocks.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ private function setBlocksFromProps($props)
1919

2020
public function addBlock(BulletinBlock $block)
2121
{
22+
$api = $this->getApi();
23+
if($api){
24+
$block->setApi($api);
25+
}
2226
array_push($this->Blocks, $block);
2327
return $this;
2428
}

src/Server/API.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public function get(ModelRequest $request)
6666
$response = $apiRequest->get($request->url(),$request->queryParams);
6767

6868
if($responseClass === BulletinOrder::class){
69-
return new BulletinOrder($request->queryParams['ZoneID'], $response);
69+
return new BulletinOrder($request->queryParams['ZoneID'], $response, $this);
7070
}
7171

7272
return collect($response)->filter()->map(function($properties) use ($responseClass){
@@ -79,7 +79,7 @@ public function save(CarouselModel $model)
7979
{
8080
$endpoint = $model->getSaveEndpoint();
8181
$method = $model->getSaveMethod();
82-
if($model->getApi() && $model->PartialBulletin){
82+
if($model->getApi() && empty($model->PartialBulletin) === false){
8383
$model->resolvePartial();
8484
}
8585
$options = [

0 commit comments

Comments
 (0)