Skip to content

Instantly share code, notes, and snippets.

@misablaha
Last active December 22, 2015 00:39
Show Gist options
  • Save misablaha/6390576 to your computer and use it in GitHub Desktop.
Save misablaha/6390576 to your computer and use it in GitHub Desktop.
<?php
namespace Sbks\Stdlib;
/**
* Class ArrayMapper
* @package Sbks\Stdlib
*/
class ArrayMapper
{
const DEFAULT_VAL = 'getDefault';
const VALUE = 'getValue';
const TO_INT = 'getIntValue';
const TO_FLOAT = 'getFloatValue';
const TO_STRING = 'getStringValue';
const TO_DATE = 'getDateValue';
const TO_TMS = 'getTmsValue';
const TO_BOOL = 'getBoolValue';
const ARRAYS = 'arrays';
private $mapping = array();
private $config = array(
'useEmptyValues' => TRUE,
);
function __construct( $mapping, $config = array() )
{
$this->mapping = $mapping;
foreach ( $config as $key => $val ) {
$this->config[$key] = $val;
}
}
/**
* @param array $array
*
* @return array
*/
public function map( $array )
{
$result = array();
foreach ( $this->mapping as $target => $source ) {
$res = $this->prepareData( $array, $target, $source );
if ( $this->isUsable( $res ) ) {
$result[$target] = $res;
}
}
return $result;
}
/**
* @param $data
* @param $target
* @param $source
*
* @return bool|int|mixed|null|string
*/
private function prepareData( $data, $target, $source )
{
// Mapovani pomoci callbacku
if ( is_callable( $source ) ) {
return call_user_func( $source, $data );
// Urceni konkretniho fieldu, ktery se ma pouzit
} elseif ( !is_array( $source ) ) {
return $data[$source];
// Specifikace mapovani
} elseif ( count( $source ) > 1
&& isset( $source[0] )
&& ( $source[0] === self::VALUE
|| $source[0] === self::TO_INT
|| $source[0] === self::TO_FLOAT
|| $source[0] === self::TO_STRING
|| $source[0] === self::TO_DATE
|| $source[0] === self::TO_TMS
|| $source[0] === self::TO_BOOL
|| $source[0] === self::DEFAULT_VAL
)
) {
$format = array_shift( $source );
if ( $format === self::DEFAULT_VAL ) {
return $source[0];
}
$found = TRUE;
$dataPart = $data;
foreach ( $source as $part ) {
if ( isset( $dataPart[$part] ) ) {
$dataPart = $dataPart[$part];
} else {
$found = FALSE;
break;
}
}
if ( $found ) {
return $this->formatVal( $format, $dataPart );
}
// Pozadavek na vnorene pole
} elseif ( !is_numeric( key( $source ) ) ) {
$nestedData = NULL;
if ( key( $source ) === self::ARRAYS ) {
$childRoute = reset( $source );
$dataPart = $data;
$found = TRUE;
foreach ( $childRoute as $part ) {
if ( isset( $dataPart[$part] ) ) {
$dataPart = $dataPart[$part];
} else {
$found = FALSE;
break;
}
}
if ( $found ) {
array_shift( $source );
foreach ( $dataPart as $key => $subData ) {
foreach ( $source as $sourcePartKey => $sourcePartValue ) {
$res = $this->prepareData( $subData, $sourcePartKey, $sourcePartValue );
if ( $this->isUsable( $res ) ) {
$nestedData[$key][$sourcePartKey] = $res;
}
}
}
}
} else {
foreach ( $source as $sourcePartKey => $sourcePartValue ) {
$res = $this->prepareData( $data, $sourcePartKey, $sourcePartValue );
if ( $this->isUsable( $res ) ) {
$nestedData[$sourcePartKey] = $res;
}
}
}
return $nestedData;
// Vice moznosti mapovani jednoho klice
// TODO: nebude fungovat pri funkci na prvnim miste
} elseif ( is_array( $source[0] ) ) {
foreach ( $source as $sourcePartKey => $sourcePartValue ) {
if ( is_numeric( $sourcePartKey ) && is_array( $sourcePartValue ) ) {
$sourcePartKey = $target;
}
$res = $this->prepareData( $data, $sourcePartKey, $sourcePartValue );
if ( $this->isUsable( $res ) ) {
return $res;
}
}
}
return NULL;
}
/**
* @param $format
* @param $value
*
* @return bool|int|string
*/
private function formatVal( $format, $value )
{
if ( $format == self::TO_INT ) return (int)$value;
if ( $format == self::TO_FLOAT ) return (float)$value;
if ( $format == self::TO_STRING ) return (string)$value;
if ( $format == self::TO_DATE ) return date( 'c', $value );
if ( $format == self::TO_TMS ) return strtotime( $value );
if ( $format == self::TO_BOOL ) return (bool)$value;
return $value;
}
/**
* Pokud se nemaji pouzivat prazdne hodnoty,
* ignorovat prazdne stringy a prazdna pole
*
* @param $res
*
* @return bool
*/
private function isUsable( $res )
{
if ( $res === NULL ) {
return FALSE;
}
if ( $this->config['useEmptyValues'] ) {
return TRUE;
}
return $res !== '' && $res !== array();
}
}
<?php
/**
* Created by JetBrains PhpStorm.
* User: Michal
* Date: 29.8.13
* Time: 11:30
* To change this template use File | Settings | File Templates.
*/
namespace SBKS\Parsers\Services\Facebook\Mapping;
use Sbks\Stdlib\ArrayMapper;
class PostFQL2Internal extends ArrayMapper
{
private $FqlTypes = array(
// '11' => 'group created',
'12' => 'event',
'46' => 'status',
// '56' => 'post on wall from another user',
// '66' => 'note created',
'80' => 'link',
'128' => 'video',
'247' => 'photo',
// '237' => 'app story',
// '257' => 'comment created',
// '272' => 'app story',
// '285' => 'checkin to a place',
// '308' => 'post in group',
);
function __construct()
{
$types = $this->FqlTypes;
$mapping = array(
'w' => array( ArrayMapper::TO_STRING, 'w' ),
'id' => array( ArrayMapper::TO_STRING, 'post_id' ),
'page_id' => array( ArrayMapper::TO_STRING, 'source_id' ),
'post_id' => function ( $data ) {
return substr( $data['post_id'], strrpos( $data['post_id'], '_' ) + 1 );
},
'user_id' => array( ArrayMapper::TO_STRING, 'actor_id' ),
'created_time' => array( ArrayMapper::VALUE, 'created_time' ), //tms
'comment_count' => array(
array( ArrayMapper::TO_INT, 'comment_info', 'comment_count' ), // newPost, postUpdate
array( ArrayMapper::DEFAULT_VAL, 0 ),
),
'share_count' => array(
array( ArrayMapper::TO_INT, 'share_count' ), // newPost, postUpdate
array( ArrayMapper::DEFAULT_VAL, 0 ),
),
'like_count' => array(
array( ArrayMapper::TO_INT, 'like_info', 'like_count' ), // newPost, postUpdate
array( ArrayMapper::DEFAULT_VAL, 0 ),
),
'can_comment' => array( ArrayMapper::VALUE, 'comment_info', 'can_comment' ),
'can_like' => array( ArrayMapper::VALUE, 'like_info', 'can_like' ),
'sbks_ea' => array(
'is_admin_post' => function ( $data ) {
return $data['source_id'] == $data['actor_id'];
},
),
'message' => array( ArrayMapper::VALUE, 'message' ),
'message_tags' => array( ArrayMapper::VALUE, 'message_tags' ),
'story' => array( ArrayMapper::VALUE, 'description' ),
'story_tags' => array( ArrayMapper::VALUE, 'description_tags' ),
'name' => array( ArrayMapper::VALUE, 'attachment', 'name' ),
'caption' => array( ArrayMapper::VALUE, 'attachment', 'caption' ),
'type' => function ( $data ) use ( $types ) {
/**
* Magic black box to simulate type returned in GRAPH API
* fixups: album, activity, event
*/
if ( isset( $data['attachment']['fb_object_type'] ) && $data['attachment']['fb_object_type'] ) {
return $data['attachment']['fb_object_type'];
} elseif ( isset( $data['attachment']['media'][0]['type'] ) ) {
return $data['attachment']['media'][0]['type'];
} elseif ( isset( $data['type'] ) && isset( $types[$data['type']] ) ) {
return $types[$data['type']];
} elseif ( isset( $data['attachment']['href'] ) ) {
return 'link';
} elseif ( isset( $data['message'] ) && $data['message'] ) {
return 'status';
} elseif ( isset( $data['description'] ) && $data['description'] ) {
return 'activity';
}
return 'status';
},
'object_id' => array( ArrayMapper::VALUE, 'attachment', 'media', 0, 'photo', 'fbid' ),
'picture' => array( ArrayMapper::VALUE, 'attachment', 'media', 0, 'src' ),
'icon' => array( ArrayMapper::VALUE, 'attachment', 'icon' ),
'link' => array(
array( ArrayMapper::VALUE, 'attachment', 'media', 0, 'href' ),
array( ArrayMapper::VALUE, 'attachment', 'href' ),
),
'permalink' => array( ArrayMapper::VALUE, 'permalink' ),
'app_id' => array( ArrayMapper::TO_STRING, 'app_id' ),
'app_name' => array( ArrayMapper::TO_STRING, 'attribution' ),
);
$config = array(
'useEmptyValues' => FALSE,
);
parent::__construct( $mapping, $config );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment