public function outputMeta($data) {
        $unserialized = @unserialize($data);
        if ($unserialized !== false) {
            return $this->multiImplode($unserialized, ', ');
        } else {
            return $data;
        }
    }

public
function
outputMeta
(
$
data
)
{
$
unserialized
=
@
unserialize
(
$
data
)
;
if
(
$
unserialized
!==
false
)
{
return
$
this
->
multiImplode
(
$
unserialized
,
', '
)
;
}
else
{
return
$
data
;
}
}

Unserialize and implode arrays
@param  mixed $data data to be formatted
@return string


public function multiImplode($array, $glue) {
    $string = '';

    foreach ($array as $key => $item) {
        if (empty($item)) {
            continue;
        }
        if (is_array($item)) {
            $string .= '<p>' . $this->multiImplode($item, $glue) . '</p>';
        } else {
            $string .= $item . $glue;
        }
    }
    $string = substr($string, 0, 0-strlen($glue));

    return $string;
    }

public function multiImplode ( $ array , $ glue ) { $ string = '' ; foreach ( $ array as $ key => $ item ) { if ( empty ( $ item ) ) { continue ; } if ( is_array ( $ item ) ) { $ string .= '<p>' . $ this -> multiImplode ( $ item , $ glue ) . '</p>' ; } else { $ string .= $ item . $ glue ; } } $ string = substr ( $ string , 0 , 0 - strlen ( $ glue ) ) ; return $ string ; }

Implode arrays into strings
@param  array  $array  array to be imploded
@param  string $glue   used to separate array objects
@return string


public function registerPostType()
    {
        $labels = array(
            'name'                => $this->nameSingular,
            'singular_name'       => $this->nameSingular,
            'add_new'             => sprintf(__('Add new %s', 'event-manager'), $this->nameSingular),
            'add_new_item'        => sprintf(__('Add new %s', 'event-manager'), $this->nameSingular),
            'edit_item'           => sprintf(__('Edit %s', 'event-manager'), $this->nameSingular),
            'new_item'            => sprintf(__('New %s', 'event-manager'), $this->nameSingular),
            'view_item'           => sprintf(__('View %s', 'event-manager'), $this->nameSingular),
            'search_items'        => sprintf(__('Search %s', 'event-manager'), $this->namePlural),
            'not_found'           => sprintf(__('No %s found', 'event-manager'), $this->namePlural),
            'not_found_in_trash'  => sprintf(__('No %s found in trash', 'event-manager'), $this->namePlural),
            'parent_item_colon'   => sprintf(__('Parent %s:', 'event-manager'), $this->nameSingular),
            'menu_name'           => $this->namePlural,
        );

        $this->args['labels'] = $labels;

        register_post_type($this->slug, $this->args);

        return $this->slug;
    }

public
function
registerPostType
(
)
{
$
labels
=
array
(
'name'
=>
$
this
->
nameSingular
,
'singular_name'
=>
$
this
->
nameSingular
,
'add_new'
=>
sprintf
(
__
(
'Add new %s'
,
'event-manager'
)
,
$
this
->
nameSingular
)
,
'add_new_item'
=>
sprintf
(
__
(
'Add new %s'
,
'event-manager'
)
,
$
this
->
nameSingular
)
,
'edit_item'
=>
sprintf
(
__
(
'Edit %s'
,
'event-manager'
)
,
$
this
->
nameSingular
)
,
'new_item'
=>
sprintf
(
__
(
'New %s'
,
'event-manager'
)
,
$
this
->
nameSingular
)
,
'view_item'
=>
sprintf
(
__
(
'View %s'
,
'event-manager'
)
,
$
this
->
nameSingular
)
,
'search_items'
=>
sprintf
(
__
(
'Search %s'
,
'event-manager'
)
,
$
this
->
namePlural
)
,
'not_found'
=>
sprintf
(
__
(
'No %s found'
,
'event-manager'
)
,
$
this
->
namePlural
)
,
'not_found_in_trash'
=>
sprintf
(
__
(
'No %s found in trash'
,
'event-manager'
)
,
$
this
->
namePlural
)
,
'parent_item_colon'
=>
sprintf
(
__
(
'Parent %s:'
,
'event-manager'
)
,
$
this
->
nameSingular
)
,
'menu_name'
=>
$
this
->
namePlural
,
)
;
$
this
->
args
[
'labels'
]
=
$
labels
;
register_post_type
(
$
this
->
slug
,
$
this
->
args
)
;
return
$
this
->
slug
;
}

Registers the post type with WP
@return string Post type slug


public function addTableColumn($key, $title, $sortable = false, $contentCallback = false)
    {
        $this->tableColumns[$key] = $title;

        if ($sortable === true) {
            $this->tableSortableColumns[$key] = $key;
        }

        if ($contentCallback !== false) {
            $this->tableColumnsContentCallback[$key] = $contentCallback;
        }
    }

public function addTableColumn ( $ key , $ title , $ sortable = false , $ contentCallback = false ) { $ this -> tableColumns [ $ key ] = $ title ; if ( $ sortable === true ) { $ this -> tableSortableColumns [ $ key ] = $ key ; } if ( $ contentCallback !== false ) { $ this -> tableColumnsContentCallback [ $ key ] = $ contentCallback ; } }

Adds a column to the admin list table
@param string   $key             Column key
@param string   $title           Column title
@param boolean  $sortable        Sortable or not
@param callback $contentCallback Callback function for displaying
column content (params: $columnKey, $postId)


public function tableColumns($columns)
    {
        if (!empty($this->tableColumns) && is_array($this->tableColumns)) {
            $columns = $this->tableColumns;
        }

        return $columns;
    }

public function tableColumns ( $ columns ) { if ( ! empty ( $ this -> tableColumns ) && is_array ( $ this -> tableColumns ) ) { $ columns = $ this -> tableColumns ; } return $ columns ; }

Set up table columns
@param  array $columns Default columns
@return array          New columns


public function tableSortableColumns($columns)
    {
        if (!empty($this->tableSortableColumns) && is_array($this->tableSortableColumns)) {
            $columns = $this->tableColumns;
        }

        function arraytolower(array $columns, $round = 0)
        {
            return unserialize(strtolower(serialize($columns)));
        }

        return arraytolower($columns);
    }

public function tableSortableColumns ( $ columns ) { if ( ! empty ( $ this -> tableSortableColumns ) && is_array ( $ this -> tableSortableColumns ) ) { $ columns = $ this -> tableColumns ; } function arraytolower ( array $ columns , $ round = 0 ) { return unserialize ( strtolower ( serialize ( $ columns ) ) ) ; } return arraytolower ( $ columns ) ; }

Setup sortable columns
@param  array $columns Default columns
@return array          New columns


public function tableColumnsContent($column, $postId)
    {
        if (!isset($this->tableColumnsContentCallback[$column])) {
            return;
        }

        call_user_func_array($this->tableColumnsContentCallback[$column], array($column, $postId));
    }

public function tableColumnsContent ( $ column , $ postId ) { if ( ! isset ( $ this -> tableColumnsContentCallback [ $ column ] ) ) { return ; } call_user_func_array ( $ this -> tableColumnsContentCallback [ $ column ] , array ( $ column , $ postId ) ) ; }

Set table column content with callback functions
@param  string  $column Key of the column
@param  integer $postId Post id of the current row in table
@return void


public function saveTerms($name, $slug, $taxonomy, $parent = 0)
    {
        $term = get_term_by('slug', $slug, $taxonomy);
        if ($term == false) {
            $new_term = wp_insert_term($name, $taxonomy, array('slug' => $slug, 'parent' => $parent));
            $term_id = $new_term['term_id'];

            $this->activateNewGroup($term_id, $parent);
        } else {
            wp_update_term($term->term_id, $taxonomy, array('name' => $name, 'parent' => $parent));
            $term_id = $term->term_id;
        }

        return $term_id;
    }

public function saveTerms ( $ name , $ slug , $ taxonomy , $ parent = 0 ) { $ term = get_term_by ( 'slug' , $ slug , $ taxonomy ) ; if ( $ term == false ) { $ new_term = wp_insert_term ( $ name , $ taxonomy , array ( 'slug' => $ slug , 'parent' => $ parent ) ) ; $ term_id = $ new_term [ 'term_id' ] ; $ this -> activateNewGroup ( $ term_id , $ parent ) ; } else { wp_update_term ( $ term -> term_id , $ taxonomy , array ( 'name' => $ name , 'parent' => $ parent ) ) ; $ term_id = $ term -> term_id ; } return $ term_id ; }

Save or update taxonomy term
@param  string  $name     name
@param  string  $slug     slug
@param  string  $taxonomy taxonomy
@param  integer $parent   parent id
@return int


public function activateNewGroup($termId, $parentId)
    {
        $selectedGroups = get_option('options_event_filter_group', false);
        if (is_array($selectedGroups) && !empty($selectedGroups)) {
            if (in_array($parentId, $selectedGroups)) {
                // Add children to option array
                $selectedGroups[] = (int) $termId;
                update_field('event_filter_group', $selectedGroups, 'option');
            }
        }
    }

public
function
activateNewGroup
(
$
termId
,
$
parentId
)
{
$
selectedGroups
=
get_option
(
'options_event_filter_group'
,
false
)
;
if
(
is_array
(
$
selectedGroups
)
&&
!
empty
(
$
selectedGroups
)
)
{
if
(
in_array
(
$
parentId
,
$
selectedGroups
)
)
{
// Add children to option array
$
selectedGroups
[
]
=
(
int
)
$
termId
;
update_field
(
'event_filter_group'
,
$
selectedGroups
,
'option'
)
;
}
}
}

Automatically add new terms to Group filter option if the parent is selected
@param  int $termId Term ID
@param  int $parentId Terms parent ID
@return void


public function removeEmpty($metaValue)
    {
        if (is_array($metaValue)) {
            return $metaValue;
        }

        return ($metaValue !== null && $metaValue !== false && $metaValue !== '');
    }

public function removeEmpty ( $ metaValue ) { if ( is_array ( $ metaValue ) ) { return $ metaValue ; } return ( $ metaValue !== null && $ metaValue !== false && $ metaValue !== '' ) ; }

Remove all values that are empty, except the value 0
@param  $metaValue
@return $metaValue

Remove all values that are empty except the value 0


public function getEmptyValues($metaValue)
    {
        if (is_array($metaValue) && empty($metaValue)) {
            return $metaValue;
        }

        return ($metaValue == null || $metaValue == false || $metaValue == '');
    }

public function getEmptyValues ( $ metaValue ) { if ( is_array ( $ metaValue ) && empty ( $ metaValue ) ) { return $ metaValue ; } return ( $ metaValue == null || $ metaValue == false || $ metaValue == '' ) ; }

Get all values that are empty
@param  $metaValue
@return $metaValue


public function removeEmptyMeta($meta, $post_id)
    {
        foreach ($meta as $key => $value) {
            $meta = get_post_meta($post_id, $key, true);
            if ($meta) {
                delete_post_meta($post_id, $key);
            }
        }
    }

public function removeEmptyMeta ( $ meta , $ post_id ) { foreach ( $ meta as $ key => $ value ) { $ meta = get_post_meta ( $ post_id , $ key , true ) ; if ( $ meta ) { delete_post_meta ( $ post_id , $ key ) ; } } }

Delete meta data from db if it's deleted from API
@param  array $meta    empty meta data fields
@param  int   $post_id post object id
@return void

Delete meta data from db if it s deleted from API


public function save()
    {
        $this->beforeSave();

        // Arrays for holding save data
        $post = array();
        $meta = array();
        $post['post_status'] = $this->post_status;

        // Get the default class variables and set it's keys to forbiddenKeys
        $defaultData = get_class_vars(get_class($this));
        $forbiddenKeys = array_keys($defaultData);

        $data = array_filter(get_object_vars($this), function ($item) use ($forbiddenKeys) {
            return !in_array($item, $forbiddenKeys);
        }, ARRAY_FILTER_USE_KEY);

        // If data key is allowed post field add to $post else add to $meta
        foreach ($data as $key => $value) {
            if (in_array($key, $this->allowedPostFields)) {
                $post[$key] = $value;
                continue;
            }

            $meta[$key] = $value;
        }

        // Save empty meta to array
        $empty_meta_values = array_filter($meta, array($this, 'getEmptyValues'));

        // Do not include null values in meta
        $meta = array_filter($meta, array($this, 'removeEmpty'));

        $post['post_type'] = $this->post_type;
        $post['meta_input'] = $meta;

        // Check if duplicate by matching "_event_manager_id" meta value
        if (isset($meta['_event_manager_id'])) {
            $duplicate = self::get(
                1,
                array(
                    'relation' => 'AND',
                    array(
                        'key' => '_event_manager_id',
                        'value' => $meta['_event_manager_id'],
                        'compare' => '='
                    )
                ),
                $this->post_type
            );
        }

        // Update if duplicate
        if (isset($duplicate->ID)) {
            //Check if event needs to be updated
            if (get_post_meta($duplicate->ID, 'last_update', true) != $meta['last_update']) {
                $post['ID'] = $duplicate->ID;
                $this->ID = wp_update_post($post);
                $isDuplicate = true;
            } else {
                return false;
            }
        } else {
            // Create if not duplicate
            $this->ID = wp_insert_post($post, true);
        }

        // Remove empty meta values from db
        $this->removeEmptyMeta($empty_meta_values, $this->ID);

        return $this->afterSave();
    }

Saves the event and it's data
@return integer The inserted/updated post id


private function attachmentExists($src)
    {
        global $wpdb;
        $query = "SELECT ID FROM {$wpdb->posts} WHERE guid = '$src'";
        $id = $wpdb->get_var($query);

        if (!empty($id) && $id > 0) {
            return $id;
        }

        return false;
    }

Checks if a attachment src already exists in media library
@param  string $src Media url
@return mixed


public function submitFormCallback($atts = [], $content = null, $tag = '')
    {
        // Normalize attribute keys, lowercase
        $atts = array_change_key_case((array)$atts, CASE_LOWER);

        // Override default attributes with user attributes
        $data = shortcode_atts([
            'user_groups' => '',
        ], $atts, $tag);

        $data = array_merge($data, \EventManagerIntegration\Helper\SubmitEvent::geFields());

        return \EventManagerIntegration\Helper\RenderBlade::blade(
            'formfields',
             $data,
            EVENTMANAGERINTEGRATION_PATH . 'source/php/Module/SubmitForm/views/'
        );
    }

Return form markup
@param array  $atts    Attributes
@param string $content Content
@param string $tag     Shortcode name
@return string Form markup


public function addEventDateArgsToPermalinks($permalink, $post, $leavename)
    {
        if (!isset($post->start_date) || $post->post_type != $this->eventPostType) {
            return $permalink;
        }

        return esc_url(add_query_arg('date', preg_replace('/\D/', '', $post->start_date), $permalink));
    }

public function addEventDateArgsToPermalinks ( $ permalink , $ post , $ leavename ) { if ( ! isset ( $ post -> start_date ) || $ post -> post_type != $ this -> eventPostType ) { return $ permalink ; } return esc_url ( add_query_arg ( 'date' , preg_replace ( '/\D/' , '' , $ post -> start_date ) , $ permalink ) ) ; }

Add date arguments to event permalink URL


public function eventFilterWhere($where)
    {
        $from = null;
        $to = null;

        if (isset($_GET['from']) && !empty($_GET['from'])) {
            $from = sanitize_text_field($_GET['from']);
        }

        if (isset($_GET['to']) && !empty($_GET['to'])) {
            $to = date('Y-m-d', strtotime("+1 day", strtotime(sanitize_text_field($_GET['to']))));
        }

        if (!is_null($from) && !is_null($to)) {
            // USE BETWEEN ON START DATE
            $where = str_replace(
                "{$this->db->posts}.post_date >= '{$from}'",
                "{$this->dbTable}.start_date BETWEEN CAST('{$from}' AS DATE) AND CAST('{$to}' AS DATE)",
                $where
            );
            $where = str_replace(
                "AND {$this->db->posts}.post_date <= '{$to}'",
                "",
                $where
            );
        } elseif (!is_null($from) || !is_null($to)) {
            // USE FROM OR TO
            $where = str_replace("{$this->db->posts}.post_date >=", "{$this->dbTable}.start_date >=", $where);
            $where = str_replace("{$this->db->posts}.post_date <=", "{$this->dbTable}.end_date <=", $where);
        }

        return $where;
    }

Add where statements
@param  string $where current where statement
@return string        updated statement


public static function singleEventDate()
    {
        global $post;

        $singleOccasion = array();
        $get_date = (!empty(get_query_var('date'))) ? get_query_var('date') : false;
        $occasions = QueryEvents::getEventOccasions($post->ID);

        //Get nearest occasions from time if no date arg
        if (!$get_date) {
            $get_date = self::getNextOccasionDate($occasions);
        }

        if (is_array($occasions) && count($occasions) == 1) {
            $singleOccasion = (array)$occasions[0];
            $singleOccasion['formatted'] = \EventManagerIntegration\App::formatEventDate($singleOccasion['start_date'], $singleOccasion['end_date']);
            $singleOccasion['date_parts'] = self::dateParts($singleOccasion['start_date']);
        } elseif (is_array($occasions) && $get_date != false) {
            foreach ($occasions as $occasion) {
                $occasion = (array)$occasion;
                $event_date = preg_replace('/\D/', '', $occasion['start_date']);
                if ($get_date == $event_date) {
                    $singleOccasion = $occasion;
                    $singleOccasion['formatted'] = \EventManagerIntegration\App::formatEventDate($occasion['start_date'], $occasion['end_date']);
                    $singleOccasion['date_parts'] = self::dateParts($occasion['start_date']);
                }
            }
        }

        return $singleOccasion;
    }


public static function getNextOccasionDate($occasions, $dateFormat = 'YmdHis')
    {
        if (!is_array($occasions) || empty($occasions)) {
            return false;
        }

        $startDates = array();
        foreach ($occasions as $occasion) {
            //Skip if event has ended
            if (time() > strtotime($occasion->end_date) || !isset($occasion->start_date) || !isset($occasion->end_date)) {
                continue;
            }

            $startDates[] = strtotime($occasion->start_date);
        }

        return date($dateFormat, self::getClosest(time(), $startDates));
    }

public
static
function
getNextOccasionDate
(
$
occasions
,
$
dateFormat
=
'YmdHis'
)
{
if
(
!
is_array
(
$
occasions
)
||
empty
(
$
occasions
)
)
{
return
false
;
}
$
startDates
=
array
(
)
;
foreach
(
$
occasions
as
$
occasion
)
{
//Skip if event has ended
if
(
time
(
)
>
strtotime
(
$
occasion
->
end_date
)
||
!
isset
(
$
occasion
->
start_date
)
||
!
isset
(
$
occasion
->
end_date
)
)
{
continue
;
}
$
startDates
[
]
=
strtotime
(
$
occasion
->
start_date
)
;
}
return
date
(
$
dateFormat
,
self
::
getClosest
(
time
(
)
,
$
startDates
)
)
;
}

Get next event occasion date in time
@param  array  $occasions  All occasions of an event
@param  string $dateFormat event start date
@return string/boolean


public static function getClosest($search, $arr)
    {
        $closest = null;
        foreach ($arr as $item) {
            if ($closest === null || abs($search - $closest) > abs($item - $search)) {
                $closest = $item;
            }
        }
        return $closest;
    }

public static function getClosest ( $ search , $ arr ) { $ closest = null ; foreach ( $ arr as $ item ) { if ( $ closest === null || abs ( $ search - $ closest ) > abs ( $ item - $ search ) ) { $ closest = $ item ; } } return $ closest ; }

Get the closest value from array of values
@param  string $search Value to compare
@param  array  $arr    event start date
@return string/boolean


public static function dateParts($start_date)
    {
        $start = date('Y-m-d H:i:s', strtotime($start_date));
        $date = array(
            'date' => mysql2date('j', $start, true),
            'month' => mysql2date('F', $start, true),
            'month_short' => substr(mysql2date('F', $start, true), 0, 3),
            'year' => mysql2date('Y', $start, true),
            'time' => mysql2date('H:i', $start, true),
        );

        return $date;
    }

public
static
function
dateParts
(
$
start_date
)
{
$
start
=
date
(
'Y-m-d H:i:s'
,
strtotime
(
$
start_date
)
)
;
$
date
=
array
(
'date'
=>
mysql2date
(
'j'
,
$
start
,
true
)
,
'month'
=>
mysql2date
(
'F'
,
$
start
,
true
)
,
'month_short'
=>
substr
(
mysql2date
(
'F'
,
$
start
,
true
)
,
0
,
3
)
,
'year'
=>
mysql2date
(
'Y'
,
$
start
,
true
)
,
'time'
=>
mysql2date
(
'H:i'
,
$
start
,
true
)
,
)
;
return
$
date
;
}

Get date parts as array
@param  string $start_date event start date
@return array              date values


public function saveDrawPoints()
    {
        if (!isset($_POST['coordinates']) && !empty($_POST['coordinates'])) {
            wp_send_json_error("Missing coordinates");
        }

        $points = $_POST['coordinates'];
        // Convert coordinates to float
        foreach ($points as &$point) {
            $point = array_map('floatval', $point);
        }
        update_option('event_import_area', $points);
        wp_send_json_success($points);
    }

public
function
saveDrawPoints
(
)
{
if
(
!
isset
(
$
_POST
[
'coordinates'
]
)
&&
!
empty
(
$
_POST
[
'coordinates'
]
)
)
{
wp_send_json_error
(
"Missing coordinates"
)
;
}
$
points
=
$
_POST
[
'coordinates'
]
;
// Convert coordinates to float
foreach
(
$
points
as
&
$
point
)
{
$
point
=
array_map
(
'floatval'
,
$
point
)
;
}
update_option
(
'event_import_area'
,
$
points
)
;
wp_send_json_success
(
$
points
)
;
}


public function enqueueAdmin()
    {
        // Styles
        wp_register_style('event-integration-admin',
            EVENTMANAGERINTEGRATION_URL . '/dist/' . Helper\CacheBust::name('css/event-manager-integration-admin.css'));
        wp_enqueue_style('event-integration-admin');

        // Scripts
        wp_register_script('event-integration-admin', EVENTMANAGERINTEGRATION_URL . '/dist/' . Helper\CacheBust::name('js/event-integration-admin.js'), true);
        wp_localize_script('event-integration-admin', 'eventintegration', array(
            'ajaxurl' => admin_url('admin-ajax.php')
        ));
        wp_localize_script('event-integration-admin', 'eventIntegrationAdmin', array(
            'loading' => __("Loading", 'event-integration'),
            'options' => array(
                'areaCoordinates' => get_option('event_import_area') ? get_option('event_import_area') : null
            )
        ));
        wp_enqueue_script('event-integration-admin');

        // Re-enqueue Google Maps JS Api with additional libraries: Places, Drawing
        if (isset($_GET['page']) && $_GET['page'] === 'event-options' && $googleApiKey = get_field('google_geocode_key', 'option')) {
            wp_enqueue_script('google-maps-api', '//maps.googleapis.com/maps/api/js?key=' . $googleApiKey . '&libraries=places,drawing', array(), '', true);
        }
    }

Enqueue required styles and scripts for admin ui
@return void


public function enqueueFront()
    {
        // Styles
        wp_enqueue_style(
            'event-integration',
            EVENTMANAGERINTEGRATION_URL . '/dist/' . Helper\CacheBust::name('css/event-manager-integration.css'));

        // Scripts

        // Google Maps JS Api
        if ($googleApiKey = get_field('google_geocode_key', 'option')) {
            wp_enqueue_script('google-maps-api', '//maps.googleapis.com/maps/api/js?key=' . $googleApiKey . '', array(), '', true);
        }

        wp_register_script('auto-complete', EVENTMANAGERINTEGRATION_URL . '/source/js/vendor/auto-complete/auto-complete.min.js', 'jquery', false, true);
        wp_enqueue_script('auto-complete');

        wp_register_script('event-integration', EVENTMANAGERINTEGRATION_URL . '/dist/' . Helper\CacheBust::name('js/event-integration-front.js'), 'jquery', false, true);
        wp_localize_script('event-integration', 'eventintegration', array(
            'ajaxurl' => admin_url('admin-ajax.php'),
            'apiurl' => get_field('event_api_url', 'option'),
        ));
        wp_localize_script('event-integration', 'eventIntegrationFront', array(
            'event_pagination_error' => __("Something went wrong, please try again later.", 'event-integration'),
            'email_not_matching' => __("The email addresses does not match.", 'event-integration'),
            'must_upload_image' => __("You must upload an image.", 'event-integration'),
        ));
        wp_enqueue_script('event-integration');
    }

Enqueue required styles and scripts on front views
@return void


public static function formatShortDate($start_date)
    {
        $start = date('Y-m-d H:i:s', strtotime($start_date));
        $today = (date('Ymd') == date('Ymd', strtotime($start_date))) ? true : false;
        $date = array(
            'today' => $today,
            'date' => mysql2date('j', $start, true),
            'month' => substr(mysql2date('F', $start, true), 0, 3),
            'time' => mysql2date('H:i', $start, true),
        );

        return $date;
    }

public
static
function
formatShortDate
(
$
start_date
)
{
$
start
=
date
(
'Y-m-d H:i:s'
,
strtotime
(
$
start_date
)
)
;
$
today
=
(
date
(
'Ymd'
)
==
date
(
'Ymd'
,
strtotime
(
$
start_date
)
)
)
true
:
false
;
$
date
=
array
(
'today'
=>
$
today
,
'date'
=>
mysql2date
(
'j'
,
$
start
,
true
)
,
'month'
=>
substr
(
mysql2date
(
'F'
,
$
start
,
true
)
,
0
,
3
)
,
'time'
=>
mysql2date
(
'H:i'
,
$
start
,
true
)
,
)
;
return
$
date
;
}

Format short start date
@param  string $start_date occasion start date
@return array              date values


public function importEventsCron()
    {
        if (get_field('event_daily_import', 'option') == true && $apiUrl = Helper\ApiUrl::buildApiUrl()) {
            new Parser\EventManagerApi($apiUrl);
        }
    }

public function importEventsCron ( ) { if ( get_field ( 'event_daily_import' , 'option' ) == true && $ apiUrl = Helper \ ApiUrl :: buildApiUrl ( ) ) { new Parser \ EventManagerApi ( $ apiUrl ) ; } }


public static function importPublishingGroups()
    {
        $api_url = get_field('event_api_url', 'option');
        if ($api_url) {
            $api_url = rtrim($api_url, '/') . '/user_groups';
            new Parser\EventManagerGroups($api_url);
        }
    }

public static function importPublishingGroups ( ) { $ api_url = get_field ( 'event_api_url' , 'option' ) ; if ( $ api_url ) { $ api_url = rtrim ( $ api_url , '/' ) . '/user_groups' ; new Parser \ EventManagerGroups ( $ api_url ) ; } }

Import publishing groups from Event Manager API
@return void


public static function checkDatabaseTable()
    {
        global $wpdb;
        $table_name = $wpdb->prefix . 'integrate_occasions';
        if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
            self::databaseCreation();
        }

        return;
    }

public
static
function
checkDatabaseTable
(
)
{
global
$
wpdb
;
$
table_name
=
$
wpdb
->
prefix
.
'integrate_occasions'
;
if
(
$
wpdb
->
get_var
(
"SHOW TABLES LIKE '$table_name'"
)
!=
$
table_name
)
{
self
::
databaseCreation
(
)
;
}
return
;
}

Create database table if not exist
@return void


public static function databaseCreation()
    {
        global $wpdb;
        global $event_db_version;
        $table_name = $wpdb->prefix . 'integrate_occasions';
        $charset_collate = $wpdb->get_charset_collate();
        $sql = "CREATE TABLE $table_name (
        ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
        event_id BIGINT(20) UNSIGNED NOT NULL,
        start_date DATETIME NOT NULL,
        end_date DATETIME NOT NULL,
        door_time DATETIME DEFAULT NULL,
        status VARCHAR(50) DEFAULT NULL,
        exception_information VARCHAR(400) DEFAULT NULL,
        content_mode VARCHAR(50) DEFAULT NULL,
        content LONGTEXT DEFAULT NULL,
        PRIMARY KEY  (ID)
        ) $charset_collate;";
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql);
        add_option('event_db_version', $event_db_version);
    }

Creates event occasion database table on plugin activation


public function checkIfEventExists($event_manager_id)
    {
        global $wpdb;
        $results = $wpdb->get_results(
            "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_event_manager_id' AND meta_value = $event_manager_id LIMIT 1",
            ARRAY_A
        );
        if (!empty($results[0]['post_id'])) {
            return $results[0]['post_id'];
        } else {
            return false;
        }
    }

Check if event already exist and return it's id
@param  [type] $event_manager_id [description]
@return [type]                   [description]

Check if event already exist and return it s id


public static function requestApi($url)
    {
        // Dont verify ssl cert in dev mode
        $args = array(
            'timeout' => 120,
            'sslverify' => defined('DEV_MODE') && DEV_MODE == true ? false : true,
            'headers' => array(
                'ClientSolution' => 'WordPress Integration '.EVENTMANAGERINTEGRATION_ID,
                'PhpVersion' => phpversion(),
                'referrer' => get_home_url(),
            ),
        );
        $request = wp_remote_get($url, $args);
        $responseCode = wp_remote_retrieve_response_code($request);
        $body = wp_remote_retrieve_body($request);

        // Decode JSON
        $body = json_decode($body, true);

        // Return null if the request was successful but result is empty
        if (isset($body['code']) && $body['code'] === 'empty_result') {
            return null;
        }

        // Return WP_Error if response code is not 200 OK or result is empty
        if ($responseCode !== 200 || !is_array($body) || empty($body)) {
            return new \WP_Error('error', __('API request failed.', 'event-integration'));
        }

        return $body;
    }

Request to Api
@param  string $url Request Url
@return array|bool|\WP_Error


public static function getEventOccasions($post_id, $custom = false)
    {
        global $wpdb;
        $db_table = $wpdb->prefix."integrate_occasions";

        $query = "
        SELECT      *
        FROM        $db_table
        WHERE       $db_table.event_id = %d
        ";
        $query .= ($custom == true) ? "AND $db_table.content_mode = 'custom'" : '';
        $query .= "ORDER BY $db_table.start_date ASC";

        $completeQuery = $wpdb->prepare($query, $post_id);
        $occasions = $wpdb->get_results($completeQuery);

        return $occasions;
    }

Get event occasions
@param  int $post_id post id
@param  bool $custom True to get occasions with custom content
@return array        object with occasions


public static function getEventMeta($post_id)
    {
        global $wpdb;

        $query = "
        SELECT      *
        FROM        $wpdb->postmeta
        WHERE       $wpdb->postmeta.post_id = %s
        ";

        $completeQuery = $wpdb->prepare($query, $post_id);
        $event_meta = $wpdb->get_results($completeQuery);

        return $event_meta;
    }

Get event meta data
@param  int $post_id post id
@return array        array with occasions


public static function stringLimiter($string, $limit)
    {
        if (strlen($string) <= $limit || $limit == -1) {
            return $string;
        } else {
            $y = mb_substr($string, 0, $limit, "utf-8").'...';

            return $y;
        }
    }

public static function stringLimiter ( $ string , $ limit ) { if ( strlen ( $ string ) <= $ limit || $ limit == - 1 ) { return $ string ; } else { $ y = mb_substr ( $ string , 0 , $ limit , "utf-8" ) . '...' ; return $ y ; } }

Limits event description
@param  string $string content string to limit
@param  int    $limit  maximum number of letters
@return string


public static function getNearbyLocations($lat, $lng, $distance = 0)
    {
        global $wpdb;

        // Radius of the earth in kilometers.
        $earth_radius = 6371;
        $sql = $wpdb->prepare(
            "
                SELECT DISTINCT
                    latitude.post_id,
                    post.post_title,
                    latitude.meta_value as lat,
                    longitude.meta_value as lng,
                    (%s * ACOS(
                        COS(RADIANS( %s )) * COS(RADIANS(latitude.meta_value)) * COS(
                        RADIANS(longitude.meta_value) - RADIANS( %s )
                        ) + SIN(RADIANS( %s )) * SIN(RADIANS(latitude.meta_value))
                    )) AS distance
                    FROM $wpdb->posts post
                    INNER JOIN $wpdb->postmeta latitude ON post.ID = latitude.post_id
                    INNER JOIN $wpdb->postmeta longitude ON post.ID = longitude.post_id
                    AND post.post_type   = 'event'
                    AND post.post_status = 'publish'
                    AND latitude.meta_key = 'latitude'
                    AND longitude.meta_key = 'longitude'
                    HAVING distance <= %s
                    ORDER BY distance ASC",
            $earth_radius,
            $lat,
            $lng,
            $lat,
            $distance
        );

        $nearby_locations = $wpdb->get_results($sql, ARRAY_A);

        if ($nearby_locations) {
            return $nearby_locations;
        }
    }

Get event that occurs nearby a locations and within given distance
@param  string       $lat       latitude
@param  string       $lng       longitude
@param  int/float    $distance  radius distance in km
@return array with locations


public function update($new_instance, $old_instance)
    {
        $instance = array();
        $instance['title'] = (! empty($new_instance['title'])) ? strip_tags($new_instance['title']) : '';
        $instance['limit'] = absint($new_instance['limit']);
        $instance['days_ahead'] = absint($new_instance['days_ahead']);
        $instance['show_date'] = isset( $new_instance['show_date'] ) ? (bool) $new_instance['show_date'] : false;
        $instance['show_location'] = isset( $new_instance['show_location'] ) ? (bool) $new_instance['show_location'] : false;
        $instance['show_image'] = isset( $new_instance['show_image'] ) ? (bool) $new_instance['show_image'] : false;
        $instance['show_content'] = isset( $new_instance['show_content'] ) ? (bool) $new_instance['show_content'] : false;
        $instance['content_limit'] = $new_instance['content_limit'];
        return $instance;
    }

public function update ( $ new_instance , $ old_instance ) { $ instance = array ( ) ; $ instance [ 'title' ] = ( ! empty ( $ new_instance [ 'title' ] ) ) ? strip_tags ( $ new_instance [ 'title' ] ) : '' ; $ instance [ 'limit' ] = absint ( $ new_instance [ 'limit' ] ) ; $ instance [ 'days_ahead' ] = absint ( $ new_instance [ 'days_ahead' ] ) ; $ instance [ 'show_date' ] = isset ( $ new_instance [ 'show_date' ] ) ? ( bool ) $ new_instance [ 'show_date' ] : false ; $ instance [ 'show_location' ] = isset ( $ new_instance [ 'show_location' ] ) ? ( bool ) $ new_instance [ 'show_location' ] : false ; $ instance [ 'show_image' ] = isset ( $ new_instance [ 'show_image' ] ) ? ( bool ) $ new_instance [ 'show_image' ] : false ; $ instance [ 'show_content' ] = isset ( $ new_instance [ 'show_content' ] ) ? ( bool ) $ new_instance [ 'show_content' ] : false ; $ instance [ 'content_limit' ] = $ new_instance [ 'content_limit' ] ; return $ instance ; }

Handles updating the settings for the current Display Events widget instance.

@param array $new_instance Values just sent to be saved.
@param array $old_instance Previously saved values from database.

@return array Updated safe values to be saved.

Handles updating the settings for the current Display Events widget instance .


public function ajaxPagination()
    {
        echo \EventManagerIntegration\Helper\RenderBlade::blade(
            'partials/list',
            $this->data(),
            $this->templateDir
        );

        wp_die();
    }

public function ajaxPagination ( ) { echo \ EventManagerIntegration \ Helper \ RenderBlade :: blade ( 'partials/list' , $ this -> data ( ) , $ this -> templateDir ) ; wp_die ( ) ; }


public function getEvents($module_id, $page = 1, $useLimit = true)
    {
        $fields = json_decode(json_encode(get_fields($module_id)));
        $display_limit = ($useLimit == true && isset($fields->mod_event_limit)) ? $fields->mod_event_limit : -1;
        $days_ahead = isset($fields->mod_event_interval) ? $fields->mod_event_interval : 0;

        // Set start and end date
        $start_date = date('Y-m-d H:i:s', strtotime("today midnight"));
        $end_date = date('Y-m-d H:i:s', strtotime("tomorrow midnight +$days_ahead days") - 1);

        // Save categories, groups and tags IDs as arrays
        $categories = $this->getModuleCategories($module_id);
        $tags = $this->getModuleTags($module_id);
        $groups = $this->getModuleGroups($module_id);

        $taxonomies = (!empty($taxonomies)) ? $taxonomies : null;
        $params = array(
            'start_date' => $start_date,
            'end_date' => $end_date,
            'display_limit' => $display_limit,
            'categories' => $categories,
            'tags' => $tags,
            'groups' => $groups,
            'location' => (isset($fields->mod_event_geographic)) ? $fields->mod_event_geographic : null,
            'distance' => (isset($fields->mod_event_distance)) ? $fields->mod_event_distance : null,
            'lang' => $this->lang,
        );

        $events = \EventManagerIntegration\Helper\QueryEvents::getEventsByInterval($params, $page);

        return $events;
    }

Get included Events
@param  int  $module_id Module ID
@param  int  $page      Pagination page number
@param  bool $useLimit  True = limit by setting, false = get all
@return array           Array with event objects


public function getModuleCategories($moduleId): array
    {
        $categories = array();
        $showAllCategories = get_field('mod_event_categories_show', $moduleId);

        $moduleCategories = get_field('mod_event_categories_list', $moduleId);
        if ($showAllCategories === false && !empty($moduleCategories) && is_array($moduleCategories)) {
            $categories = $moduleCategories;
        }

        return $categories;
    }

public function getModuleCategories ( $ moduleId ) : array { $ categories = array ( ) ; $ showAllCategories = get_field ( 'mod_event_categories_show' , $ moduleId ) ; $ moduleCategories = get_field ( 'mod_event_categories_list' , $ moduleId ) ; if ( $ showAllCategories === false && ! empty ( $ moduleCategories ) && is_array ( $ moduleCategories ) ) { $ categories = $ moduleCategories ; } return $ categories ; }

Return categories filter
@param int $moduleId The module ID
@return array|null


public function getFilterableCategories($moduleId): array
    {
        $categories = array();
        $showAllCategories = get_field('mod_event_categories_show', $moduleId);

        $moduleCategories = get_field('mod_event_categories_list', $moduleId);
        if ($showAllCategories === false && !empty($moduleCategories) && is_array($moduleCategories)) {
            $categories = $moduleCategories;
            foreach ($categories as $key => &$category) {
                $category = get_term($category, 'event_categories');
                // If category is missing, remove it from the list
                if (!$category) {
                    unset($categories[$key]);
                }
            }
        } else {
            $categories = get_terms(
                'event_categories',
                array(
                    'hide_empty' => false,
                )
            );
        }

        $categories = \EventManagerIntegration\Helper\Translations::filterTermsByLanguage($categories);

        foreach ($categories as &$category) {
            $category = array(
                'id' => $category->term_id,
                'title' => $category->name,
                'checked' => false,
            );
        }

        return $categories;
    }

Return categories available for filtering
@param int $moduleId The module ID
@return array|null


public function getModuleGroups($moduleId): array
    {
        $groups = array();
        $showAllGroups = get_field('mod_event_groups_show', $moduleId);

        $moduleGroups = get_field('mod_event_groups_list', $moduleId);
        if ($showAllGroups === false && !empty($moduleGroups) && is_array($moduleGroups)) {
            $groups = $moduleGroups;
        }

        return $groups;
    }

public function getModuleGroups ( $ moduleId ) : array { $ groups = array ( ) ; $ showAllGroups = get_field ( 'mod_event_groups_show' , $ moduleId ) ; $ moduleGroups = get_field ( 'mod_event_groups_list' , $ moduleId ) ; if ( $ showAllGroups === false && ! empty ( $ moduleGroups ) && is_array ( $ moduleGroups ) ) { $ groups = $ moduleGroups ; } return $ groups ; }

Return groups filter
@param int $moduleId The module ID
@return array|null


public function getModuleTags($moduleId): array
    {
        $tags = array();
        $showAllTags = get_field('mod_event_tags_show', $moduleId);

        $moduleTags = get_field('mod_event_tags_list', $moduleId);
        if ($showAllTags === false && !empty($moduleTags) && is_array($moduleTags)) {
            $tags = $moduleTags;
        }

        return $tags;
    }

public function getModuleTags ( $ moduleId ) : array { $ tags = array ( ) ; $ showAllTags = get_field ( 'mod_event_tags_show' , $ moduleId ) ; $ moduleTags = get_field ( 'mod_event_tags_list' , $ moduleId ) ; if ( $ showAllTags === false && ! empty ( $ moduleTags ) && is_array ( $ moduleTags ) ) { $ tags = $ moduleTags ; } return $ tags ; }

Return tags filter
@param int $moduleId The module ID
@return array|null


public function getAgeFilterRange($moduleId): array
    {
        $years = array();
        $from = (int)get_field('mod_event_filter_age_range_from', $moduleId);
        $to = (int)get_field('mod_event_filter_age_range_to', $moduleId);

        if ($from < $to) {
            foreach (range($from, $to) as $value) {
                $years[] = array(
                    'value' => $value,
                    'checked' => false,
                );
            }
        }

        return $years;
    }

public function getAgeFilterRange ( $ moduleId ) : array { $ years = array ( ) ; $ from = ( int ) get_field ( 'mod_event_filter_age_range_from' , $ moduleId ) ; $ to = ( int ) get_field ( 'mod_event_filter_age_range_to' , $ moduleId ) ; if ( $ from < $ to ) { foreach ( range ( $ from , $ to ) as $ value ) { $ years [ ] = array ( 'value' => $ value , 'checked' => false , ) ; } } return $ years ; }

Return list with filterable ages
@param int $moduleId The module ID
@return array


public function oauthRequestCallback() {
        ?>

<?php _e('API authentication', 'event-integration' ); ?>

        <?php if (get_option('_event_authorized') == false): ?>

<?php _e('Request authorization', 'event-integration'); ?>

<?php _e('To publish events from this client to the API you need authentication. Enter your given client keys and send request.', 'event-integration' ); ?>

            <form method="post" id="oauth-request" action="/wp-admin/admin-ajax.php">

                            <?php _e( 'Client key', 'event-integration' )?>

                            <input type="text" class="client-key" name="client-key" id="client-key" value="<?php echo esc_attr(get_option('_event_client')); ?>" />

                            <?php _e( 'Client secret', 'event-integration' )?>

                            <input type="text" class="client-secret" name="client-secret" id="client-secret" value="<?php echo esc_attr(get_option('_event_secret')); ?>" />

                    <input name='submit' type='submit' id='oauth-request-submit' class='button-primary' value='<?php _e('Send request', 'event-integration') ?>' />

            </form>

<?php _e('Enter verification token', 'event-integration'); ?>

            <form method="post" id="oauth-access" action="/wp-admin/admin-ajax.php">

                            <?php _e('Verification token', 'event-integration'); ?>

                            <input type="text" class="verification-token" name="verification-token" id="verification-token"/>

                    <input name='submit' type='submit' class='button-primary' value='<?php _e('Grant access', 'event-integration');  ?>' />

            </form>

        <?php endif ?>

        <?php if (get_option('_event_authorized') == true): ?>

<?php _e('Authorized', 'event-integration' ); ?>

<?php _e('This client is authorized to submit events to the API.', 'event-integration' ); ?>

            <form method="post" id="oauth-authorized" action="/wp-admin/admin-ajax.php">

                            <?php _e( 'Client key', 'event-integration' ); ?>

                                <?php echo get_option('_event_client'); ?>

                <input name='submit' type='submit' class='button' value='<?php _e('Remove client', 'event-integration') ?>' />

            </form>

        <?php endif ?>
    <?php
    }

?>" />
                        </td>
                    </tr>
                </table>
                <p class="submit">
                    <input name='submit' type='submit' id='oauth-request-submit' class='button-primary' value='<?php

?>
                            </code>
                        </td>
                    </tr>
                </table>
            <p class="submit">
                <input name='submit' type='submit' class='button' value='<?php

Callback for the submenu page. Forms to complete authorization.

Callback for the submenu page . Forms to complete authorization .


public function sanitizeInput(&$array) {
        foreach ($array as $key => &$value) {
            if(!is_array($value)) {
                if ($key == 'content') {
                    $value = sanitize_textarea_field($value);
                } else {
                    $value = sanitize_text_field($value);
                }
            } else {
                $this->sanitizeInput($value);
            }
        }

        return $array;
    }

public function sanitizeInput ( & $ array ) { foreach ( $ array as $ key => & $ value ) { if ( ! is_array ( $ value ) ) { if ( $ key == 'content' ) { $ value = sanitize_textarea_field ( $ value ) ; } else { $ value = sanitize_text_field ( $ value ) ; } } else { $ this -> sanitizeInput ( $ value ) ; } } return $ array ; }

Sanitize array with input data
@param  array &$array Defualt array
@return array         Sanitized array


public function singleViewData($data)
    {
        // Bail if not event
        if (get_post_type() !== self::$postTypeSlug || is_archive()) {
            return $data;
        }

        global $post;

        // Gather event data
        $eventData = array();
        $eventData['occasion'] = \EventManagerIntegration\Helper\SingleEventData::singleEventDate();
        $eventData['cancelled'] = !empty($eventData['occasion']['status']) && $eventData['occasion']['status'] === 'cancelled' ? __('Cancelled', 'event-integration') : null;
        $eventData['rescheduled'] = !empty($eventData['occasion']['status']) && $eventData['occasion']['status'] === 'rescheduled' ? __('Rescheduled', 'event-integration') : null;
        $eventData['exception_information'] = !empty($eventData['occasion']['exception_information']) ? $eventData['occasion']['exception_information'] : null;

        if (function_exists('municipio_get_thumbnail_source')) {
            $eventData['image_src'] = municipio_get_thumbnail_source(
                null,
                array(750, 750),
                '16:9'
            );
        } else {
            $thumbnailId = get_post_thumbnail_id($post->ID);
            $image = wp_get_attachment_image_src($thumbnailId, 'medium');
            $eventData['image_src'] = $image[0] ?? null;
        }

        $location = get_post_meta($post->ID, 'location', true);
        $eventData['location'] = !empty($location['title']) ? $location : null;

        $bookingLink = get_post_meta($post->ID, 'booking_link', true);
        $eventData['booking_link'] = !empty($bookingLink) ? $bookingLink : null;

        $ageGroupFrom = get_post_meta($post->ID, 'age_group_from', true);
        $ageGroupTo = get_post_meta($post->ID, 'age_group_to', true);

        $eventData['age_group'] = null;
        if (!empty($ageGroupFrom) && !empty($ageGroupTo)) {
            $eventData['age_group'] = sprintf('%s-%s %s', $ageGroupFrom, $ageGroupTo, __('years', 'event-integration'));
        } elseif(!empty($ageGroupFrom)) {
            $eventData['age_group'] = sprintf('%s %s %s', __('From', 'event-integration'), $ageGroupFrom, __('years', 'event-integration'));
        } elseif(!empty($ageGroupTo)) {
            $eventData['age_group'] = sprintf('%s %s %s', __('Up to', 'event-integration'), $ageGroupTo, __('years', 'event-integration'));
        }

        $data['post'] = $post;
        $data['event'] = $eventData;

        return $data;
    }

public
function
singleViewData
(
$
data
)
{
// Bail if not event
if
(
get_post_type
(
)
!==
self
::
$
postTypeSlug
||
is_archive
(
)
)
{
return
$
data
;
}
global
$
post
;
// Gather event data
$
eventData
=
array
(
)
;
$
eventData
[
'occasion'
]
=
\
EventManagerIntegration
\
Helper
\
SingleEventData
::
singleEventDate
(
)
;
$
eventData
[
'cancelled'
]
=
!
empty
(
$
eventData
[
'occasion'
]
[
'status'
]
)
&&
$
eventData
[
'occasion'
]
[
'status'
]
===
'cancelled'
__
(
'Cancelled'
,
'event-integration'
)
:
;
$
eventData
[
'rescheduled'
]
=
!
empty
(
$
eventData
[
'occasion'
]
[
'status'
]
)
&&
$
eventData
[
'occasion'
]
[
'status'
]
===
'rescheduled'
__
(
'Rescheduled'
,
'event-integration'
)
:
;
$
eventData
[
'exception_information'
]
=
!
empty
(
$
eventData
[
'occasion'
]
[
'exception_information'
]
)
$
eventData
[
'occasion'
]
[
'exception_information'
]
:
;
if
(
function_exists
(
'municipio_get_thumbnail_source'
)
)
{
$
eventData
[
'image_src'
]
=
municipio_get_thumbnail_source
(
,
array
(
750
,
750
)
,
'16:9'
)
;
}
else
{
$
thumbnailId
=
get_post_thumbnail_id
(
$
post
->
ID
)
;
$
image
=
wp_get_attachment_image_src
(
$
thumbnailId
,
'medium'
)
;
$
eventData
[
'image_src'
]
=
$
image
[
0
]
??
;
}
$
location
=
get_post_meta
(
$
post
->
ID
,
'location'
,
true
)
;
$
eventData
[
'location'
]
=
!
empty
(
$
location
[
'title'
]
)
$
location
:
;
$
bookingLink
=
get_post_meta
(
$
post
->
ID
,
'booking_link'
,
true
)
;
$
eventData
[
'booking_link'
]
=
!
empty
(
$
bookingLink
)
$
bookingLink
:
;
$
ageGroupFrom
=
get_post_meta
(
$
post
->
ID
,
'age_group_from'
,
true
)
;
$
ageGroupTo
=
get_post_meta
(
$
post
->
ID
,
'age_group_to'
,
true
)
;
$
eventData
[
'age_group'
]
=
;
if
(
!
empty
(
$
ageGroupFrom
)
&&
!
empty
(
$
ageGroupTo
)
)
{
$
eventData
[
'age_group'
]
=
sprintf
(
'%s-%s %s'
,
$
ageGroupFrom
,
$
ageGroupTo
,
__
(
'years'
,
'event-integration'
)
)
;
}
elseif
(
!
empty
(
$
ageGroupFrom
)
)
{
$
eventData
[
'age_group'
]
=
sprintf
(
'%s %s %s'
,
__
(
'From'
,
'event-integration'
)
,
$
ageGroupFrom
,
__
(
'years'
,
'event-integration'
)
)
;
}
elseif
(
!
empty
(
$
ageGroupTo
)
)
{
$
eventData
[
'age_group'
]
=
sprintf
(
'%s %s %s'
,
__
(
'Up to'
,
'event-integration'
)
,
$
ageGroupTo
,
__
(
'years'
,
'event-integration'
)
)
;
}
$
data
[
'post'
]
=
$
post
;
$
data
[
'event'
]
=
$
eventData
;
return
$
data
;
}

Add event data to single view
@param array $data Default view data
@return array Modified view data


public function getUserGroups($value, $post_id, $field)
    {
        if (!empty($value)) {
            \EventManagerIntegration\App::importPublishingGroups();
        }

        return $value;
    }

public function getUserGroups ( $ value , $ post_id , $ field ) { if ( ! empty ( $ value ) ) { \ EventManagerIntegration \ App :: importPublishingGroups ( ) ; } return $ value ; }

Import user groups when saving settings
@param  string $value   the value of the field
@param  int    $post_id the post id to save against
@param  array  $field   the field object
@return string          the new value


public function updateGroupValue($value, $post_id, $field)
    {
        // Get old value
        if ($post_id === 'options') {
            $selectedGroups = get_field('event_filter_group', 'options');
        } else {
            $selectedGroups = get_field('mod_event_groups_list', $post_id);
        }
        // Return if settings value is empty to only auto-activate children on first save
        if (!empty($selectedGroups)) {
            return $value;
        }

        if (!empty($value)) {
            foreach ($value as $v) {
                $term_children = get_term_children($v, 'event_groups');
                if ($term_children) {
                    $value = array_merge($value, $term_children);
                }
            }
            $value = array_unique($value);
        }

        return $value;
    }

Add term children to user group value
@param  string $value   the value of the field
@param  int    $post_id the post id to save against
@param  array  $field   the field object
@return string          the new value


public function eventContent($content)
    {
        if (!is_singular($this->slug)) {
            return $content;
        }

        $custom_content = $this->getCustomContent();
        if ($custom_content) {
            $content = $custom_content;
        }

        return $content;
    }

public function eventContent ( $ content ) { if ( ! is_singular ( $ this -> slug ) ) { return $ content ; } $ custom_content = $ this -> getCustomContent ( ) ; if ( $ custom_content ) { $ content = $ custom_content ; } return $ content ; }

Replace content if occasion has custom content.
@param  string $content Content of the current post.
@return string

Replace content if occasion has custom content .


public function eventContentLead($lead)
    {
        if (!is_singular($this->slug)) {
            return $lead;
        }

        $custom_content = $this->getCustomContent();
        if ($custom_content) {
            $lead = null;
        }

        return $lead;
    }

public function eventContentLead ( $ lead ) { if ( ! is_singular ( $ this -> slug ) ) { return $ lead ; } $ custom_content = $ this -> getCustomContent ( ) ; if ( $ custom_content ) { $ lead = null ; } return $ lead ; }

Remove lead content if the occasion has custom content
@param  string $lead Lead content of the current post.
@return string


public function getCustomContent()
    {
        global $post;
        $get_date = (!empty(get_query_var('date'))) ? get_query_var('date') : false;

        if ($get_date != false) {
            $occasions = \EventManagerIntegration\Helper\QueryEvents::getEventOccasions($post->ID, false);
            foreach ($occasions as $o) {
                $event_date = preg_replace('/\D/', '', $o->start_date);
                // Replace content with occasion custom content
                if ($get_date == $event_date && !empty($o->content) && $o->content_mode == 'custom') {
                    return $o->content;
                }
            }
        }
    }

Get custom occasion content
@return string


public function registerEventCategories()
    {
        $labels = array(
            'name'                  => _x('Event categories', 'Taxonomy plural name', 'event-integration'),
            'singular_name'         => _x('Event category', 'Taxonomy singular name', 'event-integration'),
            'search_items'          => __('Search categories', 'event-integration'),
            'popular_items'         => __('Popular categories', 'event-integration'),
            'all_items'             => __('All categories', 'event-integration'),
            'parent_item'           => __('Parent category', 'event-integration'),
            'parent_item_colon'     => __('Parent category', 'event-integration'),
            'edit_item'             => __('Edit category', 'event-integration'),
            'update_item'           => __('Update category', 'event-integration'),
            'add_new_item'          => __('Add new category', 'event-integration'),
            'new_item_name'         => __('New category', 'event-integration'),
            'add_or_remove_items'   => __('Add or remove categories', 'event-integration'),
            'choose_from_most_used' => __('Choose from most used categories', 'event-integration'),
            'menu_name'             => __('Categories', 'event-integration'),
        );

        $args = array(
            'labels'                => $labels,
            'public'                => true,
            'show_in_nav_menus'     => true,
            'show_admin_column'     => true,
            'hierarchical'          => true,
            'show_tagcloud'         => true,
            'show_ui'               => false,
            'query_var'             => true,
            'rewrite'               => true
        );

        register_taxonomy('event_categories', array('event'), $args);
    }

public
function
registerEventCategories
(
)
{
$
labels
=
array
(
'name'
=>
_x
(
'Event categories'
,
'Taxonomy plural name'
,
'event-integration'
)
,
'singular_name'
=>
_x
(
'Event category'
,
'Taxonomy singular name'
,
'event-integration'
)
,
'search_items'
=>
__
(
'Search categories'
,
'event-integration'
)
,
'popular_items'
=>
__
(
'Popular categories'
,
'event-integration'
)
,
'all_items'
=>
__
(
'All categories'
,
'event-integration'
)
,
'parent_item'
=>
__
(
'Parent category'
,
'event-integration'
)
,
'parent_item_colon'
=>
__
(
'Parent category'
,
'event-integration'
)
,
'edit_item'
=>
__
(
'Edit category'
,
'event-integration'
)
,
'update_item'
=>
__
(
'Update category'
,
'event-integration'
)
,
'add_new_item'
=>
__
(
'Add new category'
,
'event-integration'
)
,
'new_item_name'
=>
__
(
'New category'
,
'event-integration'
)
,
'add_or_remove_items'
=>
__
(
'Add or remove categories'
,
'event-integration'
)
,
'choose_from_most_used'
=>
__
(
'Choose from most used categories'
,
'event-integration'
)
,
'menu_name'
=>
__
(
'Categories'
,
'event-integration'
)
,
)
;
$
args
=
array
(
'labels'
=>
$
labels
,
'public'
=>
true
,
'show_in_nav_menus'
=>
true
,
'show_admin_column'
=>
true
,
'hierarchical'
=>
true
,
'show_tagcloud'
=>
true
,
'show_ui'
=>
false
,
'query_var'
=>
true
,
'rewrite'
=>
true
)
;
register_taxonomy
(
'event_categories'
,
array
(
'event'
)
,
$
args
)
;
}


public function registerEventTags()
    {
        $labels = array(
            'name'                  => _x('Event tags', 'Taxonomy plural name', 'event-integration'),
            'singular_name'         => _x('Event tag', 'Taxonomy singular name', 'event-integration'),
            'search_items'          => __('Search tags', 'event-integration'),
            'popular_items'         => __('Popular tags', 'event-integration'),
            'all_items'             => __('All tags', 'event-integration'),
            'parent_item'           => __('Parent', 'event-integration'),
            'parent_item_colon'     => __('Parent', 'event-integration'),
            'edit_item'             => __('Edit tag', 'event-integration'),
            'update_item'           => __('Update', 'event-integration'),
            'add_new_item'          => __('Add new tag', 'event-integration'),
            'new_item_name'         => __('New tag', 'event-integration'),
            'add_or_remove_items'   => __('Add or remove tags', 'event-integration'),
            'choose_from_most_used' => __('Choose from most used tags', 'event-integration'),
            'menu_name'             => __('Tags', 'event-integration'),
        );

        $args = array(
            'labels'                => $labels,
            'public'                => true,
            'show_in_nav_menus'     => true,
            'show_admin_column'     => true,
            'hierarchical'          => false,
            'show_tagcloud'         => true,
            'show_ui'               => false,
            'query_var'             => true,
            'rewrite'               => true
        );

        register_taxonomy('event_tags', array('event'), $args);
    }

public
function
registerEventTags
(
)
{
$
labels
=
array
(
'name'
=>
_x
(
'Event tags'
,
'Taxonomy plural name'
,
'event-integration'
)
,
'singular_name'
=>
_x
(
'Event tag'
,
'Taxonomy singular name'
,
'event-integration'
)
,
'search_items'
=>
__
(
'Search tags'
,
'event-integration'
)
,
'popular_items'
=>
__
(
'Popular tags'
,
'event-integration'
)
,
'all_items'
=>
__
(
'All tags'
,
'event-integration'
)
,
'parent_item'
=>
__
(
'Parent'
,
'event-integration'
)
,
'parent_item_colon'
=>
__
(
'Parent'
,
'event-integration'
)
,
'edit_item'
=>
__
(
'Edit tag'
,
'event-integration'
)
,
'update_item'
=>
__
(
'Update'
,
'event-integration'
)
,
'add_new_item'
=>
__
(
'Add new tag'
,
'event-integration'
)
,
'new_item_name'
=>
__
(
'New tag'
,
'event-integration'
)
,
'add_or_remove_items'
=>
__
(
'Add or remove tags'
,
'event-integration'
)
,
'choose_from_most_used'
=>
__
(
'Choose from most used tags'
,
'event-integration'
)
,
'menu_name'
=>
__
(
'Tags'
,
'event-integration'
)
,
)
;
$
args
=
array
(
'labels'
=>
$
labels
,
'public'
=>
true
,
'show_in_nav_menus'
=>
true
,
'show_admin_column'
=>
true
,
'hierarchical'
=>
false
,
'show_tagcloud'
=>
true
,
'show_ui'
=>
false
,
'query_var'
=>
true
,
'rewrite'
=>
true
)
;
register_taxonomy
(
'event_tags'
,
array
(
'event'
)
,
$
args
)
;
}


public function registerEventGroups()
    {
        $labels = array(
            'name'                  => _x('Event groups', 'Taxonomy plural name', 'event-integration'),
            'singular_name'         => _x('Event group', 'Taxonomy singular name', 'event-integration'),
            'search_items'          => __('Search groups', 'event-integration'),
            'popular_items'         => __('Popular groups', 'event-integration'),
            'all_items'             => __('All groups', 'event-integration'),
            'parent_item'           => __('Parent group', 'event-integration'),
            'parent_item_colon'     => __('Parent group', 'event-integration'),
            'edit_item'             => __('Edit group', 'event-integration'),
            'update_item'           => __('Update group', 'event-integration'),
            'add_new_item'          => __('Add new group', 'event-integration'),
            'new_item_name'         => __('New group', 'event-integration'),
            'add_or_remove_items'   => __('Add or remove groups', 'event-integration'),
            'choose_from_most_used' => __('Choose from most used groups', 'event-integration'),
            'menu_name'             => __('Groups', 'event-integration'),
        );

        $args = array(
            'labels'                => $labels,
            'public'                => true,
            'show_in_nav_menus'     => true,
            'show_admin_column'     => true,
            'hierarchical'          => true,
            'show_tagcloud'         => true,
            'show_ui'               => false,
            'query_var'             => true,
            'rewrite'               => true
        );

        register_taxonomy('event_groups', array('event'), $args);
    }

public
function
registerEventGroups
(
)
{
$
labels
=
array
(
'name'
=>
_x
(
'Event groups'
,
'Taxonomy plural name'
,
'event-integration'
)
,
'singular_name'
=>
_x
(
'Event group'
,
'Taxonomy singular name'
,
'event-integration'
)
,
'search_items'
=>
__
(
'Search groups'
,
'event-integration'
)
,
'popular_items'
=>
__
(
'Popular groups'
,
'event-integration'
)
,
'all_items'
=>
__
(
'All groups'
,
'event-integration'
)
,
'parent_item'
=>
__
(
'Parent group'
,
'event-integration'
)
,
'parent_item_colon'
=>
__
(
'Parent group'
,
'event-integration'
)
,
'edit_item'
=>
__
(
'Edit group'
,
'event-integration'
)
,
'update_item'
=>
__
(
'Update group'
,
'event-integration'
)
,
'add_new_item'
=>
__
(
'Add new group'
,
'event-integration'
)
,
'new_item_name'
=>
__
(
'New group'
,
'event-integration'
)
,
'add_or_remove_items'
=>
__
(
'Add or remove groups'
,
'event-integration'
)
,
'choose_from_most_used'
=>
__
(
'Choose from most used groups'
,
'event-integration'
)
,
'menu_name'
=>
__
(
'Groups'
,
'event-integration'
)
,
)
;
$
args
=
array
(
'labels'
=>
$
labels
,
'public'
=>
true
,
'show_in_nav_menus'
=>
true
,
'show_admin_column'
=>
true
,
'hierarchical'
=>
true
,
'show_tagcloud'
=>
true
,
'show_ui'
=>
false
,
'query_var'
=>
true
,
'rewrite'
=>
true
)
;
register_taxonomy
(
'event_groups'
,
array
(
'event'
)
,
$
args
)
;
}


public function addImportButtons($views)
    {
        if (current_user_can('administrator') || current_user_can('editor')) {
            $button  = '
';

            if (get_field('event_api_url', 'option')) {
                $button .= '
' . __('Import events', 'event-integration') . '
';
            }
            $button .= '
';
            $views['import-buttons'] = $button;
        }

        return $views;
    }

'<div class="import-buttons actions" style="position: relative;">'

Add buttons to start parsing xcap and Cbis
@return void


public function importEvents()
    {
        if ($apiUrl = \EventManagerIntegration\Helper\ApiUrl::buildApiUrl()) {
            $importer = new \EventManagerIntegration\Parser\EventManagerApi($apiUrl);
            $data = $importer->getCreatedData();
            wp_send_json($data);
        }

        wp_die();
    }

public function importEvents ( ) { if ( $ apiUrl = \ EventManagerIntegration \ Helper \ ApiUrl :: buildApiUrl ( ) ) { $ importer = new \ EventManagerIntegration \ Parser \ EventManagerApi ( $ apiUrl ) ; $ data = $ importer -> getCreatedData ( ) ; wp_send_json ( $ data ) ; } wp_die ( ) ; }


public function acceptOrDeny()
    {
        if (!isset($_POST['postId']) || !isset($_POST['value'])) {
            echo _e('Something went wrong!', 'event-integration');
            die();
        }

        $postId = $_POST['postId'];
        $value = $_POST['value'];

        $post = get_post($postId);
        if ($value == 0) {
            $post->post_status = 'draft';
        }
        if ($value == 1) {
            $post->post_status = 'publish';
        }

        $update = wp_update_post($post, true);
        if (is_wp_error($update)) {
            echo _e('Error', 'event-integration');
            die();
        }

        echo $value;
        die();
    }

public
function
acceptOrDeny
(
)
{
if
(
!
isset
(
$
_POST
[
'postId'
]
)
||
!
isset
(
$
_POST
[
'value'
]
)
)
{
echo
_e
(
'Something went wrong!'
,
'event-integration'
)
;
die
(
)
;
}
$
postId
=
$
_POST
[
'postId'
]
;
$
value
=
$
_POST
[
'value'
]
;
$
post
=
get_post
(
$
postId
)
;
if
(
$
value
==
0
)
{
$
post
->
post_status
=
'draft'
;
}
if
(
$
value
==
1
)
{
$
post
->
post_status
=
'publish'
;
}
$
update
=
wp_update_post
(
$
post
,
true
)
;
if
(
is_wp_error
(
$
update
)
)
{
echo
_e
(
'Error'
,
'event-integration'
)
;
die
(
)
;
}
echo
$
value
;
die
(
)
;
}

Accept or deny an event. Changes post status to draft if denied.
@return int $value

Accept or deny an event . Changes post status to draft if denied .


protected function createTunnel()
    {
        $this->runCommand(sprintf('%s %s >> %s 2>&1 &',
            config('tunneler.nohup_path'),
            $this->sshCommand,
            config('tunneler.nohup_log')
        ));
        // Ensure we wait long enough for it to actually connect.
        usleep(config('tunneler.wait'));
    }


protected function verifyTunnel()
    {
        if (config('tunneler.verify_process') == 'bash') {
            return $this->runCommand($this->bashCommand);
        }

        return $this->runCommand($this->ncCommand);
    }

protected function verifyTunnel ( ) { if ( config ( 'tunneler.verify_process' ) == 'bash' ) { return $ this -> runCommand ( $ this -> bashCommand ) ; } return $ this -> runCommand ( $ this -> ncCommand ) ; }

Verifies whether the tunnel is active or not.
@return bool

Verifies whether the tunnel is active or not .


protected function runCommand($command)
    {
        $return_var = 1;
        exec($command, $this->output, $return_var);
        return (bool)($return_var === 0);
    }

protected function runCommand ( $ command ) { $ return_var = 1 ; exec ( $ command , $ this -> output , $ return_var ) ; return ( bool ) ( $ return_var === 0 ) ; }

Runs a command and converts the exit code to a boolean
@param $command
@return bool


public function setSignalHandler(int $signal, callable $closure = null){
        if (empty($closure)){
            return pcntl_signal($signal, array($this, 'sigHandler'));
        }
        return pcntl_signal($signal, $closure);
    }

public function setSignalHandler ( int $ signal , callable $ closure = null ) { if ( empty ( $ closure ) ) { return pcntl_signal ( $ signal , array ( $ this , 'sigHandler' ) ) ; } return pcntl_signal ( $ signal , $ closure ) ; }

Sets the signal to be handled by either the closure or the built in
signal handler.

@param int $signal
@param callable|null $closure

@return bool

Sets the signal to be handled by either the closure or the built in signal handler .


public function sigHandler( int $signo ){
        $this->handleWorkerOutput('warn', sprintf("Signal %d Caught, asking the daemon to stop gracefully.", $signo));
        $this->stopGracefully = true;
    }

Built in Signal Handler.
@param int $signo


public function runProcess(Process $process, $memory)
    {
        try {
            $process->run(function ($type, $line) {
                $this->handleWorkerOutput($type, $line);
            });
        }catch (\Exception $e){
            dd($e);
        }

        // If we caught a signal and need to stop gracefully, this is the place to
        // do it.
        pcntl_signal_dispatch();
        if ($this->stopGracefully){
            $this->gracefulStop();
        }
        // Once we have run the job we'll go check if the memory limit has been
        // exceeded for the script. If it has, we will kill this script so a
        // process manager will restart this with a clean slate of memory.
        if ($this->memoryExceeded($memory)) {
            $this->stop();
        }
    }

Run the given process.

@param  Process  $process
@param  int  $memory
@return void


public function editFor($containerName, $defaultAction = 'showAll'): string
    {
        $environment = $this->createDcGeneral($containerName);
        $actionName  = $environment->getInputProvider()->getParameter('act') ?: $defaultAction;
        $action      = new Action($actionName);
        $event       = new ActionEvent($environment, $action);

        $this->dispatcher->dispatch(DcGeneralEvents::ACTION, $event);

        if (!$result = $event->getResponse()) {
            return 'Action ' . $action->getName() . ' is not supported yet.';
        }

        return $result;
    }

public
function
editFor
(
$
containerName
,
$
defaultAction
=
'showAll'
)
:
string
{
$
environment
=
$
this
->
createDcGeneral
(
$
containerName
)
;
$
actionName
=
$
environment
->
getInputProvider
(
)
->
getParameter
(
'act'
)
:
$
defaultAction
;
$
action
=
new
Action
(
$
actionName
)
;
$
event
=
new
ActionEvent
(
$
environment
,
$
action
)
;
$
this
->
dispatcher
->
dispatch
(
DcGeneralEvents
::
ACTION
,
$
event
)
;
if
(
!
$
result
=
$
event
->
getResponse
(
)
)
{
return
'Action '
.
$
action
->
getName
(
)
.
' is not supported yet.'
;
}
return
$
result
;
}

Create a frontend editor for the given table.

@param string $containerName The name of the data container to edit.

@param string $defaultAction The default action to issue, if none provided by the input provider.

@return string

Create a frontend editor for the given table .


public function createDcGeneral($containerName): EnvironmentInterface
    {
        if (!array_key_exists($containerName, self::$environments)) {
            $dcGeneral = (new DcGeneralFactory())
                ->setContainerName($containerName)
                ->setEventDispatcher($this->dispatcher)
                ->setTranslator($this->translator)
                ->createDcGeneral();

            self::$environments[$containerName] = $dcGeneral->getEnvironment();
        }

        return self::$environments[$containerName];
    }

public function createDcGeneral ( $ containerName ) : EnvironmentInterface { if ( ! array_key_exists ( $ containerName , self :: $ environments ) ) { $ dcGeneral = ( new DcGeneralFactory ( ) ) -> setContainerName ( $ containerName ) -> setEventDispatcher ( $ this -> dispatcher ) -> setTranslator ( $ this -> translator ) -> createDcGeneral ( ) ; self :: $ environments [ $ containerName ] = $ dcGeneral -> getEnvironment ( ) ; } return self :: $ environments [ $ containerName ] ; }

Create the dc-general and return it's environment instance.

@param string $containerName The name of the data container to edit.

@return EnvironmentInterface

Create the dc - general and return it s environment instance .


public function getWidget($property, PropertyValueBag $valueBag = null)
    {
        $environment         = $this->getEnvironment();
        $dispatcher          = $environment->getEventDispatcher();
        $propertyDefinitions = $environment->getDataDefinition()->getPropertiesDefinition();

        if (!$propertyDefinitions->hasProperty($property)) {
            throw new DcGeneralInvalidArgumentException(
                'Property ' . $property . ' is not defined in propertyDefinitions.'
            );
        }

        $model = clone $this->model;
        $model->setId($this->model->getId());

        if ($valueBag) {
            $values = new PropertyValueBag($valueBag->getArrayCopy());
            $this->environment->getController()->updateModelFromPropertyBag($model, $values);
        }

        $propertyDefinition = $propertyDefinitions->getProperty($property);
        $event              = new BuildWidgetEvent($environment, $model, $propertyDefinition);

        $dispatcher->dispatch(DcGeneralFrontendEvents::BUILD_WIDGET, $event);
        if (!$event->getWidget()) {
            throw new DcGeneralRuntimeException(
                sprintf('Widget was not build for property %s::%s.', $this->model->getProviderName(), $property)
            );
        }

        return $event->getWidget();
    }

Retrieve the instance of a widget for the given property.

@param string           $property Name of the property for which the widget shall be retrieved.

@param PropertyValueBag $valueBag The input values to use (optional).

@return \Widget

@throws DcGeneralRuntimeException         When No widget could be build.
@throws DcGeneralInvalidArgumentException When property is not defined in the property definitions.

Retrieve the instance of a widget for the given property .


public function renderWidget($property, $ignoreErrors = false, PropertyValueBag $valueBag = null)
    {
        $widget = $this->getWidget($property, $valueBag);

        if (!$widget) {
            throw new DcGeneralRuntimeException('No widget for property ' . $property);
        }

        if ($ignoreErrors) {
            // Clean the errors array and fix up the CSS class.
            $reflection = new \ReflectionProperty(get_class($widget), 'arrErrors');
            $reflection->setAccessible(true);
            $reflection->setValue($widget, []);
            $reflection = new \ReflectionProperty(get_class($widget), 'strClass');
            $reflection->setAccessible(true);
            $reflection->setValue($widget, str_replace('error', '', $reflection->getValue($widget)));
        } else {
            if ($valueBag && $valueBag->hasPropertyValue($property)
                && $valueBag->isPropertyValueInvalid($property)
            ) {
                foreach ($valueBag->getPropertyValueErrors($property) as $error) {
                    $widget->addError($error);
                }
            }
        }

        return $widget->parse();
    }

Render the widget for the named property.

@param string           $property     The name of the property for which the widget shall be rendered.

@param bool             $ignoreErrors Flag if the error property of the widget shall get cleared prior rendering.

@param PropertyValueBag $valueBag     The input values to use (optional).

@return string

@throws DcGeneralRuntimeException         For unknown properties.

Render the widget for the named property .


public function processInput(PropertyValueBag $valueBag)
    {
        $post = $this->hijackPost($valueBag);

        // Now get and validate the widgets.
        foreach (array_keys($valueBag->getArrayCopy()) as $property) {
            $this->processProperty($valueBag, $property);
        }

        $this->restorePost($post);
    }

public
function
processInput
(
PropertyValueBag
$
valueBag
)
{
$
post
=
$
this
->
hijackPost
(
$
valueBag
)
;
// Now get and validate the widgets.
foreach
(
array_keys
(
$
valueBag
->
getArrayCopy
(
)
)
as
$
property
)
{
$
this
->
processProperty
(
$
valueBag
,
$
property
)
;
}
$
this
->
restorePost
(
$
post
)
;
}

Process the input values from the input provider and update the information in the value bag.

@param PropertyValueBag $valueBag The value bag to update.

@return void

Process the input values from the input provider and update the information in the value bag .


private function processProperty(PropertyValueBag $valueBag, $property)
    {
        // NOTE: the passed input values are RAW DATA from the input provider - aka widget known values and not
        // native data as in the model.
        // Therefore we do not need to decode them but MUST encode them.
        $widget = $this->getWidget($property, $valueBag);
        $widget->validate();

        if ($widget->hasErrors()) {
            foreach ($widget->getErrors() as $error) {
                $valueBag->markPropertyValueAsInvalid($property, $error);
            }

            return;
        }

        if (!$widget->submitInput()) {
            // Handle as abstaining property.
            $valueBag->removePropertyValue($property);
            return;
        }

        try {
            $valueBag->setPropertyValue($property, $this->encodeValue($property, $widget->value, $valueBag));
        } catch (\Exception $e) {
            $widget->addError($e->getMessage());
            foreach ($widget->getErrors() as $error) {
                $valueBag->markPropertyValueAsInvalid($property, $error);
            }
        }
    }

Process a single property.

@param PropertyValueBag $valueBag The value bag to update.

@param string           $property The property to process.

@return void

@throws DcGeneralRuntimeException         When No widget could be build.
@throws DcGeneralInvalidArgumentException When property is not defined in the property definitions.


private function hijackPost(PropertyValueBag $valueBag)
    {
        $post  = $_POST;
        $_POST = [];
        Input::resetCache();

        // Set all POST data, these get used within the Widget::validate() method.
        foreach ($valueBag as $property => $value) {
            $_POST[$property] = $value;
        }

        return $post;
    }

Remember current POST data and overwrite it with the values from the value bag.

The previous values are returned and can be restored via a call to restorePost().

@param PropertyValueBag $valueBag The value bag to retrieve the new post data from.

@return array

@SuppressWarnings(PHPMD.Superglobals)
@SuppressWarnings(PHPMD.CamelCaseVariableName)

Remember current POST data and overwrite it with the values from the value bag .


public function handleEvent(ActionEvent $event): void
    {
        if (!$this->scopeDeterminator->currentScopeIsFrontend()) {
            return;
        }

        $action = $event->getAction();
        // Only handle if we do not have a manual sorting or we know where to insert.
        // Manual sorting is handled by clipboard.
        if ('delete' !== $action->getName()) {
            return;
        }

        // Only run when no response given yet.
        if (null !== $event->getResponse()) {
            return;
        }

        $this->process($event->getEnvironment());
    }

Handle the event to process the action.

@param ActionEvent $event The action event.

@return void

@throws RedirectResponseException After successful delete.
@throws DcGeneralRuntimeException When the DataContainer is not deletable.

Handle the event to process the action .


public function create($className = 'Imagine')
    {
        $this->configureDriverSpecificSettings();

        $className = 'Imagine\\' . $this->settings['driver'] . '\\' . $className;
        $arguments = array_slice(func_get_args(), 1);

        switch (count($arguments)) {
            case 0: $object = new $className(); break;
            case 1: $object = new $className($arguments[0]); break;
            case 2: $object = new $className($arguments[0], $arguments[1]); break;
            case 3: $object = new $className($arguments[0], $arguments[1], $arguments[2]); break;
            case 4: $object = new $className($arguments[0], $arguments[1], $arguments[2], $arguments[3]); break;
            case 5: $object = new $className($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4]); break;
            case 6: $object = new $className($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5]); break;
            default:
                $class = new \ReflectionClass($className);
                $object =  $class->newInstanceArgs($arguments);
        }

        return $object;
    }

public function create ( $ className = 'Imagine' ) { $ this -> configureDriverSpecificSettings ( ) ; $ className = 'Imagine\\' . $ this -> settings [ 'driver' ] . '\\' . $ className ; $ arguments = array_slice ( func_get_args ( ) , 1 ) ; switch ( count ( $ arguments ) ) { case 0 : $ object = new $ className ( ) ; break ; case 1 : $ object = new $ className ( $ arguments [ 0 ] ) ; break ; case 2 : $ object = new $ className ( $ arguments [ 0 ] , $ arguments [ 1 ] ) ; break ; case 3 : $ object = new $ className ( $ arguments [ 0 ] , $ arguments [ 1 ] , $ arguments [ 2 ] ) ; break ; case 4 : $ object = new $ className ( $ arguments [ 0 ] , $ arguments [ 1 ] , $ arguments [ 2 ] , $ arguments [ 3 ] ) ; break ; case 5 : $ object = new $ className ( $ arguments [ 0 ] , $ arguments [ 1 ] , $ arguments [ 2 ] , $ arguments [ 3 ] , $ arguments [ 4 ] ) ; break ; case 6 : $ object = new $ className ( $ arguments [ 0 ] , $ arguments [ 1 ] , $ arguments [ 2 ] , $ arguments [ 3 ] , $ arguments [ 4 ] , $ arguments [ 5 ] ) ; break ; default : $ class = new \ ReflectionClass ( $ className ) ; $ object = $ class -> newInstanceArgs ( $ arguments ) ; } return $ object ; }

Factory method which creates an Imagine instance.

By default this factory creates an Imagine service according to the currently configured driver (for example GD
or ImageMagick).

You may alternatively specify a class name of a driver-dependent class you need an instance of. For example,
specifying "Image" with the currently configured driver "Gd" will return an instance of the class
\Imagine\Gd\Image.

@param string $className If specified, this factory will create an instance of the driver dependent class
@return \Imagine\Image\ImagineInterface
@throws \ReflectionException
@api

Factory method which creates an Imagine instance .


protected function configureImagickSettings()
    {
        if (!isset($this->settings['driverSpecific']['Imagick'])) {
            return;
        }

        $limits = $this->settings['driverSpecific']['Imagick']['limits'] ? $this->settings['driverSpecific']['Imagick']['limits'] : [];
        foreach ($limits as $resourceType => $limit) {
            \Imagick::setResourceLimit($resourceType, $limit);
        }
    }

protected function configureImagickSettings ( ) { if ( ! isset ( $ this -> settings [ 'driverSpecific' ] [ 'Imagick' ] ) ) { return ; } $ limits = $ this -> settings [ 'driverSpecific' ] [ 'Imagick' ] [ 'limits' ] ? $ this -> settings [ 'driverSpecific' ] [ 'Imagick' ] [ 'limits' ] : [ ] ; foreach ( $ limits as $ resourceType => $ limit ) { \ Imagick :: setResourceLimit ( $ resourceType , $ limit ) ; } }

Sets limits for the Imagick driver.

@return void


public function injectSettings(array $settings)
    {
        $this->settings = $settings;
        if (!isset($settings['enabledDrivers'])) {
            // FIXME: This is a hotfix and should actually be fixed in the Neos setup step. As soon as it is fixed there, this condition can be removed.
            return;
        }
        if (!in_array($settings['driver'], array_keys(array_filter($settings['enabledDrivers'])), true)) {
            throw new \InvalidArgumentException('The "driver" for Imagine must be enabled by settings, check Neos.Imagine.enabledDrivers.', 1515402616);
        }
    }

Injects the settings.

@param array $settings
@return void
@throws \InvalidArgumentException


public function handleEvent(BuildWidgetEvent $event)
    {
        // Only run in the frontend or when the widget is not build yet
        if (false === $this->scopeDeterminator->currentScopeIsFrontend() || null !== $event->getWidget()) {
            return;
        }

        $widget = $this->buildWidget($event->getEnvironment(), $event->getProperty(), $event->getModel());

        $event->setWidget($widget);
    }

Handle the build widget event.

@param BuildWidgetEvent $event The event.

@return void


private function getWidgetClass(PropertyInterface $property)
    {
        if (!isset($GLOBALS['TL_FFL'][$property->getWidgetType()])) {
            return null;
        }

        $className = $GLOBALS['TL_FFL'][$property->getWidgetType()];
        if (!class_exists($className)) {
            return null;
        }

        return $className;
    }

private function getWidgetClass ( PropertyInterface $ property ) { if ( ! isset ( $ GLOBALS [ 'TL_FFL' ] [ $ property -> getWidgetType ( ) ] ) ) { return null ; } $ className = $ GLOBALS [ 'TL_FFL' ] [ $ property -> getWidgetType ( ) ] ; if ( ! class_exists ( $ className ) ) { return null ; } return $ className ; }

Try to resolve the class name for the widget.

@param PropertyInterface $property The property to get the widget class name for.

@return string

@SuppressWarnings(PHPMD.Superglobals)
@SuppressWarnings(PHPMD.CamelCaseVariableName)

Try to resolve the class name for the widget .


private function getOptionsForWidget(
        EnvironmentInterface $environment,
        PropertyInterface $propInfo,
        ModelInterface $model
    ) {
        $dispatcher = $environment->getEventDispatcher();
        $options    = $propInfo->getOptions();
        $event      = new GetPropertyOptionsEvent($environment, $model);
        $event->setPropertyName($propInfo->getName());
        $event->setOptions($options);
        $dispatcher->dispatch(GetPropertyOptionsEvent::NAME, $event);

        if ($event->getOptions() !== $options) {
            return $event->getOptions();
        }

        return $options;
    }

private function getOptionsForWidget ( EnvironmentInterface $ environment , PropertyInterface $ propInfo , ModelInterface $ model ) { $ dispatcher = $ environment -> getEventDispatcher ( ) ; $ options = $ propInfo -> getOptions ( ) ; $ event = new GetPropertyOptionsEvent ( $ environment , $ model ) ; $ event -> setPropertyName ( $ propInfo -> getName ( ) ) ; $ event -> setOptions ( $ options ) ; $ dispatcher -> dispatch ( GetPropertyOptionsEvent :: NAME , $ event ) ; if ( $ event -> getOptions ( ) !== $ options ) { return $ event -> getOptions ( ) ; } return $ options ; }

Get special labels.

@param EnvironmentInterface $environment The environment.

@param PropertyInterface    $propInfo    The property for which the options shall be retrieved.

@param ModelInterface       $model       The model.

@return string[]


public function execute()
    {
        $inputProvider      = $this->environment->getInputProvider();
        $palettesDefinition = $this->definition->getPalettesDefinition();
        $isSubmitted        = ($inputProvider->getValue('FORM_SUBMIT') === $this->definition->getName());
        $isAutoSubmit       = ($inputProvider->getValue('SUBMIT_TYPE') === 'auto');
        $widgetManager      = new WidgetManager($this->environment, $this->model);

        $this->dispatcher->dispatch(PreEditModelEvent::NAME, new PreEditModelEvent($this->environment, $this->model));

        $this->enforceModelRelationship();

        // Pass 1: Get the palette for the values stored in the model.
        $palette = $palettesDefinition->findPalette($this->model);

        $propertyValues = $this->processInput($widgetManager);
        if ($isSubmitted && $propertyValues) {
            // Pass 2: Determine the real palette we want to work on if we have some data submitted.
            $palette = $palettesDefinition->findPalette($this->model, $propertyValues);

            // Update the model - the model might add some more errors to the propertyValueBag via exceptions.
            $this->environment->getController()->updateModelFromPropertyBag($this->model, $propertyValues);
        }

        $fieldSets = $this->buildFieldSet($widgetManager, $palette, $propertyValues);

        $buttons = $this->getEditButtons();

        if ((!$isAutoSubmit) && $isSubmitted && empty($this->errors)) {
            $this->doPersist();
            $this->handleSubmit($buttons);
        }

        $template = new ViewTemplate('dcfe_general_edit');
        $template->setData(
            [
                'fieldsets'   => $fieldSets,
                'subHeadline' => $this->getHeadline(),
                'table'       => $this->definition->getName(),
                'enctype'     => 'multipart/form-data',
                'error'       => $this->errors,
                'editButtons' => $buttons
            ]
        );

        return $template->parse();
    }

Create the edit mask.

@return string

@throws DcGeneralRuntimeException         If the data container is not editable, closed.

@throws DcGeneralInvalidArgumentException If an unknown property is encountered in the palette.


private function enforceModelRelationship()
    {
        $event = new EnforceModelRelationshipEvent($this->environment, $this->model);

        $this->dispatcher->dispatch(DcGeneralEvents::ENFORCE_MODEL_RELATIONSHIP, $event);
    }

private function enforceModelRelationship ( ) { $ event = new EnforceModelRelationshipEvent ( $ this -> environment , $ this -> model ) ; $ this -> dispatcher -> dispatch ( DcGeneralEvents :: ENFORCE_MODEL_RELATIONSHIP , $ event ) ; }

This method triggers the event to update the parent child relationships of the current model.

@return void

This method triggers the event to update the parent child relationships of the current model .


private function processInput($widgetManager)
    {
        $input = $this->environment->getInputProvider();

        if ($input->getValue('FORM_SUBMIT') === $this->definition->getName()) {
            $propertyValues = new PropertyValueBag();
            $propertyNames  = array_intersect(
                $this->definition->getPropertiesDefinition()->getPropertyNames(),
                (array) $input->getValue('FORM_INPUTS')
            );

            // Process input and update changed properties.
            foreach ($propertyNames as $propertyName) {
                $propertyValue = $input->hasValue($propertyName) ? $input->getValue($propertyName, true) : null;
                $propertyValues->setPropertyValue($propertyName, $propertyValue);
            }

            $widgetManager->processInput($propertyValues);

            return $propertyValues;
        }

        return null;
    }

Process input and return all modified properties or null if there is no input.

@param WidgetManager $widgetManager The widget manager in use.

@return null|PropertyValueBag

Process input and return all modified properties or null if there is no input .


private function handlePrePersist()
    {
        if (null !== $this->preFunction) {
            \call_user_func($this->preFunction, $this->environment, $this->model, $this->originalModel);
        }

        $this->dispatcher->dispatch(
            PrePersistModelEvent::NAME,
            new PrePersistModelEvent($this->environment, $this->model, $this->originalModel)
        );
    }

private function handlePrePersist ( ) { if ( null !== $ this -> preFunction ) { \ call_user_func ( $ this -> preFunction , $ this -> environment , $ this -> model , $ this -> originalModel ) ; } $ this -> dispatcher -> dispatch ( PrePersistModelEvent :: NAME , new PrePersistModelEvent ( $ this -> environment , $ this -> model , $ this -> originalModel ) ) ; }

Trigger the pre persist event and handle the prePersist function if available.

@return void

Trigger the pre persist event and handle the prePersist function if available .


private function handlePostPersist()
    {
        if (null !== $this->postFunction) {
            \call_user_func($this->postFunction, $this->environment, $this->model, $this->originalModel);
        }

        $event = new PostPersistModelEvent($this->environment, $this->model, $this->originalModel);
        $this->dispatcher->dispatch($event::NAME, $event);
    }

private function handlePostPersist ( ) { if ( null !== $ this -> postFunction ) { \ call_user_func ( $ this -> postFunction , $ this -> environment , $ this -> model , $ this -> originalModel ) ; } $ event = new PostPersistModelEvent ( $ this -> environment , $ this -> model , $ this -> originalModel ) ; $ this -> dispatcher -> dispatch ( $ event :: NAME , $ event ) ; }

Trigger the post persist event and handle the postPersist function if available.

@return void

Trigger the post persist event and handle the postPersist function if available .


private function translateLabel($transString, $parameters = [])
    {
        $translator = $this->translator;
        if ($transString !== ($label =
                $translator->translate($transString, $this->definition->getName(), $parameters))) {
            return $label;
        }

        if ($transString !== ($label = $translator->translate('MSC.'.$transString, $parameters))
        ) {
            return $label;
        }

        // Fallback, just return the key as is it.
        return $transString;
    }

Get a translated label from the translator.

The fallback is as follows:
1. Try to translate via the data definition name as translation section.
2. Try to translate with the prefix 'MSC.'.
3. Return the input value as nothing worked out.

@param string $transString The non translated label for the button.

@param array  $parameters  The parameters to pass to the translator.

@return string

Get a translated label from the translator .


private function buildFieldSet($widgetManager, $palette, $propertyValues)
    {
        $propertyDefinitions = $this->definition->getPropertiesDefinition();
        $isAutoSubmit        = ($this->environment->getInputProvider()->getValue('SUBMIT_TYPE') === 'auto');

        $fieldSets = [];
        $errors    = [];
        $first     = true;
        foreach ($palette->getLegends() as $legend) {
            $legendName = $this->translator->translate(
                $legend->getName() . '_legend',
                $this->definition->getName()
            );
            $fields     = [];
            $hidden     = [];
            $properties = $legend->getProperties($this->model, $propertyValues);

            if (!$properties) {
                continue;
            }

            foreach ($properties as $property) {
                $propertyName = $property->getName();
                $this->ensurePropertyExists($propertyName, $propertyDefinitions);

                // If this property is invalid, fetch the error.
                if ((!$isAutoSubmit)
                    && $propertyValues
                    && $propertyValues->hasPropertyValue($propertyName)
                    && $propertyValues->isPropertyValueInvalid($propertyName)
                ) {
                    $errors[] = $propertyValues->getPropertyValueErrors($propertyName);
                }

                $fields[] = $widgetManager->renderWidget($propertyName, $isAutoSubmit, $propertyValues);
                $hidden[] = sprintf('<input type="hidden" name="FORM_INPUTS[]" value="%s">', $propertyName);
            }

            $fieldSet['label']   = $legendName;
            $fieldSet['class']   = $first ? 'tl_tbox' : 'tl_box';
            $fieldSet['palette'] = implode('', $hidden) . implode('', $fields);
            $fieldSet['legend']  = $legend->getName();
            $fieldSets[]         = $fieldSet;

            $first = false;
        }

        if ([] !== $errors) {
            $this->errors = array_merge(...$errors);
        }

        return $fieldSets;
    }

Build the field sets.

@param WidgetManager    $widgetManager  The widget manager in use.

@param PaletteInterface $palette        The palette to use.

@param PropertyValueBag $propertyValues The property values.

@return array

@throws DcGeneralRuntimeException         For unknown properties.
@throws DcGeneralInvalidArgumentException When the property is not registered in the definition.

@SuppressWarnings(PHPMD.CyclomaticComplexity)


private function handleSubmit($buttons)
    {
        $inputProvider = $this->environment->getInputProvider();
        foreach (array_keys($buttons) as $button) {
            if ($inputProvider->hasValue($button)) {
                $event = new HandleSubmitEvent($this->environment, $this->model, $button);

                $this->dispatcher->dispatch(DcGeneralFrontendEvents::HANDLE_SUBMIT, $event);

                break;
            }
        }
    }

private function handleSubmit ( $ buttons ) { $ inputProvider = $ this -> environment -> getInputProvider ( ) ; foreach ( array_keys ( $ buttons ) as $ button ) { if ( $ inputProvider -> hasValue ( $ button ) ) { $ event = new HandleSubmitEvent ( $ this -> environment , $ this -> model , $ button ) ; $ this -> dispatcher -> dispatch ( DcGeneralFrontendEvents :: HANDLE_SUBMIT , $ event ) ; break ; } } }

Handle the submit and determine which button has been triggered.

This method will redirect the client.

@param array $buttons The registered edit buttons.

@return void

Handle the submit and determine which button has been triggered .


private function getHeadline()
    {
        if ($this->model->getId()) {
            return $this->translateLabel('editRecord', [$this->model->getId()]);
        }
        return $this->translateLabel('newRecord');
    }

private function getHeadline ( ) { if ( $ this -> model -> getId ( ) ) { return $ this -> translateLabel ( 'editRecord' , [ $ this -> model -> getId ( ) ] ) ; } return $ this -> translateLabel ( 'newRecord' ) ; }

Determine the headline to use.

@return string.