สร้าง Flex Message ด้วย XML กับ LINE Messaging API ตอนที่ 10

เขียนเมื่อ 4 ปีก่อน โดย Ninenik Narkdee
line bot sdk bot flex message

คำสั่ง การ กำหนด รูปแบบ ตัวอย่าง เทคนิค ลูกเล่น การประยุกต์ การใช้งาน เกี่ยวกับ line bot sdk bot flex message

ดูแล้ว 11,102 ครั้ง




ต่อจากตอนที่แล้ว เราได้รู้จักกับ Flex Message ว่ามีองค์ประกอบ
อะไรบ้าง รวมถึงการสร้างข้อความ Flex Message ด้วย Line bot sdk
แยกตามแต่ละ Component ได้รู้จักกับแนวทางการสร้าง Flex Message
Layout สามารถทบทวนเนื้อหาได้ที่บทความ
    เริ่มต้นการใช้งาน Flex Message ผ่าน LINE Messaging API ตอนที่ 9 http://niik.in/899
 
ในตอนต่อไปนี้ เราจะมาเข้าสู่รายละเอียดทั้งหมดของการใช้งาน Flex Message
ผ่าน Line bot sdk และมาทำความรู้จักกับแนวทางการประยุกต์การสร้าง Flex Message 
ด้วยรูปแบบ XML 
 

Class ที่จำเป็นในการใช้งาน Flex Message 

    ให้เราเพิ่ม class เหล่านี้เข้าไปในไฟล์ bot.php และ bot_action.php
 
use LINE\LINEBot\Constant\Flex\ComponentIconSize;
use LINE\LINEBot\Constant\Flex\ComponentImageSize;
use LINE\LINEBot\Constant\Flex\ComponentImageAspectRatio;
use LINE\LINEBot\Constant\Flex\ComponentImageAspectMode;
use LINE\LINEBot\Constant\Flex\ComponentFontSize;
use LINE\LINEBot\Constant\Flex\ComponentFontWeight;
use LINE\LINEBot\Constant\Flex\ComponentMargin;
use LINE\LINEBot\Constant\Flex\ComponentSpacing;
use LINE\LINEBot\Constant\Flex\ComponentButtonStyle;
use LINE\LINEBot\Constant\Flex\ComponentButtonHeight;
use LINE\LINEBot\Constant\Flex\ComponentSpaceSize;
use LINE\LINEBot\Constant\Flex\ComponentGravity;
use LINE\LINEBot\MessageBuilder\FlexMessageBuilder;
use LINE\LINEBot\MessageBuilder\Flex\BubbleStylesBuilder;
use LINE\LINEBot\MessageBuilder\Flex\BlockStyleBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ContainerBuilder\BubbleContainerBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ContainerBuilder\CarouselContainerBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\BoxComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\ButtonComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\IconComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\ImageComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\SpacerComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\FillerComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\SeparatorComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\TextComponentBuilder;
 
ต่อไปให้เราสร้างไฟล์ชื่อ flex_gen.php ไฟล์นี้เป็นไฟล์ที่รวมฟังก์ชั่น ที่ผู้เขียนสร้างขึ้นมาประยุกต์
สำหรับแปลง Flex Message ในรูปแบบ XML โดยจะใช้คำสั่ง createFlex()
 

ไฟล์ flex_gen.php

<?php
///////////// ส่วนของการเรียกใช้งาน class ผ่าน namespace
use LINE\LINEBot;
use LINE\LINEBot\HTTPClient;
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
use LINE\LINEBot\Event;
use LINE\LINEBot\Event\BaseEvent;
use LINE\LINEBot\Event\MessageEvent;
use LINE\LINEBot\Event\AccountLinkEvent;
use LINE\LINEBot\Event\MemberJoinEvent; 
use LINE\LINEBot\MessageBuilder;
use LINE\LINEBot\MessageBuilder\TextMessageBuilder;
use LINE\LINEBot\MessageBuilder\StickerMessageBuilder;
use LINE\LINEBot\MessageBuilder\ImageMessageBuilder;
use LINE\LINEBot\MessageBuilder\LocationMessageBuilder;
use LINE\LINEBot\MessageBuilder\AudioMessageBuilder;
use LINE\LINEBot\MessageBuilder\VideoMessageBuilder;
use LINE\LINEBot\ImagemapActionBuilder;
use LINE\LINEBot\ImagemapActionBuilder\AreaBuilder;
use LINE\LINEBot\ImagemapActionBuilder\ImagemapMessageActionBuilder ;
use LINE\LINEBot\ImagemapActionBuilder\ImagemapUriActionBuilder;
use LINE\LINEBot\MessageBuilder\Imagemap\BaseSizeBuilder;
use LINE\LINEBot\MessageBuilder\ImagemapMessageBuilder;
use LINE\LINEBot\MessageBuilder\MultiMessageBuilder;
use LINE\LINEBot\TemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\DatetimePickerTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\MessageTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\PostbackTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\UriTemplateActionBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateMessageBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ButtonTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\CarouselTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\CarouselColumnTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ConfirmTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ImageCarouselTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ImageCarouselColumnTemplateBuilder;
use LINE\LINEBot\QuickReplyBuilder;
use LINE\LINEBot\QuickReplyBuilder\QuickReplyMessageBuilder;
use LINE\LINEBot\QuickReplyBuilder\ButtonBuilder\QuickReplyButtonBuilder;
use LINE\LINEBot\TemplateActionBuilder\CameraRollTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\CameraTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\LocationTemplateActionBuilder;
use LINE\LINEBot\RichMenuBuilder;
use LINE\LINEBot\RichMenuBuilder\RichMenuSizeBuilder;
use LINE\LINEBot\RichMenuBuilder\RichMenuAreaBuilder;
use LINE\LINEBot\RichMenuBuilder\RichMenuAreaBoundsBuilder;
use LINE\LINEBot\Constant\Flex\ComponentIconSize;
use LINE\LINEBot\Constant\Flex\ComponentImageSize;
use LINE\LINEBot\Constant\Flex\ComponentImageAspectRatio;
use LINE\LINEBot\Constant\Flex\ComponentImageAspectMode;
use LINE\LINEBot\Constant\Flex\ComponentFontSize;
use LINE\LINEBot\Constant\Flex\ComponentFontWeight;
use LINE\LINEBot\Constant\Flex\ComponentMargin;
use LINE\LINEBot\Constant\Flex\ComponentSpacing;
use LINE\LINEBot\Constant\Flex\ComponentButtonStyle;
use LINE\LINEBot\Constant\Flex\ComponentButtonHeight;
use LINE\LINEBot\Constant\Flex\ComponentSpaceSize;
use LINE\LINEBot\Constant\Flex\ComponentGravity;
use LINE\LINEBot\MessageBuilder\FlexMessageBuilder;
use LINE\LINEBot\MessageBuilder\Flex\BubbleStylesBuilder;
use LINE\LINEBot\MessageBuilder\Flex\BlockStyleBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ContainerBuilder\BubbleContainerBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ContainerBuilder\CarouselContainerBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\BoxComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\ButtonComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\IconComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\ImageComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\SpacerComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\FillerComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\SeparatorComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\TextComponentBuilder;


$is_carousel = NULL;
$is_bubble = NULL;
$is_singleBubble = NULL;
$count_container = 0;
$count_bubble = 0;
$name_container = NULL;

$bubble_direction = array();
$block_header = array();
$block_hero = array();
$block_body = array();
$block_footer = array();
$block_header_style = array();
$block_hero_style = array();
$block_body_style = array();
$block_footer_style = array();
$box_header = array();
$box_hero = array();
$box_body = array();
$box_footer = array();

function bubbleContainerAttr($xmlObj){
	$bubbleContainer = $xmlObj;
	$bubbleContainerAttr = NULL;
	foreach($bubbleContainer->attributes() as $key=>$val){
		if($key=="direction"){$bubbleContainerAttr[0]=implode("",(array)$val[0]);}
	}	
	return $bubbleContainerAttr;			
}
function blockStyleAttr($xmlObj){
	$blockStyle = $xmlObj;
	$blockStyleAttr = array(null,null,null);
	foreach($blockStyle->attributes() as $key=>$val){
		if($key=="backgroundColor"){$blockStyleAttr[0]=implode("",(array)$val[0]);}
		if($key=="separator"){$blockStyleAttr[1]=(boolean)implode("",(array)$val[0]);}
		if($key=="separatorColor"){$blockStyleAttr[2]=implode("",(array)$val[0]);}
	}	
	if(count($blockStyle->attributes())>0){
		return $blockStyleAttr;			
	}else{
		return NULL;	
	}
}
function textComponentArr($xmlObj){
	$textComponent = $xmlObj;
	$textComponentAttr = array(trim((string)$textComponent),null,null,null,null,null,null,null,null,null,null);
	foreach($textComponent->attributes() as $key=>$val){
		if($key=="flex"){$textComponentAttr[1]=(int)implode("",(array)$val[0]);}
		if($key=="margin"){$textComponentAttr[2]=implode("",(array)$val[0]);}
		if($key=="size"){$textComponentAttr[3]=implode("",(array)$val[0]);}
		if($key=="align"){$textComponentAttr[4]=implode("",(array)$val[0]);}
		if($key=="gravity"){$textComponentAttr[5]=implode("",(array)$val[0]);}
		if($key=="wrap"){$textComponentAttr[6]=(boolean)implode("",(array)$val[0]);}
		if($key=="maxLines"){$textComponentAttr[7]=(int)implode("",(array)$val[0]);}
		if($key=="weight"){$textComponentAttr[8]=implode("",(array)$val[0]);}		
		if($key=="color"){$textComponentAttr[9]=implode("",(array)$val[0]);}
		if($key=="action"){
			$textButton = "u";
			$strAction = str_replace(")","",implode("",(array)$val[0]));
			switch($strAction){
				case (preg_match('/^p\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new PostbackTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^m\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new MessageTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^u\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,$data);			
					break;
				case (preg_match('/^c\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/camera/");		
					break;
				case (preg_match('/^cs\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/single/");	
					break;
				case (preg_match('/^cm\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/multi/");				
					break;
				case (preg_match('/^l\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/location");				
					break;
				case (preg_match('/^d\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new DatetimePickerTemplateActionBuilder($textButton,$data,'datetime');
					break;																																			
				default:
					$actionVal = new PostbackTemplateActionBuilder($textButton,"");	

					break;					
			}					
			$textComponentAttr[10] = $actionVal;
		}
	}	
	return $textComponentAttr;
}
function boxComponentArr($xmlObj,$arrComponent = array()){
	$boxComponent = $xmlObj;
	$boxComponentAttr = array(null,$arrComponent,null,null,null,null);
	foreach($boxComponent->attributes() as $key=>$val){
		if($key=="layout"){$boxComponentAttr[0]=implode("",(array)$val[0]);}
		if($key=="flex"){$boxComponentAttr[2]=(int)implode("",(array)$val[0]);}
		if($key=="spacing"){$boxComponentAttr[3]=implode("",(array)$val[0]);}
		if($key=="margin"){$boxComponentAttr[4]=implode("",(array)$val[0]);}
		if($key=="action"){
			$textButton = "u";
			$strAction = str_replace(")","",implode("",(array)$val[0]));
			switch($strAction){
				case (preg_match('/^p\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new PostbackTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^m\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new MessageTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^u\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,$data);			
					break;
				case (preg_match('/^c\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/camera/");		
					break;
				case (preg_match('/^cs\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/single/");	
					break;
				case (preg_match('/^cm\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/multi/");				
					break;
				case (preg_match('/^l\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/location");				
					break;
				case (preg_match('/^d\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new DatetimePickerTemplateActionBuilder($textButton,$data,'datetime');
					break;																																			
				default:
					$actionVal = new PostbackTemplateActionBuilder($textButton,"");	
					break;					
			}		
			$boxComponentAttr[5] = $actionVal;
		}
	}	
	return $boxComponentAttr;
}
function buttonComponentArr($xmlObj){
	$buttonComponent = $xmlObj;
	$textButton = trim((string)$buttonComponent);
	$buttonComponentAttr = array(new PostbackTemplateActionBuilder($textButton,"nothing"),null,null,null,null,null,null);
	foreach($buttonComponent->attributes() as $key=>$val){
		if($key=="action"){
			$strAction = str_replace(")","",implode("",(array)$val[0]));
			switch($strAction){
				case (preg_match('/^p\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new PostbackTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^m\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new MessageTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^u\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,$data);			
					break;
				case (preg_match('/^c\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/camera/");		
					break;
				case (preg_match('/^cs\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/single/");	
					break;
				case (preg_match('/^cm\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/multi/");				
					break;
				case (preg_match('/^l\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/location");				
					break;
				case (preg_match('/^d\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new DatetimePickerTemplateActionBuilder($textButton,$data,'datetime');
					break;																																			
				default:
					$actionVal = new PostbackTemplateActionBuilder($textButton,"false");	
					break;					
			}
			$buttonComponentAttr[0] = $actionVal;
		}
		if($key=="flex"){$buttonComponentAttr[1]=(int)implode("",(array)$val[0]);}
		if($key=="margin"){$buttonComponentAttr[2]=implode("",(array)$val[0]);}
		if($key=="height"){$buttonComponentAttr[3]=implode("",(array)$val[0]);}
		if($key=="style"){$buttonComponentAttr[4]=implode("",(array)$val[0]);}
		if($key=="color"){$buttonComponentAttr[5]=implode("",(array)$val[0]);}
		if($key=="gravity"){$buttonComponentAttr[6]=implode("",(array)$val[0]);}
	}	
	return $buttonComponentAttr;
}
function iconComponentAttr($xmlObj){
	$iconComponent = $xmlObj;
	$iconComponentAttr = array(null,null,null,null);
	foreach($iconComponent->attributes() as $key=>$val){
		if($key=="url"){$iconComponentAttr[0]=implode("",(array)$val[0]);}
		if($key=="margin"){$iconComponentAttr[1]=implode("",(array)$val[0]);}
		if($key=="size"){$iconComponentAttr[2]=implode("",(array)$val[0]);}
		if($key=="aspectRatio"){$iconComponentAttr[3]=implode("",(array)$val[0]);}
	}	
	return $iconComponentAttr;		
}
function separatorComponentAttr($xmlObj){
	$separatorComponent = $xmlObj;
	$separatorComponentAttr = array();
	foreach($separatorComponent->attributes() as $key=>$val){
		if($key=="margin"){$separatorComponentAttr[0]=implode("",(array)$val[0]);}
		if($key=="color"){$separatorComponentAttr[1]=implode("",(array)$val[0]);}
	}	
	return $separatorComponentAttr;		
}
function fillerComponentAttr(){
		
}
function spacerComponentAttr($xmlObj){
	$spacerComponent = $xmlObj;
	$spacerComponentAttr = array("md");
	foreach($spacerComponent->attributes() as $key=>$val){
		if($key=="size"){$spacerComponentAttr[0]=implode("",(array)$val[0]);}
	}	
	return $spacerComponentAttr;	
}
function imageComponentArr($xmlObj){
	$imageComponent = $xmlObj;
	$imageComponentAttr = array(null,null,null,null,null,null,null,null,null);
	foreach($imageComponent->attributes() as $key=>$val){
		if($key=="url"){$imageComponentAttr[0]=implode("",(array)$val[0]);}
		if($key=="flex"){$imageComponentAttr[1]=(int)implode("",(array)$val[0]);}
		if($key=="margin"){$imageComponentAttr[2]=implode("",(array)$val[0]);}
		if($key=="align"){$imageComponentAttr[3]=implode("",(array)$val[0]);}
		if($key=="gravity"){$imageComponentAttr[4]=implode("",(array)$val[0]);}
		if($key=="size"){$imageComponentAttr[5]=implode("",(array)$val[0]);}
		if($key=="aspectRatio"){$imageComponentAttr[6]=implode("",(array)$val[0]);}
		if($key=="aspectMode"){$imageComponentAttr[7]=implode("",(array)$val[0]);}		
		if($key=="backgroundColor"){$imageComponentAttr[8]=implode("",(array)$val[0]);}
		if($key=="action"){
			$textButton = "u";
			$strAction = str_replace(")","",implode("",(array)$val[0]));
			switch($strAction){
				case (preg_match('/^p\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new PostbackTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^m\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new MessageTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^u\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,$data);			
					break;
				case (preg_match('/^c\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/camera/");		
					break;
				case (preg_match('/^cs\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/single/");	
					break;
				case (preg_match('/^cm\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/multi/");				
					break;
				case (preg_match('/^l\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/location");				
					break;
				case (preg_match('/^d\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new DatetimePickerTemplateActionBuilder($textButton,$data,'datetime');
					break;																																			
				default:
					$actionVal = new PostbackTemplateActionBuilder($textButton,"");	
					break;					
			}
			$imageComponentAttr[9] = $actionVal;			
		}
	}	
	return $imageComponentAttr;
}
function listElement($xmlObj,$arr_Element = array()){
	$arr_final = array();
	foreach ($xmlObj->children() as $childObj) {		
		$elName = $childObj->getName();	
		if($elName=="box"){
			$arr_final[] = new BoxComponentBuilder(...boxComponentArr($childObj,listElement($childObj,$arr_Element)));
		}else{			
			if($elName=="text"){
				$arr_final[] = new TextComponentBuilder(...textComponentArr($childObj)); // textComponentArr
			}elseif($elName=="button"){				
				$arr_final[] = new ButtonComponentBuilder(...buttonComponentArr($childObj)); // 
			}elseif($elName=="icon"){				
				$arr_final[] = new IconComponentBuilder(...iconComponentAttr($childObj)); // 						
			}elseif($elName=="image"){				
				$arr_final[] = new ImageComponentBuilder(...imageComponentArr($childObj)); // 		
			}elseif($elName=="filler"){				
				$arr_final[] = new FillerComponentBuilder(); // 				
			}elseif($elName=="spacer"){				
				$arr_final[] = new SpacerComponentBuilder(...spacerComponentAttr($childObj)); // 
			}elseif($elName=="separator"){				
				$arr_final[] = new SeparatorComponentBuilder(...separatorComponentAttr($childObj)); // 										
			}else{
				$arr_final[] = array();
			}
		}
	}	
	return $arr_final;
}
function createFlex($xmlstr){
	//$objXML = new SimpleXMLElement($xmlstr);
	$xmlIterator = new SimpleXMLIterator($xmlstr);
	$xmlIterator->rewind();
	$name_container = $xmlIterator->getName();
	$count_container = $xmlIterator->count();
	
	if($name_container!="carousel"){
		$is_singleBubble = true; 
	}
	$arr_bubble = array();
	$hasBlockStyle = false;
	$i = 0;
	for( $xmlIterator; $xmlIterator->valid(); $xmlIterator->next() ) {
		$bubble_direction[$i] = NULL;
		$bubble_direction[$i] = bubbleContainerAttr($xmlIterator->current());
	
		$block_header[$i] = NULL;
		$block_hero[$i] = NULL;
		$block_body[$i] = NULL;
		$block_footer[$i] = NULL;
		$block_header_style[$i] = NULL;
		$block_hero_style[$i] = NULL;
		$block_body_style[$i] = NULL;
		$block_footer_style[$i] = NULL;
		foreach ($xmlIterator->current()->children() as $blockChild) {
			if($blockChild->getName()=="header"){
				$block_header[$i]=$blockChild;
				$block_header_style[$i] = (!is_null(blockStyleAttr($blockChild)))?new BlockStyleBuilder(...blockStyleAttr($blockChild)):NULL;	
				$box_header[$i] = listElement($blockChild->children());
			}
			if($blockChild->getName()=="hero"){
				$block_hero[$i]=$blockChild;
				$block_hero_style[$i] = (!is_null(blockStyleAttr($blockChild)))?new BlockStyleBuilder(...blockStyleAttr($blockChild)):NULL;	
				$box_hero[$i] = listElement($blockChild->children());
			}
			if($blockChild->getName()=="body"){
				$block_body[$i]=$blockChild;	
				$block_body_style[$i] = (!is_null(blockStyleAttr($blockChild)))?new BlockStyleBuilder(...blockStyleAttr($blockChild)):NULL;	
				$box_body[$i] = listElement($blockChild->children());
			}
			if($blockChild->getName()=="footer"){
				$block_footer[$i]=$blockChild;	
				$block_footer_style[$i] = (!is_null(blockStyleAttr($blockChild)))?new BlockStyleBuilder(...blockStyleAttr($blockChild)):NULL;	
				$box_footer[$i] = listElement($blockChild->children());
			}
	
		}
		$style_bubble[$i]=NULL;
		if(!is_null($block_header_style[$i]) || !is_null($block_hero_style[$i]) || !is_null($block_body_style[$i]) || !is_null($block_footer_style[$i])){
				$style_bubble[$i] = new BubbleStylesBuilder(
					$block_header_style[$i],
					$block_hero_style[$i],
					$block_body_style[$i],
					$block_footer_style[$i]
				);
		}
		$i++;
	
	}
	for($i=0;$i<$count_container;$i++){
		$containDirection = (!is_null($bubble_direction[$i]))?$bubble_direction[$i][0]:"ltr";
		$containHeader = (!is_null($block_header[$i]))?new BoxComponentBuilder(...boxComponentArr($block_header[$i]->children(),$box_header[$i])):NULL;
		$containHero = (!is_null($block_hero[$i]))?new ImageComponentBuilder(...imageComponentArr($block_hero[$i]->children(),$box_hero[$i])):NULL; 
		$containBody = (!is_null($block_body[$i]))?new BoxComponentBuilder(...boxComponentArr($block_body[$i]->children(),$box_body[$i])):NULL;
		$containFooter = (!is_null($block_footer[$i]))?new BoxComponentBuilder(...boxComponentArr($block_footer[$i]->children(),$box_footer[$i])):NULL;
		$arr_bubble[] = new BubbleContainerBuilder(
			$containDirection,$containHeader,$containHero,$containBody,$containFooter,$style_bubble[$i]		
		);
	}		
	$arr_FlexMessage = NULL;
	if(!is_null($is_singleBubble)){
		$arr_FlexMessage = $arr_bubble[0];
	}else{
		$arr_FlexMessage = new CarouselContainerBuilder(
			$arr_bubble
		);
	}
	$textReplyMessage = $arr_FlexMessage;
	return $textReplyMessage;
}
 
ส่วนต่อมา กลับมาที่ไฟล์ bot_action.php ให้เราเรียกใช้ไฟล์ฟังก์ชั่น flex_gen.php เข้ามาใน
ไฟล์ bot_action.php ด้วยคำสั่ง
 
// ไฟล์ฟังก์ชั่นสำหรับแปลง xml เป็น flex 
require_once("flex_gen.php");
และไฟล์ bot_action.php ให้เราเพิ่ม เงื่อนไข การโต้ตอบกับ Bot อย่างง่ายเข้าไป เช่นสมมติเรากำหนด
ว่า เมื่อผู้ใช้พิมพ์ fl ให้ตอบกลับเป็นข้อความ Flex Message จะได้ไฟล์ bot_action.php เป็นดังนี้
 

ไฟล์ bot_action.php

<?php
///////////// ส่วนของการเรียกใช้งาน class ผ่าน namespace
use LINE\LINEBot;
use LINE\LINEBot\HTTPClient;
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
use LINE\LINEBot\Event;
use LINE\LINEBot\Event\BaseEvent;
use LINE\LINEBot\Event\MessageEvent;
use LINE\LINEBot\Event\AccountLinkEvent;
use LINE\LINEBot\Event\MemberJoinEvent; 
use LINE\LINEBot\MessageBuilder;
use LINE\LINEBot\MessageBuilder\TextMessageBuilder;
use LINE\LINEBot\MessageBuilder\StickerMessageBuilder;
use LINE\LINEBot\MessageBuilder\ImageMessageBuilder;
use LINE\LINEBot\MessageBuilder\LocationMessageBuilder;
use LINE\LINEBot\MessageBuilder\AudioMessageBuilder;
use LINE\LINEBot\MessageBuilder\VideoMessageBuilder;
use LINE\LINEBot\ImagemapActionBuilder;
use LINE\LINEBot\ImagemapActionBuilder\AreaBuilder;
use LINE\LINEBot\ImagemapActionBuilder\ImagemapMessageActionBuilder ;
use LINE\LINEBot\ImagemapActionBuilder\ImagemapUriActionBuilder;
use LINE\LINEBot\MessageBuilder\Imagemap\BaseSizeBuilder;
use LINE\LINEBot\MessageBuilder\ImagemapMessageBuilder;
use LINE\LINEBot\MessageBuilder\MultiMessageBuilder;
use LINE\LINEBot\TemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\DatetimePickerTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\MessageTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\PostbackTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\UriTemplateActionBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateMessageBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ButtonTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\CarouselTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\CarouselColumnTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ConfirmTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ImageCarouselTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ImageCarouselColumnTemplateBuilder;
use LINE\LINEBot\QuickReplyBuilder;
use LINE\LINEBot\QuickReplyBuilder\QuickReplyMessageBuilder;
use LINE\LINEBot\QuickReplyBuilder\ButtonBuilder\QuickReplyButtonBuilder;
use LINE\LINEBot\TemplateActionBuilder\CameraRollTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\CameraTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\LocationTemplateActionBuilder;
use LINE\LINEBot\RichMenuBuilder;
use LINE\LINEBot\RichMenuBuilder\RichMenuSizeBuilder;
use LINE\LINEBot\RichMenuBuilder\RichMenuAreaBuilder;
use LINE\LINEBot\RichMenuBuilder\RichMenuAreaBoundsBuilder;
use LINE\LINEBot\Constant\Flex\ComponentIconSize;
use LINE\LINEBot\Constant\Flex\ComponentImageSize;
use LINE\LINEBot\Constant\Flex\ComponentImageAspectRatio;
use LINE\LINEBot\Constant\Flex\ComponentImageAspectMode;
use LINE\LINEBot\Constant\Flex\ComponentFontSize;
use LINE\LINEBot\Constant\Flex\ComponentFontWeight;
use LINE\LINEBot\Constant\Flex\ComponentMargin;
use LINE\LINEBot\Constant\Flex\ComponentSpacing;
use LINE\LINEBot\Constant\Flex\ComponentButtonStyle;
use LINE\LINEBot\Constant\Flex\ComponentButtonHeight;
use LINE\LINEBot\Constant\Flex\ComponentSpaceSize;
use LINE\LINEBot\Constant\Flex\ComponentGravity;
use LINE\LINEBot\MessageBuilder\FlexMessageBuilder;
use LINE\LINEBot\MessageBuilder\Flex\BubbleStylesBuilder;
use LINE\LINEBot\MessageBuilder\Flex\BlockStyleBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ContainerBuilder\BubbleContainerBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ContainerBuilder\CarouselContainerBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\BoxComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\ButtonComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\IconComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\ImageComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\SpacerComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\FillerComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\SeparatorComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\TextComponentBuilder;

// ไฟล์ฟังก์ชั่นสำหรับแปลง xml เป็น flex 
require_once("flex_gen.php");

// ส่วนของการทำงาน
if(!is_null($events)){

	// ถ้า bot ถูก invite เพื่อเข้า Join Event ให้ bot ส่งข้อความใน GROUP ว่าเข้าร่วม GROUP แล้ว
	if(!is_null($eventJoin)){
		$textReplyMessage = "ขอเข้าร่วมด้วยน่ะ $sourceType ID:: ".$sourceId;
		$replyData = new TextMessageBuilder($textReplyMessage);                 
	}
	
	// ถ้า bot ออกจาก สนทนา จะไม่สามารถส่งข้อความกลับได้ เนื่องจากไม่มี replyToken
	if(!is_null($eventLeave)){

	}	
	
	// ถ้า bot ถูกเพื่มเป้นเพื่อน หรือถูกติดตาม หรือ ยกเลิกการ บล็อก
	if(!is_null($eventFollow)){
        $textReplyMessage = "ขอบคุณที่เป็นเพื่อน และติดตามเรา";        
        $replyData = new TextMessageBuilder($textReplyMessage);     			
	}
	
	// ถ้า bot ถูกบล็อก หรือเลิกติดตาม จะไม่สามารถส่งข้อความกลับได้ เนื่องจากไม่มี replyToken
	if(!is_null($eventUnfollow)){

	}		
	
	// ถ้ามีสมาชิกคนอื่น เข้ามาร่วมใน room หรือ group 
	// room คือ สมมติเราคุยกับ คนหนึ่งอยู่ แล้วเชิญคนอื่นๆ เข้ามาสนทนาด้วย จะกลายเป็นห้องใหม่
	// group คือ กลุ่มที่เราสร้างไว้ มีชื่อกลุ่ม แล้วเราเชิญคนอื่นเข้ามาในกลุ่ม เพิ่มร่วมสนทนาด้วย
	if(!is_null($eventMemberJoined)){
			$arr_joinedMember = $eventObj->getEventBody();
			$joinedMember = $arr_joinedMember['joined']['members'][0];
			if(!is_null($groupId) || !is_null($roomId)){
				if($eventObj->isGroupEvent()){
					foreach($joinedMember as $k_user=>$v_user){
						if($k_user=="userId"){
							$joined_userId = $v_user;
						}
					}						
					$response = $bot->getGroupMemberProfile($groupId, $joined_userId);
				}
				if($eventObj->isRoomEvent()){
					foreach($joinedMember as $k_user=>$v_user){
						if($k_user=="userId"){
							$joined_userId = $v_user;
						}
					}					
					$response = $bot->getRoomMemberProfile($roomId, $joined_userId);    
				}
			}else{
				$response = $bot->getProfile($userId);
			}
			if ($response->isSucceeded()) {
				$userData = $response->getJSONDecodedBody(); // return array     
				// $userData['userId']
				// $userData['displayName']
				// $userData['pictureUrl']
				// $userData['statusMessage']
				$textReplyMessage = 'สวัสดีครับ คุณ '.$userData['displayName'];     
			}else{
				$textReplyMessage = 'สวัสดีครับ ยินดีต้อนรับ';
			}
//        $textReplyMessage = "ยินดีต้อนรับกลับมาอีกครั้ง ".json_encode($joinedMember);
        $replyData = new TextMessageBuilder($textReplyMessage);     				
	}
	
	// ถ้ามีสมาชิกคนอื่น ออกจากก room หรือ group จะไม่สามารถส่งข้อความกลับได้ เนื่องจากไม่มี replyToken
	if(!is_null($eventMemberLeft)){
	
	}	

	// ถ้ามีกาาเชื่อมกับบัญชี LINE กับระบบสมาชิกของเว็บไซต์เรา
	if(!is_null($eventAccountLink)){
		// หลักๆ ส่วนนี้ใช้สำรหบัเพิ่มความภัยในการเชื่อมบัญตี LINE กับระบบสมาชิกของเว็บไซต์เรา 
        $textReplyMessage = "AccountLink ทำงาน ".$replyToken." Nonce: ".$eventObj->getNonce();
        $replyData = new TextMessageBuilder($textReplyMessage);   	  					
	}
			
    // ถ้าเป็น Postback Event
    if(!is_null($eventPostback)){
        $dataPostback = NULL;
        $paramPostback = NULL;
        // แปลงข้อมูลจาก Postback Data เป็น array
        parse_str($eventObj->getPostbackData(),$dataPostback);
        // ดึงค่า params กรณีมีค่า params
        $paramPostback = $eventObj->getPostbackParams();
		
		$moreResult = "";
		if(isset($dataPostback['action']) && $dataPostback['action']=="more_richmenu"){
			$respRichMenu = $bot->linkRichMenu($userId,$dataPostback['richmenuid']);
			$moreResult = $respRichMenu->getRawBody();
			$result = json_decode($respRichMenu->getRawBody(),TRUE);	
		}		
		if(isset($dataPostback['action']) && $dataPostback['action']=="back_richmenu"){
			$respRichMenu = $bot->unlinkRichMenu($userId);
			$moreResult = $respRichMenu->getRawBody();
			$result = json_decode($respRichMenu->getRawBody(),TRUE);	
		}				
		
		if(isset($dataPostback['action']) && $dataPostback['action']=="delete_richmenu"){
			$respRichMenu = $bot->deleteRichMenu($dataPostback['richMenuId']);
			$moreResult = $respRichMenu->getRawBody();
			$result = json_decode($respRichMenu->getRawBody(),TRUE);	
		}
		if(isset($dataPostback['action']) && $dataPostback['action']=="get_richmenu"){
			$respRichMenu = $bot->getRichMenu($dataPostback['richMenuId']);
			$moreResult = $respRichMenu->getRawBody();
			$result = json_decode($respRichMenu->getRawBody(),TRUE);	
		}
		if(isset($dataPostback['action']) && $dataPostback['action']=="s_default_richmenu"){
			$respRichMenu = $httpClient->post("https://api.line.me/v2/bot/user/all/richmenu/".$dataPostback['richMenuId'],array());
			$moreResult = $respRichMenu->getRawBody();
			$result = json_decode($respRichMenu->getRawBody(),TRUE);	
		}		
		if(isset($dataPostback['action']) && $dataPostback['action']=="c_default_richmenu"){
			$respRichMenu = $httpClient->delete("https://api.line.me/v2/bot/user/all/richmenu");
			$moreResult = $respRichMenu->getRawBody();
			$result = json_decode($respRichMenu->getRawBody(),TRUE);	
		}			
		if(isset($dataPostback['action']) && $dataPostback['action']=="g_default_richmenu"){
			$respRichMenu = $httpClient->get("https://api.line.me/v2/bot/user/all/richmenu");
			$moreResult = $respRichMenu->getRawBody();
			$result = json_decode($respRichMenu->getRawBody(),TRUE);	
		}			
		if(isset($dataPostback['action']) && $dataPostback['action']=="upload_richmenu"){
			$richMenuImg = str_replace('Rich Menu ','',$dataPostback['richMenuName']);
			if(!file_exists("rich-menu/rich-menu-0".$richMenuImg.".png")){
				$richMenuImg = substr(str_replace('Rich Menu ','',$dataPostback['richMenuName']),0,1);
			}
			$respRichMenu = $bot->uploadRichMenuImage($dataPostback['richMenuId'],"rich-menu/rich-menu-0".$richMenuImg.".png","image/png");
			$moreResult = $respRichMenu->getRawBody();
			$result = json_decode($respRichMenu->getRawBody(),TRUE);	
		}					
		
        // ทดสอบแสดงข้อความที่เกิดจาก Postaback Event
        $textReplyMessage = "ข้อความจาก Postback Event Data : DataPostback = ";        
        $textReplyMessage.= json_encode($dataPostback);
        $textReplyMessage.= " ParamPostback = ".json_encode($paramPostback);
		$textReplyMessage.= " RsponseMore = ".$moreResult;
        $replyData = new TextMessageBuilder($textReplyMessage);     
    }
    // ถ้าเป้น Message Event 
    if(!is_null($eventMessage)){
		
		// สร้างตัวแปรเก็ยค่าประเภทของ Message จากทั้งหมด 7 ประเภท
		$typeMessage = $eventObj->getMessageType();  
		//  text | image | sticker | location | audio | video | file  
		// เก็บค่า id ของข้อความ
		$idMessage = $eventObj->getMessageId();  		
		// ถ้าเป็นข้อความ
		if($typeMessage=='text'){
			$userMessage = $eventObj->getText(); // เก็บค่าข้อความที่ผู้ใช้พิมพ์
		}
		// ถ้าเป็น image
		if($typeMessage=='image'){

		}				
		// ถ้าเป็น audio

		if($typeMessage=='audio'){

		}		
		// ถ้าเป็น video
		if($typeMessage=='video'){

		}	
		// ถ้าเป็น file
		if($typeMessage=='file'){
			$FileName = $eventObj->getFileName();
			$FileSize = $eventObj->getFileSize();
		}				
		// ถ้าเป็น image หรือ audio หรือ video หรือ file และต้องการบันทึกไฟล์
		if(preg_match('/image|audio|video|file/',$typeMessage)){			
			$responseMedia = $bot->getMessageContent($idMessage);
			if ($responseMedia->isSucceeded()) {
				// คำสั่ง getRawBody() ในกรณีนี้ จะได้ข้อมูลส่งกลับมาเป็น binary 
				// เราสามารถเอาข้อมูลไปบันทึกเป็นไฟล์ได้
				$dataBinary = $responseMedia->getRawBody(); // return binary
				// ดึงข้อมูลประเภทของไฟล์ จาก header
				$fileType = $responseMedia->getHeader('Content-Type');    
				switch ($fileType){
					case (preg_match('/^application/',$fileType) ? true : false):
//						$fileNameSave = $FileName; // ถ้าต้องการบันทึกเป็นชื่อไฟล์เดิม
						$arr_ext = explode(".",$FileName);
						$ext = array_pop($arr_ext);
						$fileNameSave = time().".".$ext;       						
						break;					
					case (preg_match('/^image/',$fileType) ? true : false):
						list($typeFile,$ext) = explode("/",$fileType);
						$ext = ($ext=='jpeg' || $ext=='jpg')?"jpg":$ext;
						$fileNameSave = time().".".$ext;
						break;
					case (preg_match('/^audio/',$fileType) ? true : false):
						list($typeFile,$ext) = explode("/",$fileType);
						$fileNameSave = time().".".$ext;                        
						break;
					case (preg_match('/^video/',$fileType) ? true : false):
						list($typeFile,$ext) = explode("/",$fileType);
						$fileNameSave = time().".".$ext;                                
						break;                                                      
				}
				$botDataFolder = 'botdata/'; // โฟลเดอร์หลักที่จะบันทึกไฟล์
				$botDataUserFolder = $botDataFolder.$userId; // มีโฟลเดอร์ด้านในเป็น userId อีกขั้น
				if(!file_exists($botDataUserFolder)) { // ตรวจสอบถ้ายังไม่มีให้สร้างโฟลเดอร์ userId
					mkdir($botDataUserFolder, 0777, true);
				}   
				// กำหนด path ของไฟล์ที่จะบันทึก
				$fileFullSavePath = $botDataUserFolder.'/'.$fileNameSave;
//				file_put_contents($fileFullSavePath,$dataBinary); // เอา comment ออก ถ้าต้องการทำการบันทึกไฟล์
				$textReplyMessage = "บันทึกไฟล์เรียบร้อยแล้ว $fileNameSave";
				$replyData = new TextMessageBuilder($textReplyMessage);
//				$failMessage = json_encode($fileType);				
//				$failMessage = json_encode($responseMedia->getHeaders());
				$replyData = new TextMessageBuilder($failMessage);  					
			}else{
				$failMessage = json_encode($idMessage.' '.$responseMedia->getHTTPStatus() . ' ' . $responseMedia->getRawBody());
				$replyData = new TextMessageBuilder($failMessage);  		
			}
		}
		// ถ้าเป็น sticker
		if($typeMessage=='sticker'){
			$packageId = $eventObj->getPackageId();
			$stickerId = $eventObj->getStickerId();
		}
		// ถ้าเป็น location
		if($typeMessage=='location'){
			$locationTitle = $eventObj->getTitle();
			$locationAddress = $eventObj->getAddress();
			$locationLatitude = $eventObj->getLatitude();
			$locationLongitude = $eventObj->getLongitude();
		}       
		
		
        switch ($typeMessage){ // กำหนดเงื่อนไขการทำงานจาก ประเภทของ message
            case 'text':  // ถ้าเป็นข้อความ
                $userMessage = strtolower($userMessage); // แปลงเป็นตัวเล็ก สำหรับทดสอบ
                switch ($userMessage) {
						case "fl": // ส่วนทดสอบโต้ตอบข้อควมม flex
							$textReplyMessage = new BubbleContainerBuilder(
								"ltr",NULL,NULL,
								new BoxComponentBuilder(
									"vertical",
									array(
										new TextComponentBuilder("hello"),
										new TextComponentBuilder("world")
									)
								)
							);
							$replyData = new FlexMessageBuilder("This is a Flex Message",$textReplyMessage);		   													  	
							break;
						case (preg_match('/^cr-/',$userMessage) ? true : false):
							$paramRichMenu = explode(">",$userMessage);
							if(!isset($paramRichMenu) || !is_array($paramRichMenu) || count($paramRichMenu)<3){
								exit;
							}
							$patternSet = $paramRichMenu[0];
							$numberID = $paramRichMenu[1];
							$actionSet = $paramRichMenu[2];
							$actionArr_prepare = array();
							if(isset($actionSet)){
								$actionArr_prepare = explode(")",$actionSet);
								array_pop($actionArr_prepare);
							}
							$imgTypePattern = str_replace("cr-","",$patternSet);
							$areaBound_arr = array(
								"a"=>array(0,0,833,843),
								"b"=>array(833,0,833,843),

								"c"=>array(1666,0,834,843),
								"d"=>array(0,843,833,843),
								"e"=>array(833,843,833,843),
								"f"=>array(1666,843,834,843),
								"g"=>array(0,0,1250,843),
								"h"=>array(1250,0,1250,843),
								"i"=>array(0,843,1250,843),
								"j"=>array(1250,843,1250,843),
								"k"=>array(0,0,2500,843),
								"l"=>array(0,0,1666,1686),
								"m"=>array(0,843,2500,843),
								"n"=>array(0,0,1250,1686),
								"o"=>array(1250,0,1250,1686),
								"p"=>array(0,0,2500,1686)
							);
							$imgTypePatternArea_arr = array(
								"1"=>array("a","b","c","d","e","f"),
								"2"=>array("g","h","i","j"),
								"3"=>array("k","d","e","f"),
								"4"=>array("l","c","f"),
								"5"=>array("k","m"),
								"6"=>array("n","o"),
								"7"=>array("p")
							);
							
							function makeFRM($imgType){
								global $areaBound_arr,$imgTypePatternArea_arr,$actionSet,$actionArr_prepare;
								$dataArr = array();
								$Area_arr = $imgTypePatternArea_arr[$imgType];
								for($i=1;$i<=count($imgTypePatternArea_arr[$imgType]);$i++){									
									if(preg_match('/^p\(/',$actionArr_prepare[$i-1])){
										list($ac,$data) = explode("(",$actionArr_prepare[$i-1]);
										$actionVal = new PostbackTemplateActionBuilder('p',$data);
									}elseif(preg_match('/^m\(/',$actionArr_prepare[$i-1])){
										list($ac,$data) = explode("(",$actionArr_prepare[$i-1]);
										$actionVal = new MessageTemplateActionBuilder('m',$data);									
									}elseif(preg_match('/^u\(/',$actionArr_prepare[$i-1])){
										list($ac,$data) = explode("(",$actionArr_prepare[$i-1]);
										$actionVal = new UriTemplateActionBuilder('u',$data);	
									}elseif(preg_match('/^c\(/',$actionArr_prepare[$i-1])){
										list($ac,$data) = explode("(",$actionArr_prepare[$i-1]);
										$actionVal = new UriTemplateActionBuilder('u',"line://nv/camera/");		
									}elseif(preg_match('/^cs\(/',$actionArr_prepare[$i-1])){
										list($ac,$data) = explode("(",$actionArr_prepare[$i-1]);
										$actionVal = new UriTemplateActionBuilder('u',"line://nv/cameraRoll/single/");	
									}elseif(preg_match('/^cm\(/',$actionArr_prepare[$i-1])){
										list($ac,$data) = explode("(",$actionArr_prepare[$i-1]);
										$actionVal = new UriTemplateActionBuilder('u',"line://nv/cameraRoll/multi/");														
									}elseif(preg_match('/^l\(/',$actionArr_prepare[$i-1])){
										list($ac,$data) = explode("(",$actionArr_prepare[$i-1]);
										$actionVal = new UriTemplateActionBuilder('u',"line://nv/location");																											
									}elseif(preg_match('/^d\(/',$actionArr_prepare[$i-1])){
										list($ac,$data) = explode("(",$actionArr_prepare[$i-1]);
										$actionVal = new DatetimePickerTemplateActionBuilder('d',$data,'datetime');
									}elseif(preg_match('/^n\(/',$actionArr_prepare[$i-1])){
										$actionVal = NULL;
										continue;
									}else{
										$actionVal = NULL;
										continue;
									}
									$patternLetter = $Area_arr[$i-1];
									array_push($dataArr,
											new RichMenuAreaBuilder(
												new RichMenuAreaBoundsBuilder(...$areaBound_arr[$patternLetter]),$actionVal
											)					
									);
								}
								return $dataArr;						
							}
//							$arrayRichMenu = makeFRM();
							// $sizeBuilder, $selected, $name, $chatBarText, $areaBuilders // 1686, 843.  // 2500
							// ($x, $y, $width, $height)
							$_idRichMenu = $imgTypePattern."-".$numberID;
							$respRichMenu = $bot->createRichMenu(
								new RichMenuBuilder(
									new RichMenuSizeBuilder(1686,2500),true,"Rich Menu $_idRichMenu",
									"เมนู",
									makeFRM($imgTypePattern)
								)
							);
							// ทำอื่นๆ 
							$textReplyMessage = " การสร้าง Rich Menu ".$respRichMenu->getRawBody()." Res = ".json_encode($dataArr);
							$replyData = new TextMessageBuilder($textReplyMessage);         							
							break;								
						case "gr-":
							$respRichMenu = $httpClient->get("https://api.line.me/v2/bot/user/all/richmenu");
							$result = json_decode($respRichMenu->getRawBody(),TRUE);		
							$defaultRichMenu = (isset($result['richMenuId']))?$result['richMenuId']:NULL;
	
							$respRichMenu = $bot->getRichMenuList();
							$result = json_decode($respRichMenu->getRawBody(),TRUE);									
							// สร้างตัวแปร สำหรับเก็บ rich menu แต่ละรายการไว้ในแต่ละคอลัมน์
							$columnTemplate = array();
							foreach($result['richmenus'] as $itemRichMenu){
								$_txtShow = ($itemRichMenu['richMenuId']==$defaultRichMenu)?"ยกเลิก":"กำหนดเป็น";
								$_action = ($itemRichMenu['richMenuId']==$defaultRichMenu)?"c_default_richmenu":"s_default_richmenu";
								$imgRichLayout = substr(str_replace('Rich Menu ','',$itemRichMenu['name']),0,1);
								array_push($columnTemplate,	
									new CarouselColumnTemplateBuilder(
											$itemRichMenu['name'], // ชื่อ rich menu
											'เลือกการจัดการ',
											'https://www.example.com/linebot/rich-menu/rich-menu-pattern-0'.$imgRichLayout.'.png', // ไม่แสดงรูป มีมี url รูป
											array(										
												new PostbackTemplateActionBuilder(
													$_txtShow.' Default', // ข้อความแสดงในปุ่ม
													http_build_query(array(
														'action'=>$_action,			
														'richMenuName'=>$itemRichMenu['name'],					 
														'richMenuId'=>$itemRichMenu['richMenuId']
													)), // ข้อมูลที่จะส่งไปใน webhook ผ่าน postback event
													'กำหนด Default Rich Menu'  // ข้อความที่จะแสดงฝั่งผู้ใช้ เมื่อคลิกเลือก
												),      	
												new PostbackTemplateActionBuilder(
													'แสดงที่ Default', // ข้อความแสดงในปุ่ม
													http_build_query(array(
														'action'=>'g_default_richmenu',		
														'richMenuName'=>$itemRichMenu['name'],			 
														'richMenuId'=>$itemRichMenu['richMenuId']
													)), // ข้อมูลที่จะส่งไปใน webhook ผ่าน postback event
													'แสดง Default Rich Menu'  // ข้อความที่จะแสดงฝั่งผู้ใช้ เมื่อคลิกเลือก
												),     																						
												new PostbackTemplateActionBuilder(
													'อัพโหลดรูป Rich Menu นี้', // ข้อความแสดงในปุ่ม
													http_build_query(array(
														'action'=>'upload_richmenu',			
														'richMenuName'=>$itemRichMenu['name'],					 
														'richMenuId'=>$itemRichMenu['richMenuId']
													)), // ข้อมูลที่จะส่งไปใน webhook ผ่าน postback event
													'อัพโหลดรูป Rich Menu'  // ข้อความที่จะแสดงฝั่งผู้ใช้ เมื่อคลิกเลือก
												) 						
											)		
									)	// end CarouselColumnTemplateBuilder			
								); // end array push function
							}	// end foreach						
							
							// ใช้ Carousel Template วนลูปแสดงรายการ rich menu ที่ได้สร้างไว้
							$replyData = new TemplateMessageBuilder('Carousel',
								new CarouselTemplateBuilder(
									$columnTemplate
								)
							);											
							break;  	
						case "gr2-":
							$respRichMenu = $bot->getRichMenuList();
							$result = json_decode($respRichMenu->getRawBody(),TRUE);	
								
							// สร้างตัวแปร สำหรับเก็บ rich menu แต่ละรายการไว้ในแต่ละคอลัมน์
							$columnTemplate = array();
							foreach($result['richmenus'] as $itemRichMenu){
								$imgRichLayout = substr(str_replace('Rich Menu ','',$itemRichMenu['name']),0,1);								
								array_push($columnTemplate,	
									new CarouselColumnTemplateBuilder(
											$itemRichMenu['name'], // ชื่อ rich menu
											'เลือกการจัดการ',
											'https://www.example.com/linebot/rich-menu/rich-menu-pattern-0'.$imgRichLayout.'.png', // ไม่แสดงรูป มีมี url รูป
											array(
												new PostbackTemplateActionBuilder(
													'รายละเอียด Rich Menu', // ข้อความแสดงในปุ่ม
													http_build_query(array(
														'action'=>'get_richmenu',		
														'richMenuName'=>$itemRichMenu['name'],						 
														'richMenuId'=>$itemRichMenu['richMenuId']
													)), // ข้อมูลที่จะส่งไปใน webhook ผ่าน postback event
													'ข้อมูล Rich Menu'  // ข้อความที่จะแสดงฝั่งผู้ใช้ เมื่อคลิกเลือก
												),      																														
												new PostbackTemplateActionBuilder(
													'ลบ Rich Menu นี้', // ข้อความแสดงในปุ่ม
													http_build_query(array(
														'action'=>'delete_richmenu',			
														'richMenuName'=>$itemRichMenu['name'],					 
														'richMenuId'=>$itemRichMenu['richMenuId']
													)), // ข้อมูลที่จะส่งไปใน webhook ผ่าน postback event
													'ลบ Rich Menu'  // ข้อความที่จะแสดงฝั่งผู้ใช้ เมื่อคลิกเลือก
												),      		
												new PostbackTemplateActionBuilder(
													'อัพโหลดรูป Rich Menu นี้', // ข้อความแสดงในปุ่ม
													http_build_query(array(
														'action'=>'upload_richmenu',			
														'richMenuName'=>$itemRichMenu['name'],					 
														'richMenuId'=>$itemRichMenu['richMenuId']
													)), // ข้อมูลที่จะส่งไปใน webhook ผ่าน postback event
													'อัพโหลดรูป Rich Menu'  // ข้อความที่จะแสดงฝั่งผู้ใช้ เมื่อคลิกเลือก
												) 						
											)		
									)	// end CarouselColumnTemplateBuilder			
								); // end array push function
							}	// end foreach						
							
							// ใช้ Carousel Template วนลูปแสดงรายการ rich menu ที่ได้สร้างไว้
							$replyData = new TemplateMessageBuilder('Carousel',
								new CarouselTemplateBuilder(
									$columnTemplate
								)
							);											
							break;  															
						case "ot":
							// ทำอื่นๆ 
							break;
						case "l": // เงื่อนไขทดสอบถ้ามีใครพิมพ์ L ใน GROUP / ROOM แล้วให้ bot ออกจาก GROUP / ROOM
								$sourceId = $eventObj->getEventSourceId();
								if($eventObj->isGroupEvent()){
									$bot->leaveGroup($sourceId);
								}
								if($eventObj->isRoomEvent()){
									$bot->leaveRoom($sourceId);  
								}                                                                                         
							break;							
						case "qr":
							$postback = new PostbackTemplateActionBuilder(
                                'Postback', // ข้อความแสดงในปุ่ม
                                http_build_query(array(
                                    'action'=>'buy',
                                    'item'=>100
                                )), // ข้อมูลที่จะส่งไปใน webhook ผ่าน postback event
		                         'Buy'  // ข้อความที่จะแสดงฝั่งผู้ใช้ เมื่อคลิกเลือก
                            );
							$txtMsg = new MessageTemplateActionBuilder(

                                'ข้อความภาษาไทย',// ข้อความแสดงในปุ่ม
                                'thai' // ข้อความที่จะแสดงฝั่งผู้ใช้ เมื่อคลิกเลือก
                            );
							$datetimePicker = new DatetimePickerTemplateActionBuilder(
								'Datetime Picker', // ข้อความแสดงในปุ่ม
								http_build_query(array(
									'action'=>'reservation',
									'person'=>5
								)), // ข้อมูลที่จะส่งไปใน webhook ผ่าน postback event
								'datetime', // date | time | datetime รูปแบบข้อมูลที่จะส่ง ในที่นี้ใช้ datatime
								substr_replace(date("Y-m-d H:i"),'T',10,1), // วันที่ เวลา ค่าเริ่มต้นที่ถูกเลือก
								substr_replace(date("Y-m-d H:i",strtotime("+5 day")),'T',10,1), //วันที่ เวลา มากสุดที่เลือกได้
								substr_replace(date("Y-m-d H:i"),'T',10,1) //วันที่ เวลา น้อยสุดที่เลือกได้
							);
							
							$quickReply = new QuickReplyMessageBuilder(
								array(
									new QuickReplyButtonBuilder(new LocationTemplateActionBuilder('เลือกตำแหน่ง')),
									new QuickReplyButtonBuilder(new CameraTemplateActionBuilder('ถ่ายรูป')),
									new QuickReplyButtonBuilder(new CameraRollTemplateActionBuilder('เลือกรูปภาพ')),
									new QuickReplyButtonBuilder($postback),
									new QuickReplyButtonBuilder($datetimePicker),
									new QuickReplyButtonBuilder(
										$txtMsg,
										"https://www.ninenik.com/images/ninenik_page_logo.png"
									),
								)
							);
							$textReplyMessage = "ส่งพร้อม quick reply ";
							$replyData = new TextMessageBuilder($textReplyMessage,$quickReply);     						
							break;   												                       
                    default:
                        $textReplyMessage = " คุณไม่ได้พิมพ์ ค่า ตามที่กำหนด";
                        $replyData = new TextMessageBuilder($textReplyMessage);         
                        break;                                      
                }
                break;                                                  
            default:
				if(!is_null($replyData)){
					
				}else{
					// กรณีทดสอบเงื่อนไขอื่นๆ ผู้ใช้ไม่ได้ส่งเป็นข้อความ
					$textReplyMessage = 'สวัสดีครับ คุณ '.$typeMessage;         
					$replyData = new TextMessageBuilder($textReplyMessage);         
				}
                break;  
        }
    }
}
?>
 
ทดสอบ ถ้าไม่มีอะไรผิดพลาด ก็จะได้ผลลัพธ์ดังนี้
 
 


 


 
 
ส่วนของการสร้าง Flex Message ข้างต้น เราทำการสร้าง Bubble ที่มี
Text Component ข้อความว่า hello world
 
$textReplyMessage = new BubbleContainerBuilder(
	"ltr",NULL,NULL,
	new BoxComponentBuilder(
		"vertical",
		array(
			new TextComponentBuilder("hello"),
			new TextComponentBuilder("world")
		)
	)
);
$replyData = new FlexMessageBuilder("This is a Flex Message",$textReplyMessage);
 
สำหรับ คำว่า "This is a Flex Message" จะเป็นข้อความที่แสดงหรืออธิบายว่า Flex Message
ที่เราส่งไปนั้น เป็นเนื้อหาเกี่ยวกับอะไร ตามตัวอย่างรูปด้านบน หน้ารวมห้องสนทนา เราจะเห็นข้อความ
นี้แสดง ข้อความส่วนนี้ สามารถเปลี่ยนอะไรก็ได้ ที่เราต้องการสื่อถึงรายละเอียดของ Flex Message
 
 

สร้าง Flex Message จากรูปแบบ XML

    ต่อไปเรามาดูว่า ถ้าเราจะส่งข้อความ hello world ในรูปแบบตามตัวอย่างข้างต้น แต่เขียนในรูปแบบ
XML จะสามารถทำได้แบบไหน
 
        // Flex Message รูปแบบ XML
        $xmlstr = <<<XML
        <noncarousel>
            <bubble direction="ltr">
                <body>
                    <box layout="vertical">
                        <text>hello</text>
                        <text>world</text>
                    </box>
                </body>	
            </bubble>
        </noncarousel>	
XML;
							
        $textReplyMessage = createFlex($xmlstr);
        $replyData = new FlexMessageBuilder("Flex from XML",$textReplyMessage);

 
ในรูปแบบ XML เราสร้าง XML string แล้วไว้ในตัวแปร $xmlstr โดยใช้รูปแบบ Heredoc syntax
เป็นการกำหนดค่าตัวแปรรูปแบบหนึ่ง 
 
    $xmlstr = <<<XML
<!--รูปแบบ XML ที่ต้องการ-->
XML;
สังเกตุว่า ตัวปิดของการกำหนดแบบ Herodoc (XML;) จะต้องชิดขอบด้านซ้าย โดยไม่มีช่องว่ามากั้นเสมอ
ไม่เช่นจะไม่สามารถกำหนดค่าได้
    หลักการทำงาน เราส่งรูปแบบ XML เข้าไปในฟังก์ชั่น createFlex($xmlstr) เพื่อแปลงค่า
เป็น Flex Message ก่อนนำไปใช้งาน
 
 

Flex Message XML Elements

    องค์ประกอบของ Flex Message ในรูปแบบ XML ประกอบไปด้วย Elements ต่างๆ 
แบ่งออกได้เป็นแต่ละส่วนดังนี้
 

    ส่วนที่ใช้ในการกำหนด Container

  •     <noncarousel> รูปแบบการใช้งาน <noncarousel>...</noncarousel>
  •     <carousel> รูปแบบการใช้งาน <carousel>...</carousel>
  •     <bubble>  รูปแบบการใช้งาน <bubble>....</bubble>
 

    ส่วนที่ใช้ในการกำหนด Block

  •     <header> รูปแบบการใช้งาน <header>...</header>
  •     <hero> รูปแบบการใช้งาน <hero>...</hero>
  •     <body> รูปแบบการใช้งาน <body>...</body>
  •     <footer> รูปแบบการใช้งาน <footer>...</footer>
 

    ส่วนที่ใช้ในการกำหนด Component

  •     <box> รูปแบบการใช้งาน <box>...</box>
  •     <button> รูปแบบการใช้งาน <button>...</button>
  •     <filler> รูปแบบการใช้งาน <filler />
  •     <icon> รูปแบบการใช้งาน <icon />
  •     <image> รูปแบบการใช้งาน <image />
  •     <separator> รูปแบบการใช้งาน <separator />
  •     <spacer> รูปแบบการใช้งาน <spacer />
  •     <text> รูปแบบการใช้งาน <text>...</text>
 
จะใช้เป็นตัวพิมพ์เล็กทั้งหมด จะเห็นว่าจะเหมือนกันรูปแบบที่กำหนดใน JSON แต่มีเพิ่ม
มาคือ <noncarousel> สำหรับ ส่งข้อมูล Flex ที่เป็น Single Bubble

 

การกำหนด Property ให้กับ Flex Message Element

    ใน Element แต่ละตัว ก็จะมี property ตามรูปแบบ ที่ Line กำหนด โดยในการ XML
เราจะกำหนด property ไว้ในส่วนของ Attribute และบางตัวกำหนดไว้ใน Text Node
ของ Element นั้น
    สามารถดู property ต่าง ๆ เพิ่มเติมได้ที่
 
    Property จะเป็นแบบ case-sensitive คือยึดตามรูปแบบของ Line เช่น สีพื้นหลัง
ใช้เป็น "backgroundColor" จะไม่ใช้เป็น "backgroundcolor"
 
    ตัวอย่าง
<noncarousel>
	<bubble direction="ltr">
		<body backgroundColor="#CCCCCC">
			<box layout="vertical">
				<text>hello</text>
				<text>world</text>
			</box>
		</body>	
	</bubble>
</noncarousel>	
    Element บางตัวใช้ textNode เป็นค่า text property เช่น <text> และ <button>
    ตัวอย่าง
 
<text>hello world</text>
<button action="u(http://niik.in)">Go</button>
    Element บางตัว เช่น <filler> ไม่มี property ก็สามารถใช้เป็น <filler /> ได้เลย

 
 

Elements Property

    ต่อไปเราจะมาดู property ต่างๆ ไล่ไปแต่ละ element โดย property ใดที่จำเป็นต้องกำหนดเสมอ
เราจะใช้ * กำหนดไว้ด้านหน้า
 

Container Elements

    Carousel Container

<carousel>
	<bubble direction="ltr">

    </bubble>
	<bubble direction="ltr">

    </bubble>    
</carousel>
 

    Bubble Container

<noncarousel>
	<bubble direction="ltr">
    
    </bubble>
</noncarousel>
สำหรับ property ของ Container จะกำหนดใน Bubble Element มี property เดียวคือ
*direction 
    กำหนดค่า ltr หรือ rtl เป็นการกำหนดลักษณะการอ่านของข้อความ จากซ้ายไปขวาหรือขวาไปซ้าย 
ในไทยก็จะเป็นการอ่านจากซ้ายไปขวา เราก็ใช้ ltr เสมอแทนได้
 
 
 

Block Elements

<noncarousel>
	<bubble direction="ltr">
    	<header backgroundColor="#CCCCCC">
        
        </header>
        <hero>
        
		<hero>
        <body separator="true" separatorColor="#FF0000">
        
        </body>
    	<footer>
        
        </footer>
    </bubble>
</noncarousel>
สำหรับ Header, Hero, Body และ Footer Block จะมีด้วยกัน 3 property ได้แก่
 
backgroundColor 
    ค่าสีพื้นหลังใช้เป็นข้อความเลขฐาน 16 เช่น #CCCCCC
separator 
    กำหนดมีเส้นแบ่งด้านบนของ Block หรือไม่ ใช้ค่า "true" หรือ "false" ไม่มีผลกับ Block ตัวแรก
separatorColor 
    ค่าสีเส้นแบ่งเลขฐาน 16 เช่น #CCCCCC
 
 
 

Component Elements

    Box Element

<box layout="vertical" flex="2">

</box>
*layout 
    กำหนดค่าการจัดเรียงแนวนอน "horizontal" "vertical" หรือ "baseline" 
    เพิ่มเติม http://niik.in/899
flex
    กำหนดเป็นตัวเลข เป็นค่ากำหนดถึงสัดส่วนความกว้างหรือสูงของ element นั้นเทียบกับ parent box 
    เพิ่มเติม http://niik.in/899
spacing
    กำหนดระยะห่างระหว่าง element ด้านใน ค่า none, xs, sm, md, lg, xl, หรือ xxl 
    เพิ่มเติม http://niik.in/899
margin
    กำหนดระยะห่างของ element ใกล้เคียง none, xs, sm, md, lg, xl, หรือ xxl
    เพิ่มเติม http://niik.in/899
action
    กำหนดการทำงานให้กับ element นั้น ๆ เมื่อแตะหรือกดที่ element
    รูปแบบการใช้งาน จะอธิบายในหัวข้อถัดไป ตัวอย่าง action="u(http://niik.in)" หมายถึง
    ลิ้งค์ไปยัง url ที่กำหนด
 
 

    Button Element

<button style="primary" action="u(http://niik.in)">
More
</button>
 *action
    กำหนดการทำงานให้กับ element นั้น ๆ เมื่อแตะหรือกดที่ element
    รูปแบบการใช้งาน จะอธิบายในหัวข้อถัดไป ตัวอย่าง action="u(http://niik.in)" หมายถึง
    ลิ้งค์ไปยัง url ที่กำหนด
flex
    กำหนดเป็นตัวเลข เป็นค่ากำหนดถึงสัดส่วนความกว้างหรือสูงของ element นั้นเทียบกับ parent box 
    เพิ่มเติม http://niik.in/899
margin
    กำหนดระยะห่างของ element ใกล้เคียง none, xs, sm, md, lg, xl, หรือ xxl
    เพิ่มเติม http://niik.in/899
height
    กำหนดความสูงให้กับ button ค่า sm หรือ md ค่าเริ่มต้นคือ md
style
    กำหนดรูปแบบของ button ค่า
  •     link สำหรับรูปแบบลิ้งค์คล้ายใน HTML
  •     primary สำหรับปุ่มพื้นหลังสีเข้ม
  •     secondary สำหรับปุ่มพื้นหลังสีอ่อน
    ค่าเริ่มต้นเป็น link *(คำว่า ค่าเริ่มต้น หมายถึง ถ้าไม่ได้กำหนด จะใช้ค่าเริ่มต้น แทน)
color
    ค่าสีใช้เป็นข้อความเลขฐาน 16 เช่น #CCCCCC 
    จะเป็นค่าสีของข้อความถ้ากำหนด style เป็น link และจะเป็นสีพื้นหลัง
    ถ้ากำหนด style เป็น primary หรือ secondary
gravity
    การจัดตำแหน่งในแนวตั้งเทียบกับ parent box
    ค่า top , center หรือ bottom 
    เพิ่มเติม http://niik.in/899
 
 

    Filler Element

<filler />
ไม่ต้องกำหนด property แต่จำไว้ว่า filler มี flex เท่ากับ 1 เสมอ และ การกำหนด spacing 
ใน parent box ไม่มีผลกับ filler
 
 

    Icon Element

<icon url="https://www.ninenik.com/images/ninenik_page_logo.png" />
*url
    กำหนด url ของไฟล์รูปภาพที่ต้องการใช้เป็นไอคอน ต้องเรียกผ่าน https เท่านั้น
    รองรับไฟล์ JPEG และ PNG ขนาดสูงสุดไม่เกิน 240x240 
    ขนาดไฟล์สูงสุดไม่เกิน 1 MB
margin
    กำหนดระยะห่างของ element ใกล้เคียง none, xs, sm, md, lg, xl, หรือ xxl
    เพิ่มเติม http://niik.in/899
size
    กำหนดขนาดสูงสุดของ element นั้นๆ
    ใช้ค่า xxs, xs, sm, md, lg, xl, xxl, 3xl, 4xl, หรือ 5xl ใหญ่ขึ้นตามลำดับ ค่าเริ่มต้นคือ md
aspectRatio
    อัตราส่วนความกว้างต่อความสูง {width}:{height} เข่น 4:3 หรือ 16:9 ค่าเริ่มต้นเป็น 1:1
    เพิ่มเติม http://niik.in/899
 
Icon Element จะมี flex property เท่ากับ 0 คือ มีความกว้างหรือความสูง เท่ากับขนาดของ Icon นั้นๆ
 
 

    Image Element

<image url="https://www.ninenik.com/images/ninenik_page_logo.png" />
*url
    กำหนด url ของไฟล์รูปภาพ ต้องเรียกผ่าน https เท่านั้น
    รองรับไฟล์ JPEG และ PNG ขนาดสูงสุดไม่เกิน 1024x1024 
    ขนาดไฟล์สูงสุดไม่เกิน 1 MB
flex
    กำหนดเป็นตัวเลข เป็นค่ากำหนดถึงสัดส่วนความกว้างหรือสูงของ element นั้นเทียบกับ parent box 
    เพิ่มเติม http://niik.in/899
margin
    กำหนดระยะห่างของ element ใกล้เคียง none, xs, sm, md, lg, xl, หรือ xxl
    เพิ่มเติม http://niik.in/899
align
    การจัดตำแหน่งในแนวนอนเทียบกับ parent box
    ค่า start , center หรือ end ค่าเริ่มต้น จะเป็น center
    เพิ่มเติม http://niik.in/899
gravity
    การจัดตำแหน่งในแนวตั้งเทียบกับ parent box
    ค่า top , center หรือ bottom ค่าเริ่มต้น จะเป็น top
    เพิ่มเติม http://niik.in/899
size
    กำหนดขนาดสูงสุดของ element นั้นๆ
    ใช้ค่า xxs, xs, sm, md, lg, xl, xxl, 3xl, 4xl, 5xl, หรือ full  ขนาดจะใหญ่ขึ้นตามลำดับ 
    ค่าเริ่มต้นคือ md
aspectRatio
    อัตราส่วนความกว้างต่อความสูง {width}:{height} เข่น 4:3 หรือ 16:9 ค่าเริ่มต้นเป็น 1:1
    เพิ่มเติม http://niik.in/899
aspectMode
    การกำหนดลักษณะการแสดงของรูป ค่า fit และ cover ค่าเริ่มต้นคือ fit
    fit สำหรับให้แสดงให้เห็นรูปนั้นๆ ในพื้นที่ อาจจะมีช่องว่างพื้นหลังถ้ารูปนั้นมีขนาดไม่สันพันธ์กับพื้นที่
    cover สำหรับให้รูปคลุมเต็มพื้นที่ ลักษณะคล้ายกับเป็นรูปพื้นหลัง บางส่วนของรูปอาจหายไป
    ถ้าพื้นที่ไม่สัมพันธ์กับขนาดรูป
    เพิ่มเติม http://niik.in/899
backgroundColor
    สำหรับกำหนดสีพื้นหลัง กรณีรูปนั้นเป็นรูปโปร่งแสง
    ค่าสีพื้นหลังใช้เป็นข้อความเลขฐาน 16 เช่น #CCCCCC
action
    กำหนดการทำงานให้กับ element นั้น ๆ เมื่อแตะหรือกดที่ element
    รูปแบบการใช้งาน จะอธิบายในหัวข้อถัดไป ตัวอย่าง action="u(http://niik.in)" หมายถึง
    ลิ้งค์ไปยัง url ที่กำหนด
 
 

    Separator Element

<separator />
margin
    กำหนดระยะห่างของ element ใกล้เคียง none, xs, sm, md, lg, xl, หรือ xxl
    เพิ่มเติม http://niik.in/899
color
    กำหนดสีของเส้นคั่นหรือเส้นแบ่ง ค่าสีใช้เป็นข้อความเลขฐาน 16 เช่น #CCCCCC 

 

    Spacer Element

<spacer />
size
    ขนาดของช่องว่าง ระหว่าง element 
    ใช้ค่า xs, sm, md, lg, xl, หรือ xxl ขนาดจะใหญ่ขึ้นตามลำดับ 
    ค่าเริ่มต้นคือ md
 
การกำหนด spacing property ของ parent box จะไม่มีผลกับ Spacer Element

 

    Text Element

<text>Hello World</text>
flex
    กำหนดเป็นตัวเลข เป็นค่ากำหนดถึงสัดส่วนความกว้างหรือสูงของ element นั้นเทียบกับ parent box 
    เพิ่มเติม http://niik.in/899
margin
    กำหนดระยะห่างของ element ใกล้เคียง none, xs, sm, md, lg, xl, หรือ xxl
    เพิ่มเติม http://niik.in/899
size
    กำหนดขนาดของตัวอักษร
    ใช้ค่า xxs, xs, sm, md, lg, xl, xxl, 3xl, 4xl, หรือ 5xl  ขนาดจะใหญ่ขึ้นตามลำดับ 
    ค่าเริ่มต้นคือ md
align
    การจัดตำแหน่งในแนวนอนเทียบกับ parent box
    ค่า start , center หรือ end ค่าเริ่มต้น จะเป็น center
    เพิ่มเติม http://niik.in/899
gravity
    การจัดตำแหน่งในแนวตั้งเทียบกับ parent box
    ค่า top , center หรือ bottom ค่าเริ่มต้น จะเป็น top
    เพิ่มเติม http://niik.in/899
wrap
    กำหนดให้ขึ้นบรรทัดใหม่อัตโนมัติ เพื่อให้ข้อความอยู่ในกรอบ หรือพื้นที่ 
    ใช้ ค่า true หรือ false ค่าเริ่มต้นเป็น false  กรณีใช้ค่าเป็น true เราสามารถกำหนด
    การขึ้นบรรทัดใหม่โดยใช้ \n แทรกในข้อความได้
maxLines
    กำหนดตัวเลข จำนวนบรรทัดของข้อความสูงสุด กรณีข้อความมีจำนวนมาก 
    ทำให้จำนวนบรรทัดเกินค่าที่กำหนด จะแสดงเป็น (...) ต่อท้าย 
    ถ้ากำหนดเป็น 0 จะหมายถึงให้แสดงข้อความทั้งหมด ค่าเริ่มต้นเท่ากับ 0
weight
    กำหนดความเข้มหรือความหนาของข้อความ โดยใช้ค่า regular หรือ bold 
    โดยถ้าระบุเป็น bold จะเป็นตัวหนา ค่าเริ่มต้นเป็น regular หรือตัวอักษรปกติ
color
    กำหนดสีของข้อความ ค่าสีใช้เป็นข้อความเลขฐาน 16 เช่น #CCCCCC 
action
    กำหนดการทำงานให้กับ element นั้น ๆ เมื่อแตะหรือกดที่ element
    รูปแบบการใช้งาน จะอธิบายในหัวข้อถัดไป ตัวอย่าง action="u(http://niik.in)" หมายถึง
    ลิ้งค์ไปยัง url ที่กำหนด
 
 
 

การกำหนด Action ให้กับ Element

    action เป็น property หนึ่งที่ให้ผู้ใช้สามารถโต้ตอบหรือปฏิสัมพันธ์กับ Flex Message โดย Element
ที่รองรับ action property ได้แก่ Box , Button , Image และ Text Element
 
<button style="primary" action="u(http://niik.in)">More</button>

    รูปแบบ action

    p(data) สำหรับกำหนด postback action
        action="p(a=1&b=2)"
 
    m(data) สำหรับกำหนด message action
        action="m(flex message)"
 
    u(data) สำหรับกำหนด uri action หรือ url 
        action="u(http://niik.in)"
 
    d(data) สำหรับกำหนด datetime picker action
        action="d(reservDate=1&room=1)"
 
    c() สำหรับกำหนด เพื่อถ่ายรูป
        action="c()"
 
    cs() สำหรับกำหนด ให้เลือกรูป 1 รูปจากคลังภาพ
        action="cs()"
 
    cm() สำหรับกำหนด ให้เลือกรูปได้หลายรูปจากคลังภาพ
        action="cm()"
 
    l() สำหรับกำหนด เลือกตำแหน่งในแผนที่ (*ตัว L พิมพ์เล็ก)
        action="l()"
 
 
ทั้งหมด เป็นแนวทางการประยุกต์ การสร้าง Flex Message ในรูปแบบ XML สามารถนำไปปรับแต่ง
เพิ่มเติมได้ตามต้องการ 


   เพิ่มเติมเนื้อหา ครั้งที่ 1 วันที่ 04-05-2020


อัพเดทการกำหนด XML สำหรับ Flex Message เพิ่มเติม 

    เนื้อหานี้จะเป็นส่วนเพิ่มเติม สำหรับการกำหนด XML ให้กับ Flex Message ซึ่งมีการ
ปรับเพิ่มเติมความสามารถเข้ามา เช่น
    การกำหนดขนาดของ Bubble ที่เรียกรับค่า nano, micro, kilo, mega, และ giga กรณีไม่กำหนดค่าเริ่ม
ต้นจะเป็น mega.
  https://developers.line.biz/en/reference/messaging-api/#bubble
 
 
    สามารถกำหนด size attribute และกำหนดค่าที่ต้องการเข้าไปได้เลย
    กรณีใช้งาน bubble ใน carousel ต้องกำหนดทุกๆ bubble เป็นค่าเดียวกันเท่านั้น
 
    <bubble direction="ltr" size="giga">   
        <body>
            <box layout="vertical">
                <image url="https://www.ninenik.com/images/ninenik_page_logo.png" size="full" />
            </box>		
        </body>  		
    </bubble>
 
 
 
    สามารถกำหนด Action ให้กับ bubble ด้วย action attribute ดังนี้
    สมตติต้องการให้ผู้ใช้ แจ้งตำแหน่ง หรือพิกัดในแผนที่
 
    <bubble direction="ltr" size="kilo" action="l()">   
        <body>
            <box layout="vertical">
                <image action="u(http://niik.in)" 
url="https://www.ninenik.com/images/ninenik_page_logo.png" size="full" />
            </box>		
        </body>  		
    </bubble>
 
    สังเกตว่า เรากำหนด action ไว้สองที่คือ ในรูป เป็นลิ้งค์ไป url ที่ต้องการ และกำหนดใน bubble เป็นการขอพิกัด
    การทำงานของ action คือ ถ้ากดที่รูป ก็จะทำงาน action ของรูป แต่ถ้าเรากดพื้นที่อื่นนอกรูป แต่อยู่ใน bubble
    ก็จะเป็นการขอพิกัดแทน
 
 
 
    สามารถใช้ Component อื่นๆ นอกจาก Image ใน Hero block ได้ เหมือนกับ block ส่วนอื่นๆ 
 
    <bubble direction="ltr" size="kilo" action="l()">   
		<hero backgroundColor="#60C5F1">
            <box layout="horizontal">
                <image url="https://www.ninenik.com/images/ninenik_page_logo.png" size="md" />            
            </box>		 
		</hero>
        <body>
            <box layout="vertical">
                <image action="u(http://niik.in)" 
					url="https://www.ninenik.com/images/ninenik_page_logo.png" size="full" />
            </box>	
        </body>  		
    </bubble>
 
 
 
    สามารถกำหนด attribute เพิ่มเติมเหล่านี้ให้กับ Box, Image, Text, Icon และ Button Component ได้
    ได้แก่ position, offsetTop, offsetBottom, offsetStart และ offsetEnd
 
    <bubble direction="ltr" size="kilo" action="l()">   
		<hero backgroundColor="#60C5F1">
            <box layout="horizontal">
                <image url="https://www.ninenik.com/images/ninenik_page_logo.png" size="md" />            
            </box>		 
		</hero>
        <body>
            <box layout="vertical">
                <image 
					offsetBottom="10px" offsetTop="25px"
					action="u(http://niik.in)" 
					url="https://www.ninenik.com/images/ninenik_page_logo.png" size="full" />
            </box>	
        </body>  		
    </bubble>    
 
    นอกจากนั้น พิเศษสำหรับ Box Component จะสามารถกำหนดค่า attribute เหล่านี้เพิ่มเติมได้
    paddingAll, paddingTop, paddingBottom, paddingStart, paddingEnd, backgroundColor,
    borderColor, borderWidth, cornerRadius, width, height, และ position
 
    <bubble direction="ltr" size="kilo" action="l()">   
		<hero backgroundColor="#60C5F1">
            <box layout="horizontal">
                <image url="https://www.ninenik.com/images/ninenik_page_logo.png" size="md" />            
            </box>		 
		</hero>
        <body>
            <box layout="vertical" backgroundColor="#4AD071"
				cornerRadius="20px" borderColor="#FFFF00" borderWidth="10px">
                <image 
					offsetBottom="10px" offsetTop="25px"
					action="u(http://niik.in)" 
					url="https://www.ninenik.com/images/ninenik_page_logo.png" size="full" />
            </box>	
        </body>  		
    </bubble>
    
    ดูค่าสำหรับกำหนดเพิ่มเติม https://developers.line.biz/en/reference/messaging-api/#box
 
 
 
     สามารถจัดรูปแบบเพิ่มเติมให้กับข้อความ Text Component โดยกำหนด style และ decoration ตามต้องการ
 
    <bubble direction="ltr" size="kilo" action="l()">   
		<hero backgroundColor="#60C5F1">
            <box layout="horizontal">
                <image url="https://www.ninenik.com/images/ninenik_page_logo.png" size="md" />            
            </box>		 
		</hero>
        <body>
            <box layout="vertical" backgroundColor="#4AD071"
				cornerRadius="20px" borderColor="#FFFF00" borderWidth="10px">
                <image 
					offsetBottom="10px" offsetTop="25px"
					action="u(http://niik.in)" 
					url="https://www.ninenik.com/images/ninenik_page_logo.png" size="full" />
            </box>	
        </body>  		
		<footer>
            <box layout="vertical">
                <text size="md" align="center" color="#ff0000" style="italic">Closing the distance</text>
                <text size="lg" align="center" color="#00ff00" decoration="underline">Closing the distance</text>
                <text size="xl" align="center" color="#0000ff" weight="bold">Closing the distance</text>
            </box>		
		</footer>
    </bubble>
 
    และสำหรับการใช้งาน Text เราสามารถกำหนดและใช้งาน Span Component ใหม่ ที่จะอยู่ภายใน Text Component อีกที
    เป็นตัวช่วยกำหนด และจัดรูปแบบข้อความ แยกเป็นส่วนได้ โดยข้อความจาก span จะแทนที่ข้อความ text เดิม
 
		<footer>
            <box layout="vertical">
                <text size="md" align="center" color="#ff0000" style="italic">Closing the distance</text>
                <text size="lg" align="center" color="#00ff00" decoration="underline">Closing the distance</text>
                <text size="xl" align="center" color="#0000ff" weight="bold">
				Closing the distance
				<span color="#FF0000" style="italic" decoration="underline">This is apan 1</span>
				<span weight="bold" color="#A34AA4">This is apan 2</span>
				</text>
            </box>		
		</footer>
 
    ข้อความคำว่า Closing the distance จะถูกแทนที่ด้วยข้อความใน span ทั้งสอง
 
 
    และสุดท้าย การใช้งาน Filler Component เราสามารถกำหนด attribute ชื่อว่า flex เพิ่มเติมได้
 
    <bubble direction="ltr">
        <body>
            <box layout="horizontal">
                <image url="https://www.ninenik.com/images/ninenik_page_logo.png" />      
                <filler flex="3" />
                <image url="https://www.ninenik.com/images/ninenik_page_logo.png" />      
            </box>
        </body>       
    </bubble>
 
    เพื่อให้เราสามารถกำหนดการใช้งานความสามารถใหม่ข้างต้นได้ สิ่งที่ต้องทำคือ ในไฟล์ bot_action.php และ
    flex_gen.php ให้ตรวจสอบดูว่า เราทำการ เรียกใช้งานสองคำสั่งนี้เข้ามาแล้วหรือไม่ ถ้ายังไม่มีให้เพิ่มเข้าไป
 
use LINE\LINEBot\Constant\Flex\BubleContainerSize;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\SpanComponentBuilder;
 
    ส่วนโค้ดของไฟล์ flex_gen.php ที่ปรับใหม่จะเป็นดังนี้ สามารถคัดลองไปแทนตัวเก่าได้เลย
 

    ไฟล์ flex_gen.php

 
<?php
///////////// ส่วนของการเรียกใช้งาน class ผ่าน namespace
use LINE\LINEBot;
use LINE\LINEBot\HTTPClient;
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
use LINE\LINEBot\Event;
use LINE\LINEBot\Event\BaseEvent;
use LINE\LINEBot\Event\MessageEvent;
use LINE\LINEBot\Event\AccountLinkEvent;
use LINE\LINEBot\Event\MemberJoinEvent; 
use LINE\LINEBot\MessageBuilder;
use LINE\LINEBot\MessageBuilder\TextMessageBuilder;
use LINE\LINEBot\MessageBuilder\StickerMessageBuilder;
use LINE\LINEBot\MessageBuilder\ImageMessageBuilder;
use LINE\LINEBot\MessageBuilder\LocationMessageBuilder;
use LINE\LINEBot\MessageBuilder\AudioMessageBuilder;
use LINE\LINEBot\MessageBuilder\VideoMessageBuilder;
use LINE\LINEBot\ImagemapActionBuilder;
use LINE\LINEBot\ImagemapActionBuilder\AreaBuilder;
use LINE\LINEBot\ImagemapActionBuilder\ImagemapMessageActionBuilder ;
use LINE\LINEBot\ImagemapActionBuilder\ImagemapUriActionBuilder;
use LINE\LINEBot\MessageBuilder\Imagemap\BaseSizeBuilder;
use LINE\LINEBot\MessageBuilder\ImagemapMessageBuilder;
use LINE\LINEBot\MessageBuilder\MultiMessageBuilder;
use LINE\LINEBot\TemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\DatetimePickerTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\MessageTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\PostbackTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\UriTemplateActionBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateMessageBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ButtonTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\CarouselTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\CarouselColumnTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ConfirmTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ImageCarouselTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ImageCarouselColumnTemplateBuilder;
use LINE\LINEBot\QuickReplyBuilder;
use LINE\LINEBot\QuickReplyBuilder\QuickReplyMessageBuilder;
use LINE\LINEBot\QuickReplyBuilder\ButtonBuilder\QuickReplyButtonBuilder;
use LINE\LINEBot\TemplateActionBuilder\CameraRollTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\CameraTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\LocationTemplateActionBuilder;
use LINE\LINEBot\RichMenuBuilder;
use LINE\LINEBot\RichMenuBuilder\RichMenuSizeBuilder;
use LINE\LINEBot\RichMenuBuilder\RichMenuAreaBuilder;
use LINE\LINEBot\RichMenuBuilder\RichMenuAreaBoundsBuilder;
use LINE\LINEBot\Constant\Flex\ComponentIconSize;
use LINE\LINEBot\Constant\Flex\ComponentImageSize;
use LINE\LINEBot\Constant\Flex\ComponentImageAspectRatio;
use LINE\LINEBot\Constant\Flex\ComponentImageAspectMode;
use LINE\LINEBot\Constant\Flex\ComponentFontSize;
use LINE\LINEBot\Constant\Flex\ComponentFontWeight;
use LINE\LINEBot\Constant\Flex\ComponentMargin;
use LINE\LINEBot\Constant\Flex\ComponentSpacing;
use LINE\LINEBot\Constant\Flex\ComponentButtonStyle;
use LINE\LINEBot\Constant\Flex\ComponentButtonHeight;
use LINE\LINEBot\Constant\Flex\ComponentSpaceSize;
use LINE\LINEBot\Constant\Flex\ComponentGravity;
use LINE\LINEBot\Constant\Flex\BubleContainerSize;
use LINE\LINEBot\MessageBuilder\FlexMessageBuilder;
use LINE\LINEBot\MessageBuilder\Flex\BubbleStylesBuilder;
use LINE\LINEBot\MessageBuilder\Flex\BlockStyleBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ContainerBuilder\BubbleContainerBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ContainerBuilder\CarouselContainerBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\BoxComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\ButtonComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\IconComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\ImageComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\SpacerComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\FillerComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\SeparatorComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\TextComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\SpanComponentBuilder;


$is_carousel = NULL;
$is_bubble = NULL;
$is_singleBubble = NULL;
$count_container = 0;
$count_bubble = 0;
$name_container = NULL;

$bubble_direction = array();
$bubble_size = array();
$bubble_action = array();
$block_header = array();
$block_hero = array();
$block_body = array();
$block_footer = array();
$block_header_style = array();
$block_hero_style = array();
$block_body_style = array();
$block_footer_style = array();
$box_header = array();
$box_hero = array();
$box_body = array();
$box_footer = array();

function bubbleContainerAttr($xmlObj){
	$bubbleContainer = $xmlObj;
	$bubbleContainerAttr = array(null,null,null);
	foreach($bubbleContainer->attributes() as $key=>$val){
		if($key=="direction"){$bubbleContainerAttr[0]=implode("",(array)$val[0]);}
		if($key=="size"){$bubbleContainerAttr[1]=implode("",(array)$val[0]);}
		if($key=="action"){
			$textButton = "u";
			$strAction = str_replace(")","",implode("",(array)$val[0]));
			switch($strAction){
				case (preg_match('/^p\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new PostbackTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^m\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new MessageTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^u\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,$data);			
					break;
				case (preg_match('/^c\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/camera/");		
					break;
				case (preg_match('/^cs\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/single/");	
					break;
				case (preg_match('/^cm\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/multi/");				
					break;
				case (preg_match('/^l\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/location");				
					break;
				case (preg_match('/^d\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new DatetimePickerTemplateActionBuilder($textButton,$data,'datetime');
					break;																																			
				default:
					$actionVal = new PostbackTemplateActionBuilder($textButton,"");	
					break;					
			}					
			$bubbleContainerAttr[2] = $actionVal;
		}		
	}	
	return $bubbleContainerAttr;			
}
function blockStyleAttr($xmlObj){
	$blockStyle = $xmlObj;
	$blockStyleAttr = array(null,null,null);
	foreach($blockStyle->attributes() as $key=>$val){
		if($key=="backgroundColor"){$blockStyleAttr[0]=implode("",(array)$val[0]);}
		if($key=="separator"){$blockStyleAttr[1]=(boolean)implode("",(array)$val[0]);}
		if($key=="separatorColor"){$blockStyleAttr[2]=implode("",(array)$val[0]);}
	}	
	if(count($blockStyle->attributes())>0){
		return $blockStyleAttr;			
	}else{
		return NULL;	
	}
}
function textComponentArr($xmlObj){
	$textComponent = $xmlObj;
	$textComponentAttr = array(trim((string)$textComponent),null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null);
	foreach($textComponent->attributes() as $key=>$val){
		if($key=="flex"){$textComponentAttr[1]=(int)implode("",(array)$val[0]);}
		if($key=="margin"){$textComponentAttr[2]=implode("",(array)$val[0]);}
		if($key=="size"){$textComponentAttr[3]=implode("",(array)$val[0]);}
		if($key=="align"){$textComponentAttr[4]=implode("",(array)$val[0]);}
		if($key=="gravity"){$textComponentAttr[5]=implode("",(array)$val[0]);}
		if($key=="wrap"){$textComponentAttr[6]=(boolean)implode("",(array)$val[0]);}
		if($key=="maxLines"){$textComponentAttr[7]=(int)implode("",(array)$val[0]);}
		if($key=="weight"){$textComponentAttr[8]=implode("",(array)$val[0]);}		
		if($key=="color"){$textComponentAttr[9]=implode("",(array)$val[0]);}
		if($key=="action"){
			$textButton = "u";
			$strAction = str_replace(")","",implode("",(array)$val[0]));
			switch($strAction){
				case (preg_match('/^p\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new PostbackTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^m\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new MessageTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^u\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,$data);			
					break;
				case (preg_match('/^c\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/camera/");		
					break;
				case (preg_match('/^cs\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/single/");	
					break;
				case (preg_match('/^cm\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/multi/");				
					break;
				case (preg_match('/^l\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/location");				
					break;
				case (preg_match('/^d\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new DatetimePickerTemplateActionBuilder($textButton,$data,'datetime');
					break;																																			
				default:
					$actionVal = new PostbackTemplateActionBuilder($textButton,"");	
					break;					
			}					
			$textComponentAttr[10] = $actionVal;
		}
		if($key=="position"){$textComponentAttr[11]=implode("",(array)$val[0]);}
		if($key=="offsetTop"){$textComponentAttr[12]=implode("",(array)$val[0]);}
		if($key=="offsetBottom"){$textComponentAttr[13]=implode("",(array)$val[0]);}
		if($key=="offsetStart"){$textComponentAttr[14]=implode("",(array)$val[0]);}
		if($key=="offsetEnd"){$textComponentAttr[15]=implode("",(array)$val[0]);}
		if($key=="style"){$textComponentAttr[16]=implode("",(array)$val[0]);}
		if($key=="decoration"){$textComponentAttr[17]=implode("",(array)$val[0]);}
	}	
	return $textComponentAttr;
}
function boxComponentArr($xmlObj,$arrComponent = array()){
	$boxComponent = $xmlObj;
	$boxComponentAttr = array(null,$arrComponent,null,null,null,null,null,null,null,null,null,null,null,null
	,null,null,null,null,null,null,null,null);
	foreach($boxComponent->attributes() as $key=>$val){
		if($key=="layout"){$boxComponentAttr[0]=implode("",(array)$val[0]);}
		if($key=="flex"){$boxComponentAttr[2]=(int)implode("",(array)$val[0]);}
		if($key=="spacing"){$boxComponentAttr[3]=implode("",(array)$val[0]);}
		if($key=="margin"){$boxComponentAttr[4]=implode("",(array)$val[0]);}
		if($key=="action"){
			$textButton = "u";
			$strAction = str_replace(")","",implode("",(array)$val[0]));
			switch($strAction){
				case (preg_match('/^p\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new PostbackTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^m\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new MessageTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^u\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,$data);			
					break;
				case (preg_match('/^c\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/camera/");		
					break;
				case (preg_match('/^cs\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/single/");	
					break;
				case (preg_match('/^cm\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/multi/");				
					break;
				case (preg_match('/^l\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/location");				
					break;
				case (preg_match('/^d\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new DatetimePickerTemplateActionBuilder($textButton,$data,'datetime');
					break;																																			
				default:
					$actionVal = new PostbackTemplateActionBuilder($textButton,"");	
					break;					
			}		
			$boxComponentAttr[5] = $actionVal;
		}
		if($key=="paddingAll"){$boxComponentAttr[6]=implode("",(array)$val[0]);}
		if($key=="paddingTop"){$boxComponentAttr[7]=implode("",(array)$val[0]);}
		if($key=="paddingBottom"){$boxComponentAttr[8]=implode("",(array)$val[0]);}
		if($key=="paddingStart"){$boxComponentAttr[9]=implode("",(array)$val[0]);}
		if($key=="paddingEnd"){$boxComponentAttr[10]=implode("",(array)$val[0]);}
		if($key=="backgroundColor"){$boxComponentAttr[11]=implode("",(array)$val[0]);}
		if($key=="borderColor"){$boxComponentAttr[12]=implode("",(array)$val[0]);}
		if($key=="borderWidth"){$boxComponentAttr[13]=implode("",(array)$val[0]);}
		if($key=="cornerRadius"){$boxComponentAttr[14]=implode("",(array)$val[0]);}
		if($key=="width"){$boxComponentAttr[15]=implode("",(array)$val[0]);}
		if($key=="height"){$boxComponentAttr[16]=implode("",(array)$val[0]);}
		if($key=="position"){$boxComponentAttr[17]=implode("",(array)$val[0]);}
		if($key=="offsetTop"){$boxComponentAttr[18]=implode("",(array)$val[0]);}
		if($key=="offsetBottom"){$boxComponentAttr[19]=implode("",(array)$val[0]);}
		if($key=="offsetStart"){$boxComponentAttr[20]=implode("",(array)$val[0]);}
		if($key=="offsetEnd"){$boxComponentAttr[21]=implode("",(array)$val[0]);}
	}	
	return $boxComponentAttr;
}
function buttonComponentArr($xmlObj){
	$buttonComponent = $xmlObj;
	$textButton = trim((string)$buttonComponent);
	$buttonComponentAttr = array(new PostbackTemplateActionBuilder($textButton,"nothing"),null,null,null,
	null,null,null,null,null,null,null,null);
	foreach($buttonComponent->attributes() as $key=>$val){
		if($key=="action"){
			$strAction = str_replace(")","",implode("",(array)$val[0]));
			switch($strAction){
				case (preg_match('/^p\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new PostbackTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^m\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new MessageTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^u\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,$data);			
					break;
				case (preg_match('/^c\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/camera/");		
					break;
				case (preg_match('/^cs\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/single/");	
					break;
				case (preg_match('/^cm\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/multi/");				
					break;
				case (preg_match('/^l\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/location");				
					break;
				case (preg_match('/^d\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new DatetimePickerTemplateActionBuilder($textButton,$data,'datetime');
					break;																																			
				default:
					$actionVal = new PostbackTemplateActionBuilder($textButton,"false");	
					break;					
			}
			$buttonComponentAttr[0] = $actionVal;
		}
		if($key=="flex"){$buttonComponentAttr[1]=(int)implode("",(array)$val[0]);}
		if($key=="margin"){$buttonComponentAttr[2]=implode("",(array)$val[0]);}
		if($key=="height"){$buttonComponentAttr[3]=implode("",(array)$val[0]);}
		if($key=="style"){$buttonComponentAttr[4]=implode("",(array)$val[0]);}
		if($key=="color"){$buttonComponentAttr[5]=implode("",(array)$val[0]);}
		if($key=="gravity"){$buttonComponentAttr[6]=implode("",(array)$val[0]);}
		
		if($key=="position"){$buttonComponentAttr[7]=implode("",(array)$val[0]);}
		if($key=="offsetTop"){$buttonComponentAttr[8]=implode("",(array)$val[0]);}
		if($key=="offsetBottom"){$buttonComponentAttr[9]=implode("",(array)$val[0]);}
		if($key=="offsetStart"){$buttonComponentAttr[10]=implode("",(array)$val[0]);}
		if($key=="offsetEnd"){$buttonComponentAttr[11]=implode("",(array)$val[0]);}		
		
	}	
	return $buttonComponentAttr;
}
function iconComponentAttr($xmlObj){
	$iconComponent = $xmlObj;
	$iconComponentAttr = array(null,null,null,null,null,null,null,null,null);
	foreach($iconComponent->attributes() as $key=>$val){
		if($key=="url"){$iconComponentAttr[0]=implode("",(array)$val[0]);}
		if($key=="margin"){$iconComponentAttr[1]=implode("",(array)$val[0]);}
		if($key=="size"){$iconComponentAttr[2]=implode("",(array)$val[0]);}
		if($key=="aspectRatio"){$iconComponentAttr[3]=implode("",(array)$val[0]);}
		
		if($key=="position"){$iconComponentAttr[4]=implode("",(array)$val[0]);}
		if($key=="offsetTop"){$iconComponentAttr[5]=implode("",(array)$val[0]);}
		if($key=="offsetBottom"){$iconComponentAttr[6]=implode("",(array)$val[0]);}
		if($key=="offsetStart"){$iconComponentAttr[7]=implode("",(array)$val[0]);}
		if($key=="offsetEnd"){$iconComponentAttr[8]=implode("",(array)$val[0]);}				
		
	}	
	return $iconComponentAttr;		
}
function spanComponentAttr($xmlObj){
	$spanComponent = $xmlObj;
	$spanComponentAttr = array("test span",null,null,null,null,null);	
	foreach($spanComponent->attributes() as $key=>$val){
		if($key=="size"){$spanComponentAttr[1]=implode("",(array)$val[0]);}
		if($key=="color"){$spanComponentAttr[2]=implode("",(array)$val[0]);}		
		if($key=="weight"){$spanComponentAttr[3]=implode("",(array)$val[0]);}
		if($key=="style"){$spanComponentAttr[4]=implode("",(array)$val[0]);}
		if($key=="decoration"){$spanComponentAttr[5]=implode("",(array)$val[0]);}		
	}	
	return $spanComponentAttr;		
}
function separatorComponentAttr($xmlObj){
	$separatorComponent = $xmlObj;
	$separatorComponentAttr = array();
	foreach($separatorComponent->attributes() as $key=>$val){
		if($key=="margin"){$separatorComponentAttr[0]=implode("",(array)$val[0]);}
		if($key=="color"){$separatorComponentAttr[1]=implode("",(array)$val[0]);}
	}	
	return $separatorComponentAttr;		
}
function fillerComponentAttr($xmlObj){
	$fillerComponent= $xmlObj;
	$fillerComponentAttr = array();
	foreach($fillerComponent->attributes() as $key=>$val){
		if($key=="flex"){$fillerComponentAttr[0]=(int)implode("",(array)$val[0]);}
	}	
	return $fillerComponentAttr;				
}
function spacerComponentAttr($xmlObj){
	$spacerComponent = $xmlObj;
	$spacerComponentAttr = array("md");
	foreach($spacerComponent->attributes() as $key=>$val){
		if($key=="size"){$spacerComponentAttr[0]=implode("",(array)$val[0]);}
	}	
	return $spacerComponentAttr;	
}
function imageComponentArr($xmlObj){
	$imageComponent = $xmlObj;
	$imageComponentAttr = array(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null);
	foreach($imageComponent->attributes() as $key=>$val){
		if($key=="url"){$imageComponentAttr[0]=implode("",(array)$val[0]);}
		if($key=="flex"){$imageComponentAttr[1]=(int)implode("",(array)$val[0]);}
		if($key=="margin"){$imageComponentAttr[2]=implode("",(array)$val[0]);}
		if($key=="align"){$imageComponentAttr[3]=implode("",(array)$val[0]);}
		if($key=="gravity"){$imageComponentAttr[4]=implode("",(array)$val[0]);}
		if($key=="size"){$imageComponentAttr[5]=implode("",(array)$val[0]);}
		if($key=="aspectRatio"){$imageComponentAttr[6]=implode("",(array)$val[0]);}
		if($key=="aspectMode"){$imageComponentAttr[7]=implode("",(array)$val[0]);}		
		if($key=="backgroundColor"){$imageComponentAttr[8]=implode("",(array)$val[0]);}
		if($key=="action"){
			$textButton = "u";
			$strAction = str_replace(")","",implode("",(array)$val[0]));
			switch($strAction){
				case (preg_match('/^p\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new PostbackTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^m\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new MessageTemplateActionBuilder($textButton,$data);				
					break;
				case (preg_match('/^u\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,$data);			
					break;
				case (preg_match('/^c\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/camera/");		
					break;
				case (preg_match('/^cs\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/single/");	
					break;
				case (preg_match('/^cm\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/cameraRoll/multi/");				
					break;
				case (preg_match('/^l\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new UriTemplateActionBuilder($textButton,"line://nv/location");				
					break;
				case (preg_match('/^d\(/',$strAction) ? true : false):
					list($ac,$data) = explode("(",$strAction);
					$actionVal = new DatetimePickerTemplateActionBuilder($textButton,$data,'datetime');
					break;																																			
				default:
					$actionVal = new PostbackTemplateActionBuilder($textButton,"");	
					break;					
			}
			$imageComponentAttr[9] = $actionVal;			
		}
		if($key=="position"){$imageComponentAttr[10]=implode("",(array)$val[0]);}
		if($key=="offsetTop"){$imageComponentAttr[11]=implode("",(array)$val[0]);}
		if($key=="offsetBottom"){$imageComponentAttr[12]=implode("",(array)$val[0]);}
		if($key=="offsetStart"){$imageComponentAttr[13]=implode("",(array)$val[0]);}
		if($key=="offsetEnd"){$imageComponentAttr[14]=implode("",(array)$val[0]);}				
	}	
	return $imageComponentAttr;
}
function genComponent($elName,$childObj,$arr_Element=null){
	if($elName=="box"){
		$arr_childObj = array_chunk(boxComponentArr($childObj,listElement($childObj,$arr_Element)), 6, true); 
		$param_childObj = array_shift($arr_childObj);
		$option_attr = boxComponentArr($childObj);
		$boxObj_C = new BoxComponentBuilder(...$param_childObj);	
		if(is_array($option_attr) && count($option_attr)>0){
			$boxObj_C->setPaddingAll($option_attr[6])
			->setPaddingTop($option_attr[7])
			->setPaddingBottom($option_attr[8])
			->setPaddingStart($option_attr[9])
			->setPaddingEnd($option_attr[10])
			->setBackgroundColor($option_attr[11])
			->setBorderColor($option_attr[12])
			->setBorderWidth($option_attr[13])
			->setCornerRadius($option_attr[14])
			->setWidth($option_attr[15])																											
			->setHeight($option_attr[16])
			->setPosition($option_attr[17])
			->setOffsetTop($option_attr[18])
			->setOffsetBottom($option_attr[19])
			->setOffsetStart($option_attr[20])
			->setOffsetEnd($option_attr[21]);
		}	
		return $boxObj_C;
	}
	if($elName=="text"){
		$arr_childObj = array_chunk(textComponentArr($childObj), 11, true); 
		$param_childObj = array_shift($arr_childObj);
		$option_attr = textComponentArr($childObj);
		$textObj_C = new TextComponentBuilder(...$param_childObj); 
		if(is_array($option_attr) && count($option_attr)>0){
			$textObj_C->setPosition($option_attr[11])
			->setOffsetTop($option_attr[12])
			->setOffsetBottom($option_attr[13])
			->setOffsetStart($option_attr[14])
			->setOffsetEnd($option_attr[15])
			->setStyle($option_attr[16])
			->setDecoration($option_attr[17]);
		}
		$spanObj_C = array();
		foreach ($childObj->children() as $_childObj) {		
			$spanObj_C[] = new SpanComponentBuilder(...spanComponentAttr($_childObj));
		}
		$textObj_C->setContents($spanObj_C);
		return $textObj_C;
	}
	if($elName=="button"){
		$arr_childObj = array_chunk(buttonComponentArr($childObj), 7, true); 
		$param_childObj = array_shift($arr_childObj);
		$option_attr = buttonComponentArr($childObj);
		$buttonObj_C = new ButtonComponentBuilder(...$param_childObj); 
		if(is_array($option_attr) && count($option_attr)>0){
			$buttonObj_C->setPosition($option_attr[7])
			->setOffsetTop($option_attr[8])
			->setOffsetBottom($option_attr[9])
			->setOffsetStart($option_attr[10])
			->setOffsetEnd($option_attr[11]);
		}
		return $buttonObj_C;
	}
	if($elName=="icon"){
		$arr_childObj = array_chunk(iconComponentAttr($childObj), 4, true); 
		$param_childObj = array_shift($arr_childObj);
		$option_attr = iconComponentAttr($childObj);
		$iconObj_C = new IconComponentBuilder(...$param_childObj); 
		if(is_array($option_attr) && count($option_attr)>0){
			$iconObj_C->setPosition($option_attr[4])
			->setOffsetTop($option_attr[5])
			->setOffsetBottom($option_attr[6])
			->setOffsetStart($option_attr[7])
			->setOffsetEnd($option_attr[8]);
		}
		return $iconObj_C;
	}
	if($elName=="image"){
		$arr_childObj = array_chunk(imageComponentArr($childObj), 10, true); 
		$param_childObj = array_shift($arr_childObj);
		$option_attr = imageComponentArr($childObj);
		$imageObj_C = new ImageComponentBuilder(...$param_childObj); 
		if(is_array($option_attr) && count($option_attr)>0){
			$imageObj_C->setPosition($option_attr[10])
			->setOffsetTop($option_attr[11])
			->setOffsetBottom($option_attr[12])
			->setOffsetStart($option_attr[13])
			->setOffsetEnd($option_attr[14]);
		}
		return $imageObj_C;
	}			
	if($elName=="filler"){
		$fillerObj_C = new FillerComponentBuilder(); 	
		$option_attr = fillerComponentAttr($childObj);
		if(is_array($option_attr) && count($option_attr)>0){
			$fillerObj_C->setFlex($option_attr[0]);
		}
		return $fillerObj_C;
	}
}
function listElement($xmlObj,$arr_Element = array()){
	$arr_final = array();
	foreach ($xmlObj->children() as $childObj) {		
		$elName = $childObj->getName();	
		if($elName=="box"){
			$arr_final[] = genComponent("box",$childObj,$arr_Element);
		}else{			
			if($elName=="text"){
				$arr_final[] = genComponent("text",$childObj);
			}elseif($elName=="button"){		
				$arr_final[] = genComponent("button",$childObj);		
			}elseif($elName=="icon"){			
				$arr_final[] = genComponent("icon",$childObj);				
			}elseif($elName=="image"){			
				$arr_final[] = genComponent("image",$childObj);	
			}elseif($elName=="filler"){		
				$arr_final[] = genComponent("filler",$childObj); 		
			}elseif($elName=="span"){				
				$arr_final[] = new SpanComponentBuilder(...spanComponentAttr($childObj)); // 							
			}elseif($elName=="spacer"){				
				$arr_final[] = new SpacerComponentBuilder(...spacerComponentAttr($childObj)); // 
			}elseif($elName=="separator"){				
				$arr_final[] = new SeparatorComponentBuilder(...separatorComponentAttr($childObj)); // 										
			}else{
				$arr_final[] = array();
			}
		}
	}	
	return $arr_final;
}
function createFlex($xmlstr){
	//$objXML = new SimpleXMLElement($xmlstr);
	$xmlIterator = new SimpleXMLIterator($xmlstr);
	$xmlIterator->rewind();
	$name_container = $xmlIterator->getName();
	$count_container = $xmlIterator->count();
	
	if($name_container!="carousel"){
		$is_singleBubble = true; 
	}
	$arr_bubble = array();
	$hasBlockStyle = false;
	$i = 0;
	for( $xmlIterator; $xmlIterator->valid(); $xmlIterator->next() ) {
		$bubble_direction[$i] = NULL;
		$bubble_size[$i] = NULL;
		$bubble_action[$i] = NULL;
		$bubble_direction[$i] = bubbleContainerAttr($xmlIterator->current());
		$bubble_size[$i] = bubbleContainerAttr($xmlIterator->current());
		$bubble_action[$i] = bubbleContainerAttr($xmlIterator->current());
		
		$block_header[$i] = NULL;
		$block_hero[$i] = NULL;
		$block_body[$i] = NULL;
		$block_footer[$i] = NULL;
		$block_header_style[$i] = NULL;
		$block_hero_style[$i] = NULL;
		$block_body_style[$i] = NULL;
		$block_footer_style[$i] = NULL;
		foreach ($xmlIterator->current()->children() as $blockChild) {
			if($blockChild->getName()=="header"){
				$block_header[$i]=$blockChild;
				$block_header_style[$i] = (!is_null(blockStyleAttr($blockChild)))?new BlockStyleBuilder(...blockStyleAttr($blockChild)):NULL;	
				$box_header[$i] = listElement($blockChild->children());
			}
			if($blockChild->getName()=="hero"){
				$block_hero[$i]=$blockChild;
				$block_hero_style[$i] = (!is_null(blockStyleAttr($blockChild)))?new BlockStyleBuilder(...blockStyleAttr($blockChild)):NULL;	
				$box_hero[$i] = listElement($blockChild->children());
			}
			if($blockChild->getName()=="body"){
				$block_body[$i]=$blockChild;	
				$block_body_style[$i] = (!is_null(blockStyleAttr($blockChild)))?new BlockStyleBuilder(...blockStyleAttr($blockChild)):NULL;	
				$box_body[$i] = listElement($blockChild->children());
			}
			if($blockChild->getName()=="footer"){
				$block_footer[$i]=$blockChild;	
				$block_footer_style[$i] = (!is_null(blockStyleAttr($blockChild)))?new BlockStyleBuilder(...blockStyleAttr($blockChild)):NULL;	
				$box_footer[$i] = listElement($blockChild->children());
			}
	
		}
		$style_bubble[$i]=NULL;
		if(!is_null($block_header_style[$i]) || !is_null($block_hero_style[$i]) || !is_null($block_body_style[$i]) || !is_null($block_footer_style[$i])){
				$style_bubble[$i] = new BubbleStylesBuilder(
					$block_header_style[$i],
					$block_hero_style[$i],
					$block_body_style[$i],
					$block_footer_style[$i]
				);
		}
		$i++;
	
	}
	for($i=0;$i<$count_container;$i++){
		$containDirection = (!is_null($bubble_direction[$i]))?$bubble_direction[$i][0]:"ltr";
		$block_HeaderObj = (!is_null($block_header[$i]))?genComponent("box",$block_header[$i]->children(),$box_header[$i]):NULL;
		$block_HeroObj = (!is_null($block_hero[$i]))?genComponent("box",$block_hero[$i]->children(),$box_hero[$i]):NULL; 
		$block_BodyObj = (!is_null($block_body[$i]))?genComponent("box",$block_body[$i]->children(),$box_body[$i]):NULL;
		$block_FooterObj = (!is_null($block_footer[$i]))?genComponent("box",$block_footer[$i]->children(),$box_footer[$i]):NULL;
		
		$containHeader = $block_HeaderObj;
		$containHero = $block_HeroObj;
		$containBody = $block_BodyObj;
		$containFooter = $block_FooterObj;
		$containSize = (!is_null($bubble_size[$i]))?$bubble_size[$i][1]:NULL;
		$containAction = (!is_null($bubble_action[$i]))?$bubble_action[$i][2]:NULL;
		$bubbleObj = new BubbleContainerBuilder(
			$containDirection,$containHeader,$containHero,$containBody,$containFooter,$style_bubble[$i],$containSize
		);
		if(!is_null($containAction)){
			$bubbleObj = $bubbleObj->setAction($containAction);
		}		
		$arr_bubble[] = $bubbleObj;
	}		
	$arr_FlexMessage = NULL;
	if(!is_null($is_singleBubble)){
		$arr_FlexMessage = $arr_bubble[0];
	}else{
		$arr_FlexMessage = new CarouselContainerBuilder(
			$arr_bubble
		);
	}
	$textReplyMessage = $arr_FlexMessage;
	return $textReplyMessage;
}
 
 


กด Like หรือ Share เป็นกำลังใจ ให้มีบทความใหม่ๆ เรื่อยๆ น่ะครับ



อ่านต่อที่บทความ









เนื้อหาที่เกี่ยวข้อง






เนื้อหาพิเศษ เฉพาะสำหรับสมาชิก

กรุณาล็อกอิน เพื่ออ่านเนื้อหาบทความ

ยังไม่เป็นสมาชิก

สมาชิกล็อกอิน



( หรือ เข้าใช้งานผ่าน Social Login )




URL สำหรับอ้างอิง





คำแนะนำ และการใช้งาน

สมาชิก กรุณา ล็อกอินเข้าระบบ เพื่อตั้งคำถามใหม่ หรือ ตอบคำถาม สมาชิกใหม่ สมัครสมาชิกได้ที่ สมัครสมาชิก


  • ถาม-ตอบ กรุณา ล็อกอินเข้าระบบ
  • เปลี่ยน


    ( หรือ เข้าใช้งานผ่าน Social Login )







เว็บไซต์ของเราให้บริการเนื้อหาบทความสำหรับนักพัฒนา โดยพึ่งพารายได้เล็กน้อยจากการแสดงโฆษณา โปรดสนับสนุนเว็บไซต์ของเราด้วยการปิดการใช้งานตัวปิดกั้นโฆษณา (Disable Ads Blocker) ขอบคุณครับ