2023-05-17 11:18:53 +02:00
< ? php
class EventEvolutionLineWidget
{
public $title = 'Evolution of published event count (filterable)' ;
public $render = 'MultiLineChart' ;
public $width = 7 ;
public $height = 6 ;
public $description = 'A linechart of event publishes.' ;
public $cacheLifetime = null ;
public $autoRefreshDelay = false ;
public $params = [
'filter' => 'A list of filters by organisation meta information (nationality, sector, type, name, uuid) to include. (dictionary, prepending values with ! uses them as a negation)' ,
2023-11-15 15:09:53 +01:00
'start_date' => 'Start date, expressed in Y-m-d format (e.g. 2012-10-01)' ,
'cumulative' => '(default: on), should the data counted cumulatively over time' ,
2023-05-17 11:18:53 +02:00
];
private $validFilterKeys = [
'nationality' ,
'sector' ,
'type' ,
'name' ,
'uuid'
];
public $placeholder =
' {
" filter " : {
" sector " : " financial "
},
" start_date " : " 2017-01 " ,
} ' ;
private $Organisation = null ;
private $Event = null ;
private function timeConditions ( $options )
{
if ( ! empty ( $options [ 'start_date' ])) {
$condition = strtotime ( $options [ 'start_date' ]);
} else {
$condition = strtotime ( '2012-10-01' );
}
$datetime = new DateTime ();
$datetime -> setTimestamp ( $condition );
return $datetime -> format ( 'Y-m-d H:i:s' );
}
public function handler ( $user , $options = array ())
{
$this -> Organisation = ClassRegistry :: init ( 'Organisation' );
$this -> Event = ClassRegistry :: init ( 'Event' );
2023-11-15 15:09:53 +01:00
$isCumulative = isset ( $options [ 'cumulative' ]) && empty ( $options [ 'cumulative' ]);
2023-05-17 11:18:53 +02:00
$oparams = [
'conditions' => [
'AND' => [ 'Organisation.local' => ! isset ( $options [ 'local' ]) ? 1 : $options [ 'local' ]]
],
'limit' => 10 ,
'recursive' => - 1
];
$eparams = [];
2024-04-08 16:37:57 +02:00
$filteringOnOrg = false ;
2023-05-17 11:18:53 +02:00
if ( ! empty ( $options [ 'filter' ]) && is_array ( $options [ 'filter' ])) {
foreach ( $this -> validFilterKeys as $filterKey ) {
if ( ! empty ( $options [ 'filter' ][ $filterKey ])) {
2024-04-08 16:37:57 +02:00
$filteringOnOrg = true ;
2023-05-17 11:18:53 +02:00
if ( ! is_array ( $options [ 'filter' ][ $filterKey ])) {
$options [ 'filter' ][ $filterKey ] = [ $options [ 'filter' ][ $filterKey ]];
}
$tempConditionBucket = [];
foreach ( $options [ 'filter' ][ $filterKey ] as $value ) {
if ( $value [ 0 ] === '!' ) {
$tempConditionBucket [ 'Organisation.' . $filterKey . ' NOT IN' ][] = mb_substr ( $value , 1 );
} else {
$tempConditionBucket [ 'Organisation.' . $filterKey . ' IN' ][] = $value ;
}
}
if ( ! empty ( $tempConditionBucket )) {
$oparams [ 'conditions' ][ 'AND' ][] = $tempConditionBucket ;
}
}
}
}
$timeConditions = $this -> timeConditions ( $options );
if ( $timeConditions ) {
$eparams [ 'conditions' ][ 'AND' ][] = [ 'Event.publish_timestamp >=' => strtotime ( $timeConditions )];
}
$org_ids = $this -> Organisation -> find ( 'list' , [
'recursive' => - 1 ,
'conditions' => $oparams [ 'conditions' ],
'fields' => [ 'id' ]
]);
2024-04-08 16:37:57 +02:00
if ( $filteringOnOrg ) {
$eparams [ 'conditions' ][ 'AND' ][ 'Event.orgc_id IN' ] = ! empty ( $org_ids ) ? $org_ids : [ - 1 ];
}
2023-05-17 11:18:53 +02:00
$this -> Event -> virtualFields = [
'published_date' => null
];
$raw = $this -> Event -> find ( 'all' , [
'recursive' => - 1 ,
'conditions' => $eparams [ 'conditions' ],
'fields' => [ 'DATE_FORMAT(FROM_UNIXTIME(Event.publish_timestamp), "%Y-%m") AS date' , 'count(id) AS count' ],
2023-11-15 15:09:53 +01:00
'group' => [ 'MONTH(FROM_UNIXTIME(Event.publish_timestamp)), YEAR(FROM_UNIXTIME(Event.publish_timestamp))' , 'DATE_FORMAT(FROM_UNIXTIME(Event.publish_timestamp), "%Y-%m")' ]
2023-05-17 11:18:53 +02:00
]);
usort ( $raw , [ $this , 'sortByCreationDate' ]);
$raw_padded = [];
$total = 0 ;
$default_start_date = empty ( $raw ) ? '2012-10-01' : ( $raw [ 0 ][ 0 ][ 'date' ] . '-01' );
$start = new DateTime ( empty ( $options [ 'start_date' ]) ? $default_start_date : $options [ 'start_date' ]);
$end = new DateTime ( date ( 'Y-m' ) . '-01' );
$interval = DateInterval :: createFromDateString ( '1 month' );
$period = new DatePeriod ( $start , $interval , $end );
foreach ( $period as $dt ) {
$raw_padded [ $dt -> format ( 'Y-m' ) . '-01' ] = 0 ;
}
foreach ( $raw as $datapoint ) {
$raw_padded [ $datapoint [ 0 ][ 'date' ] . '-01' ] = ( int ) $datapoint [ 0 ][ 'count' ];
}
$total = 0 ;
foreach ( $raw_padded as $date => $count ) {
$total += $count ;
2023-11-15 15:09:53 +01:00
if ( $isCumulative ) {
$raw_padded [ $date ] = $count ;
} else {
$raw_padded [ $date ] = $total ;
}
2023-05-17 11:18:53 +02:00
}
$data = [];
foreach ( $raw_padded as $date => $count ) {
$data [ 'data' ][] = [
'Events' => ( int ) $count ,
'date' => $date
];
}
return $data ;
}
private function sortByCreationDate ( $a , $b ) {
if ( $a [ 0 ][ 'date' ] > $b [ 0 ][ 'date' ]) {
return 1 ;
} else {
return - 1 ;
}
return 0 ;
}
}