<?php

define('REPORT_PERIOD_MONTHLY', 'monthly');
define('REPORT_PERIOD_3MONTHS', '3months');
define('REPORT_PERIOD_YEARLY', 'year');

/**
 * Implements hook_menu().
 */
function groups_reports_menu() {
  $items['reports/groups-membership-report'] = array(
    'title' => 'User group membership report',
    'description' => 'View membership statistic aggregated by continents.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('groups_reports_groups_membership_report_form'),
    'access callback' => array('groups_reports_access'),
    'weight' => -1,
  );
  $items['reports/groups-membership-history-report'] = array(
    'title' => 'Membership history report',
    'description' => 'View membership history.',
    'page callback' => 'groups_reports_groups_membership_history_report',
    'access callback' => array('groups_reports_access'),
    'weight' => -1,
  );
  $items['reports/group-status-report'] = array(
    'title' => 'Group status report',
    'description' => 'View the completeness of user groups.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('groups_reports_groups_status_report_form'),
    'access callback' => array('groups_reports_access'),
    'weight' => -1,
  );
  $items['reports/group-contact-report/csv'] = array(
    'title' => 'Group contact report CSV export',
    'description' => 'Export group organizers in CSV format',
    'page callback' => 'groups_reports_groups_contact_report_csv_export',
    'access callback' => TRUE,
    'weight' => -1,
  );
  $items['admin/config/system/reports'] = array(
    'title' => 'Groups report Settings',
    'description' => 'Groups report settings',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('groups_reports_admin_settings'),
    'access arguments' => array('administer site configuration'),
    'file' => 'groups_reports.admin.inc',
  );
  return $items;
}

/**
 * Implements a hook_access() callback.
 *
 * Allow access for ambassador and community_manager roles.
 */
function groups_reports_access() {
  global $user;
  return (
    (in_array("administrator", $user->roles)) ||
    (in_array("ambassador", $user->roles)) ||
    (in_array("community_manager", $user->roles))
  );
}

/**
 * Update the daily membership statistics
 */
function groups_reports_update_membership_stat($timestamp = null) {
  $timestr = gmdate('Ymd', $timestamp ? $timestamp : time());
  $result = db_select('node', 'n')
    ->fields('n')->condition('status', 1)
    ->condition('type', 'group', '=')
    ->execute();
  foreach ($result as $record) {
    $node = node_load($record->nid);
    // update meetup.com membership data
    $membercount = 0;
    if (isset($node->field_meetup_members[LANGUAGE_NONE])) {
      $membercount = (int)$node->field_meetup_members[LANGUAGE_NONE][0]['value'];
    }
    db_merge('groups_membership_stat')
      ->key(array('nid' => $node->nid, 'timestamp' => $timestr, 'datasrc' => 'M'))
      ->fields(array(
        'nid' => $node->nid,
        'timestamp' => $timestr,
        'membercount' => $membercount,
        'datasrc' => 'M',
      ))->execute();
    // update alternate membership data
    $membercount = 0;
    if (isset($node->field_group_members[LANGUAGE_NONE])) {
      $membercount = (int)$node->field_group_members[LANGUAGE_NONE][0]['value'];
    }
    db_merge('groups_membership_stat')
      ->key(array('nid' => $node->nid, 'timestamp' => $timestr, 'datasrc' => 'C'))
      ->fields(array(
        'nid' => $node->nid,
        'timestamp' => $timestr,
        'membercount' => $membercount,
        'datasrc' => 'C',
      ))->execute();
  }
  watchdog('Groups Reports', 'Groups membership statistics had been updated.', array(), WATCHDOG_INFO);
}

/**
 * Implements hook_cronapi()
 *
 * Define groups_reports module's scheduled jobs.
 */
function groups_reports_cronapi($op, $job = NULL) {
  $items['groups_update_membership_stat'] = array(
    'description' => 'Update group membership daily statistcs.',
    'rule'        => '0 4 * * *',
    'callback'    => 'groups_reports_update_membership_stat',
    'arguments'   => array(),
  );
  return $items;
}

/**
 * Return the default date of the membership report.
 *
 * @return string
 *   return the current date if now groups_membership_stat record exists,
 *   otherwise return the most recent date.
 */
function _groups_reports_get_default_membership_date() {
  $query = db_select('groups_membership_stat');
  $query->addExpression('MAX(timestamp)');
  $recent_date = $query->execute()->fetchField();
  if (isset($recent_date)) {
    $recent_ts = DateTime::createFromFormat( 'Ymd', $recent_date, new DateTimeZone('UTC'))
      ->getTimestamp();
  } else {
    $recent_ts = time();
  }
  return gmdate('Y-m-d', $recent_ts);
}

/**
 * Form constructor of groups membership report.
 */
function groups_reports_groups_membership_report_form($form = array(), &$form_state) {
  $form['filter'] = array(
    '#type' => 'fieldset',
    '#title' => t('Report filters'),
    '#attributes' => array('class' => array('container-inline')),
  );
  $form['filter']['date'] = array(
    '#type' => 'date_popup',
    '#title' => t('Report date'),
    '#title_display' => 'invisible',
    '#date_format' => 'Y-m-d',
    '#default_value' => _groups_reports_get_default_membership_date(),
  );
  $form['filter']['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Apply',
  );
  // get filter values
  if (isset($form_state['values'])) {
    $filter_date = $form_state['values']['date'];
  } else {
    $filter_date = $form['filter']['date']['#default_value'];
  }
  $report_date = DateTime::createFromFormat( 'Y-m-d', $filter_date, new DateTimeZone('UTC'))->getTimestamp();
  // build report
  module_load_include('inc', 'field_group_location', 'field_group_lookup');
  $chart_data = array(
    'labels' => array(),
    'datasets' => array(chartjs_create_dataset()),
  );
  $continents = _continent_get_predefined_list();
  $report = groups_report_get_regional_membership_report($report_date);
  $total = 0;
  foreach ($continents as $key => $value) {
    $data[$key] = array();
    $summary[$key] = array(
      'title' => t('<a href="!url">@title</a>', array('!url' => '#'.$key, '@title' => $value)),
      'count' => isset($report['totals'][$key]) ? $report['totals'][$key] : 0,
    );
    $chart_data['labels'][] = $value;
    $chart_data['datasets'][0]->data[] = $summary[$key]['count'];
    $total += $summary[$key]['count'];
  }
  $form['chart'] = array(
    '#type' => 'chart',
    '#labels' => $chart_data['labels'],
    '#datasets' => $chart_data['datasets'],
    '#options' => array('responsive' => true, 'maintainAspectRatio' => false),
  );
  $form['totals'] = array(
    '#prefix' => '<div class="totals-container">',
    '#suffix' => '</div>',
    '#markup' => t('<span class="totals_label">Community members worldwide</span> <span class="total">@total</span> <span class="suffix">people</span>', array('@total' => $total)),
  );
  foreach ($report['rows'] as $row) {
    $data[$row['field_group_location_continent']][] = array(
      'group' => $row['title'],
      'count' => $row['membercount'],
    );
  }
  $header = array(t('User Group'), t('Members'));
  foreach ($continents as $key => $value) {
    $data[$key][] = array(
      'group' => '<b>Total</b>',
      'count' => '<b>'.$summary[$key]['count'].'</b>',
    );
    $form['report_table_'.$key] = array(
      '#prefix' => '<a name="'.$key.'"></a><h3>'.check_plain($value).'</h3>',
      '#theme' => 'table',
      '#header' => $header,
      '#rows' => $data[$key],
      '#sticky' => FALSE,
      '#attributes' => array('id' => 'group-report-continent'),
      '#empty' => t('No membership data available.'),
    );
  }
  return $form;
}

/**
 * Form submit callback of groups membership report
 */
function groups_reports_groups_membership_report_form_submit($form = array(), &$form_state) {
  $form_state['rebuild'] = TRUE;
}

/**
 * Implements group membership history report menu callback.
 */
function groups_reports_groups_membership_history_report() {
  $report = groups_report_get_members_report(time());
  $chart_data = array(
    'labels' => array(),
    'datasets' => array(chartjs_create_dataset()),
  );
  $chart_data['datasets'][0]->strokeColor = '#0099da';
  $chart_data['datasets'][0]->fillColor = '#d7edfb';
  $chart_data['datasets'][0]->pointColor = '#0099da';
  $chart_data['datasets'][0]->pointStrokeColor = '#0099da';
  $chart_data['datasets'][0]->pointHighlightFill = '#000000';
  $chart_data['datasets'][0]->pointHighlightStroke = '#000000';
  foreach ($report as &$item) {
    $item['timestamp'] = format_date($item['timestamp'], 'custom', 'm/d/Y', 'GMT');
    $chart_data['labels'][] = $item['timestamp'];
    $chart_data['datasets'][0]->data[] = $item['count'];
  }
  $report = array_reverse($report);
  $build['chart'] = array(
    '#type' => 'chart',
    '#chart_type' => 'line',
    '#name' => 'membership-history-chart',
    '#height' => '300px',
    '#labels' => $chart_data['labels'],
    '#datasets' => $chart_data['datasets'],
    '#options' => array(
      'responsive' => true,
      'maintainAspectRatio' => false,
      'datasetFill' => true,
      'bezierCurve' => false,
      'datasetStrokeWidth' => 3,
    ),
  );
  $header = array(t('Date'), t('Members'));
  $build['summary_table'] = array(
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => $report,
    '#sticky' => FALSE,
    '#attributes' => array('id' => 'group-report-summary'),
    '#empty' => t('No membership data available.'),
  );
  return $build;
}

/**
 * Construct the date interval array based on a date
 * argument and report period type.
 *
 * @param  $date
 *   last date of the interval
 * @param  $report_period
 *   type of report period like monthly, last 3 months, yearly
 * @return
 *   array of timestamps.
 */
function groups_reports_get_axis_dates($date, $report_period, $timestamp_result = TRUE) {
  $result = array();
  switch ($report_period) {
    case REPORT_PERIOD_MONTHLY:
      for ($i = 0; $i < 30; $i++) {
        $result[] = $date;
        $date -= (24*60*60); // 1day
      }
      break;
    case REPORT_PERIOD_3MONTHS:
      for ($i = 0; $i < 15; $i++) {
        $result[] = $date;
        $date -= (24*60*60)*6; // 6days
      }
      break;
    case REPORT_PERIOD_YEARLY:
      // take 1st day of every month
      $year = (int)gmdate('Y', $date);
      $month = (int)gmdate('n', $date);
      echo "year = $year\n";
      echo "month = $month\n";
      for ($i = 0; $i < 12; $i++) {
        $result[] = gmmktime(0, 0, 0, $month, 1, $year);
        $month--;
        if ($month == 0) {
          $month = 12;
          $year--;
        }
      }
      break;
    default:
      throw new Exeception('Invalid report period');
  }
  if ($timestamp_result == FALSE) {
    array_walk($result, 'groups_reports_transform_gmdate');
  }
  return $result;
}

/**
 * Transform a timestamp to a date string, used as
 * an array_walk() callback.
 */
function groups_reports_transform_gmdate(&$item, $key) {
  $item = gmdate('Ymd', $item);
}

/**
 * Returns an aggregated membership report by date.
 */
function groups_report_get_members_report($date, $report_period = REPORT_PERIOD_MONTHLY) {
  $date_interval = groups_reports_get_axis_dates($date, $report_period);
  $date_interval = array_reverse($date_interval);
  $interval_filter = $date_interval;
  array_walk($interval_filter, 'groups_reports_transform_gmdate');
  $query = db_select('groups_membership_stat', 's');
  $query->fields('s', array('timestamp'));
  $query->condition('s.timestamp', $interval_filter, 'in');
  $query->addExpression('sum(s.membercount)', 'membercount');
  $query->groupBy('s.timestamp');
  $result = $query->execute();
  $rows = array();
  foreach ($date_interval as $ts) {
    $key = gmdate('Ymd', $ts);
    $rows[$key] = array(
      'timestamp' => $ts,
      'count' => 0,
    );
  }
  foreach ($result as $membership) {
    $rows[$membership->timestamp]['count'] = $membership->membercount;
  }
  return $rows;
}

/**
 * Create a regional membership report for a given date.
 */
function groups_report_get_regional_membership_report($date) {
  $query = db_select('node', 'n');
  $query->join('field_data_field_group_location', 'l', 'n.nid = l.entity_id');
  $query->leftJoin('groups_membership_stat', 's', 'n.nid = s.nid');
  $query->fields('n', array('nid', 'title'));
  $query->fields('l', array('field_group_location_continent', 'field_group_location_country'));
  $query->addExpression('sum(s.membercount)', 'membercount');
  $query->condition('n.type', 'group', '=');
  $query->condition('n.status', 1, '=');
  $query->condition('s.timestamp', gmdate('Ymd', $date), '=');
  $query->groupBy('n.title');
  $query->groupBy('n.nid');
  $query->groupBy('l.field_group_location_continent');
  $query->groupBy('l.field_group_location_country');
  $result = $query->execute();
  $rows = array();
  $totals = array();
  foreach ($result as $row) {
    $rows[] = (array)$row;
    if (!isset($totals[$row->field_group_location_continent])) {
      $totals[$row->field_group_location_continent] = 0;
    }
    $totals[$row->field_group_location_continent] += $row->membercount;
  }
  return array(
    'rows' => $rows,
    'totals' => $totals,
  );
}

/**
 * Return organic group members filtered by group role.
 * @param  $gid                 Group Id
 * @param  $role_name           Role name
 * @param  $remove_admin_user   Remove admin user (defaults to TRUE)
 * @return Array of user entities.
 */
function _groups_reports_og_members_by_role($gid, $role_name, $remove_admin_user = TRUE) {
   $query = db_select('og_users_roles', 'ogur');
   $query->innerJoin('og_role', 'ogr', 'ogur.rid = ogr.rid');
   $uids = $query
    ->fields('ogur', array('uid'))
    ->condition('ogr.gid', $gid, '=')
    ->condition('ogr.name', $role_name, '=')
    ->execute()
    ->fetchCol();
  // remove administrator
  if (($key = array_search(1, $uids)) !== false) {
    unset($uids[$key]);
  }
  $users = user_load_multiple($uids);
  return $users;
}

/**
 * Map uid, name, email from a user account.
 */
function _groups_reports_map_users($users) {
  $items = array();
  foreach ($users as $user) {
    $items[] = array(
      'uid' => $user->uid,
      'name' => $user->data['oauth2_fullname'],
      'email' => $user->mail);
  }
  return $items;
}

/**
 * Create a group profile completeness status report.
 */
function groups_reports_group_status_report($filter_status = FALSE) {
  $status_point_max = 3;
  $items = array();
  $query = db_select('node', 'n');
  $query->join('field_data_field_group_location', 'l', 'n.nid = l.entity_id');
  $query->join('field_data_field_group_status', 'gs', 'n.nid = gs.entity_id');
  $query->fields('n', array('nid', 'title'));
  $query->fields('l', array('field_group_location_continent', 'field_group_location_country'));
  $query->fields('gs', array('field_group_status_value'));
  if ($filter_status != FALSE) {
    $status = $filter_status == 'official' ? 1 : 0;
    $query->condition('gs.field_group_status_value', $status, '=');
  }
  $query->condition('n.type', 'group', '=');
  $query->condition('n.status', 1, '=');
  $query->orderBy('l.field_group_location_continent', 'ASC');
  $query->orderBy('n.title', 'ASC');
  $result = $query->execute();
  $rows = array();
  $totals = array();
  foreach ($result as $row) {
    $node = node_load($row->nid);
    $item = new stdClass;
    $item->gid = $node->nid;
    $item->title = $node->title;
    $item->continent = $row->field_group_location_continent;
    $item->group_status = $row->field_group_status_value;
    $item->organizers = _groups_reports_map_users(
      _groups_reports_og_members_by_role($row->nid, 'administrator member'));
    // assign imported organizers
    $v = _groups_reports_extract_resource($node, 19);
    if (isset($v)) {
      $item->organizers_orig = _groups_reports_parse_organizers($v);
    } else {
      $item->organizers_orig = array();
    }
    $uids = array();
    if (isset($node->field_ambassadors[LANGUAGE_NONE][0])) {
      foreach ($node->field_ambassadors[LANGUAGE_NONE] as $user_ref) {
        $uids[] = $user_ref['target_id'];
      }
    }
    $item->ambassadors = _groups_reports_map_users(user_load_multiple($uids));
    // assign social links
    $item->social_links = array();
    if (isset($node->field_resource_links[LANGUAGE_NONE][0])) {
      foreach ($node->field_resource_links[LANGUAGE_NONE] as $resource_link) {
        // except Facebook, Google Plus, Meetup.com, Linkedin here
        if (($resource_link['key'] == 18) || ($resource_link['key'] == 9) ||
                  ($resource_link['key'] == 7) || ($resource_link['key'] == 5)) {
          $item->social_links[] = $resource_link['value'];
        }
      }
    }
    $item->status_messages = array();
    $item->status_point = 0;
    $item->status_point_max = $status_point_max;
    groups_reports_group_status_validate_organizers($item);
    groups_reports_group_status_validate_ambassadors($item);
    groups_reports_group_status_validate_social_links($item);
    $items[] = $item;
  }
  return $items;
}

/**
 * Group status report validation: check organizers
 * +1 if organizers assigned to the group.
 */
function groups_reports_group_status_validate_organizers(&$item) {
  if (count($item->organizers) > 0) {
    $item->status_point++;
  } else {
    $item->status_messages[] = t('No organizers assigned to this group');
  }
}

/**
 * Group status report validation: check ambassadors
 * +1 if ambassadors assigned to the group.
 */
function groups_reports_group_status_validate_ambassadors(&$item) {
  if (count($item->ambassadors) > 0) {
    $item->status_point++;
  } else {
    $item->status_messages[] = t('No Ambassadors assigned to this group');
  }
}

/**
 * Group status report validation: check social links
 * +1 if a Facebook page, Meetup.com group, Linkedin group assigned to group.
 */
function groups_reports_group_status_validate_social_links(&$item) {
  if (count($item->social_links) > 0) {
    $item->status_point++;
  } else {
    $item->status_messages[] = t('No social link assigned to this group');
  }
}

/**
 * Form constructor of group status report
 */
function groups_reports_groups_status_report_form($form = array(), &$form_state) {
  module_load_include('inc', 'field_group_location', 'field_group_lookup');
  $continents = _continent_get_predefined_list();
  $status = (isset($_GET['status'])) ? $_GET['status'] : FALSE;
  $rows = groups_reports_group_status_report($status);
  $totals = new stdClass();
  $totals->points = 0;
  $totals->max = 0;
  foreach ($rows as $row) {
    if ($row->group_status == 1) {
      $row->title = sprintf('%s (official)', $row->title);
    }
    $totals->points += $row->status_point;
    $totals->max += $row->status_point_max;
    $organizers = '';
    foreach ($row->organizers as $organizer) {
      $organizers .= l(sprintf('%s <%s>', $organizer['name'], $organizer['email']), 'user/'.$organizer['uid']).'<br/>';
    }
    $ambassadors = '';
    foreach ($row->ambassadors as $ambassador) {
      $ambassadors .= l(sprintf('%s <%s>', $ambassador['name'], $ambassador['email']), 'user/'.$ambassador['uid']).'<br/>';
    }
    $status_messages = '';
    foreach ($row->status_messages as $msg) {
      $status_messages .= '<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>'.$msg.'<br/>';
    }
    $completeness_class = 'col-status-new';
    if ($row->status_point > 0) {
      $completeness_class = 'col-status-missing';
    }
    if ($row->status_point == $row->status_point_max) {
      $completeness_class = 'col-status-complete';
    }
    $group_url = url(drupal_get_path_alias('node/'.$row->gid), array('absolute' => TRUE));
    $data[$row->continent][] = array(
      'completeness' => array(
        'data' => '',
        'class' => array('col-completeness', $completeness_class)),
      'title' => array(
        'data' => sprintf('<a href="%s">%s</a>', $group_url, $row->title),
        'class' => array('col-user-group')),
      'status' => array(
        'data' => sprintf('<span class="status-point">%d</span><span class="status-max">/%d</span>', $row->status_point, $row->status_point_max),
        'class' => array('col-status')),
      'organizers' => array(
        'data' => $organizers,
        'class' => array('col-organizers')),
      'ambassadors' => array(
        'data' => $ambassadors,
        'class' => array('col-ambassadors')),
      'status_messages' => array(
        'data' => $status_messages,
        'class' => array('col-messages')),
    );
  }
  $total_percents = (int)(($totals->points / $totals->max) * 100+.5);;
  $form['totals'] = array(
    '#prefix' => '<div class="totals-container">',
    '#suffix' => '</div>',
    '#markup' => t('<span class="totals_label">Process level</span> <span class="total">@total</span> <span class="suffix">%</span><br/>Total @points points from maximum @max', array('@total' => $total_percents, '@points' => $totals->points, '@max' => $totals->max)),
  );
  $header = array(
    array('data' => '', 'class' => array('col-completeness')),
    array('data' => t('User Group'), 'class' => array('col-user-group')),
    array('data' => t('Status'), 'class' => array('col-status')),
    array('data' => t('Organizers'), 'class' => array('col-organizers')),
    array('data' => t('Ambassadors'), 'class' => array('col-ambassadors')),
    array('data' => t('Status messages'), 'class' => array('col-messages')),
  );
  foreach ($continents as $key => $value) {
    if (isset($data[$key])) {
      $form['report_table_'.$key] = array(
        '#prefix' => '<a name="'.$key.'"></a><h3>'.check_plain($value).'</h3>',
        '#theme' => 'table',
        '#header' => $header,
        '#rows' => $data[$key],
        '#sticky' => FALSE,
        '#attributes' => array('id' => 'group-report-continent'),
        '#empty' => t('No membership data available.'),
      );
    }
  }
  return $form;
}

/**
 * Display a row of contact data as a csv line.
 */
function _groups_report_contact_csv_row($row, $organizer, $source, &$seen) {
  if (!isset($organizer['email'])) {
    return;
  }
  if (in_array($organizer['email'], $seen) == false) {
    printf("'%s','%s','%s','%s'\n", $row->title, $organizer['name'], $organizer['email'], $source);
    $seen[] = $organizer['email'];
  }
}

/**
 * Export group organizer contacts in CSV format.
 *
 * The groups_contact_report_key variable contains the token required for
 * public access.
 */
function groups_reports_groups_contact_report_csv_export() {
  $access = groups_reports_access();
  // check for token if not authenticated
  if (($access == FALSE) && (isset($_GET['token']))) {
    $access = (variable_get('groups_contact_report_key', 'dummytoken') == $_GET['token']);
  }
  if ($access == FALSE) {
    drupal_access_denied();
    return;
  }
  drupal_add_http_header('Content-Type', 'text/csv; utf-8');
  drupal_add_http_header('Content-Disposition', 'attachment; filename="groups-contacts.csv"');
  $status = (isset($_GET['status'])) ? $_GET['status'] : FALSE;
  $rows = groups_reports_group_status_report($status);
  printf("'%s','%s','%s'\n", 'User group', 'Full name', 'Email', 'Source');
  foreach ($rows as $row) {
    $seen = array();
    foreach ($row->organizers as $organizer) {
      _groups_report_contact_csv_row($row, $organizer, 'db', $seen);
    }
    foreach ($row->organizers_orig as $organizer) {
      _groups_report_contact_csv_row($row, $organizer, 'json', $seen);
    }
  }
  exit;
}

/**
 * Extract resource field value based on key from a group
 * node.
 * @param  $node
 *   source node
 * @param  $resource_id
 *   id of resource to extract from resource field
 * @return string|boolean
 *   string representation of the resource value, or
 *   returns false if not found.
 */
function _groups_reports_extract_resource($node, $resource_id) {
  if (isset($node->field_resource_links[LANGUAGE_NONE])) {
    foreach ($node->field_resource_links[LANGUAGE_NONE] as $resource) {
      if ($resource['key'] == $resource_id) {
        return $resource['value'];
      }
    }
  }
  return FALSE;
}

/**
 * Parse delimiter parsed organizer names into array
 * format.
 * @param  $str
 *   input string
 * @return
 *   parsed output as an array.
 */
function _groups_reports_parse_organizers($str) {
  $organizers = array();
  $elements = explode(';', $str);
  if (isset($elements)) {
    foreach ($elements as $element) {
      $organizer['name'] = trim(strip_tags($element));
      preg_match('#\<(.*?)\>#', $element, $match);
      if (isset($match[1])) {
        $organizer['email'] = $match[1];
      }
      if (!empty($organizer['name'])) {
        $organizers[] = $organizer;
      }
    }
  }
  return $organizers;
}
