public function view() { parent::view(FALSE); if (isset($this->mode)) { $section = $this->mode; header('Content-Type: application/json'); echo file_get_contents(WORKSPACE . '/elasticsearch/mappings/' . $section . '.json'); die; } $this->addScriptToHead(URL . '/extensions/elasticsearch/assets/elasticsearch.mappings.js', 101); $this->addStylesheetToHead(URL . '/extensions/elasticsearch/assets/elasticsearch.mappings.css', 'screen', 102); $this->setPageType('table'); $this->setTitle(__('Symphony') . ' – ' . __('ElasticSearch') . ' – ' . __('Mappings')); $this->appendSubheading(__('Mappings')); $types = ElasticSearch::getAllTypes(); $tableHead = array(); $tableBody = array(); $tableHead[] = array(__('Section'), 'col'); $tableHead[] = array(__('Mapped Fields'), 'col'); $tableHead[] = array(__('Mapping JSON'), 'col'); $tableHead[] = array(__('Entries'), 'col'); if (!is_array($types) or empty($types)) { $tableBody = array(Widget::TableRow(array(Widget::TableData(__('None Found.'), 'inactive', null, count($tableHead))))); } else { foreach ($types as $type) { $col_name = Widget::TableData($type->section->get('name')); $col_name->appendChild(Widget::Input('items[' . $type->section->get('handle') . ']', NULL, 'checkbox')); $col_fields = Widget::TableData(implode(', ', $type->fields)); $col_json = Widget::TableData(sprintf('<a href="%s">%s.json</a>', $type->section->get('handle'), $type->section->get('handle'))); if ($type->type) { $count = $type->type->count(); $col_count = Widget::TableData('<span id="reindex-' . $type->section->get('handle') . '">' . (string) $count . ' ' . ($count == 1 ? 'entry' : 'entries') . '</span>', $count_class . ' count-column'); } else { $col_count = Widget::TableData('Rebuild mapping before continuing', $count_class . ' count-column inactive'); } $attributes = array('data-handle' => $type->section->get('handle')); if (in_array($type->section->get('handle'), $this->reindex) && $type->type) { $attributes['data-reindex'] = 'yes'; } $tableBody[] = Widget::TableRow(array($col_name, $col_fields, $col_json, $col_count), NULL, NULL, NULL, $attributes); } } $table = Widget::Table(Widget::TableHead($tableHead), null, Widget::TableBody($tableBody), 'selectable'); $this->Form->appendChild($table); $actions = new XMLElement('div'); $actions->setAttribute('class', 'actions'); $options = array(array(null, false, __('With Selected...')), array('reindex', false, __('Reindex Entries')), array('rebuild', false, __('Rebuild Mapping')), array('delete', false, __('Delete Mapping'))); $actions->appendChild(Widget::Apply($options)); $this->Form->appendChild($actions); }
public function view() { $this->addStylesheetToHead(URL . '/extensions/elasticsearch/assets/elasticsearch.stats.css', 'screen', 102); $this->addStylesheetToHead(URL . '/extensions/elasticsearch/assets/elasticsearch.drawer.css', 'screen', 103); $this->addScriptToHead(URL . '/extensions/elasticsearch/assets/elasticsearch.drawer.js', 103); $this->addScriptToHead(URL . '/extensions/elasticsearch/assets/elasticsearch.jquery.ui.js', 104); $this->addStylesheetToHead(URL . '/extensions/elasticsearch/assets/elasticsearch.jquery.daterangepicker.css', 'screen', 105); $this->addScriptToHead(URL . '/extensions/elasticsearch/assets/elasticsearch.jquery.daterangepicker.js', 106); parent::view(FALSE); // Get URL parameters, set defaults /*-----------------------------------------------------------------------*/ $sort = (object) $_GET['sort']; $filter = (object) $_GET['filter']; $pagination = (object) $_GET['pagination']; if (!isset($sort->column)) { $sort->column = 'count'; } if (!isset($sort->direction)) { $sort->direction = 'desc'; } if (!isset($filter->keywords) || empty($filter->keywords)) { $filter->keywords = NULL; } if (!isset($filter->date_from) || empty($filter->date_from)) { $filter->date_from = date('Y-m-d', strtotime('last month')); } if (!isset($filter->date_to) || empty($filter->date_to)) { $filter->date_to = date('Y-m-d', strtotime('today')); } if (!isset($filter->average_results['value']) || !is_numeric($filter->average_results['value'])) { $filter->average_results = NULL; } if (!isset($filter->average_depth['value']) || !is_numeric($filter->average_depth['value'])) { $filter->average_depth = NULL; } if (is_array($filter->average_results)) { $filter->average_results = implode('', $filter->average_results); } if (is_array($filter->average_depth)) { $filter->average_depth = implode('', $filter->average_depth); } $output_mode = $_GET['output']; if (!isset($output_mode)) { $output_mode = 'table'; } // Build pagination and fetch rows /*-----------------------------------------------------------------------*/ $pagination->{'per-page'} = 50; $pagination->{'current-page'} = @(int) $pagination->{'current-page'} > 1 ? (int) $pagination->{'current-page'} : 1; // get the logs! $rows = ElasticSearchLogs::getQueries($sort->column, $sort->direction, $pagination->{'current-page'}, $pagination->{'per-page'}, $filter); // total number of unique query terms $query_stats = ElasticSearchLogs::getTotalQueries($filter); //var_dump($query_stats);die; $pagination->{'total-entries'} = $query_stats->total; $pagination->start = max(1, ($pagination->{'current-page'} - 1) * $pagination->{'per-page'}); $pagination->end = $pagination->start == 1 ? $pagination->{'per-page'} : $pagination->start + count($rows); $pagination->{'total-pages'} = ceil($pagination->{'total-entries'} / $pagination->{'per-page'}); // sum of the "count" column for all queries i.e. total number of searches $total_search_count = ElasticSearchLogs::getSearchCount($filter); // cache amended filters for use elsewhere $this->sort = $sort; $this->filter = $filter; $this->pagination = $pagination; // Set up page meta data /*-----------------------------------------------------------------------*/ $this->setPageType('table'); $this->setTitle(__('Symphony') . ' – ' . __('ElasticSearch') . ' – ' . __('Query Logs')); $this->insertDrawer(Widget::Drawer('elasticsearch', __('Filter Queries'), $this->__buildDrawerHTML($filter), 'opened'), 'horizontal'); $this->appendSubheading(__('Query Logs'), Widget::Anchor(__('Export CSV'), $this->__buildURL(NULL, array('output' => 'csv')), NULL, 'button')); // Build summary /*-----------------------------------------------------------------------*/ $stats = new XMLElement('ul'); $stats->appendChild(new XMLElement('li', __("<span>%s</span> unique queries from <span>%s</span> sessions.", array(number_format($query_stats->total), number_format($total_search_count))))); $stats->appendChild(new XMLElement('li', __("Average <span>%s</span> characters per query.", array((int) $query_stats->average_length)))); $stats->appendChild(new XMLElement('li', __("Average <span>%s</span> results retrieved per search.", array(number_format($query_stats->average_results, 1))))); $stats->appendChild(new XMLElement('li', __("Average search depth <span>%s</span> pages.", array(number_format($query_stats->average_depth, 1))))); $summary = new XMLElement('div', NULL, array('class' => 'summary')); $summary->appendChild($stats); $this->Form->appendChild($summary); // Build table /*-----------------------------------------------------------------------*/ $tableHead = array(); $tableBody = array(); // append table headings $tableHead[] = array(__('Rank'), 'col'); $tableHead[] = $this->__buildColumnHeader(__('Query'), 'keywords', 'asc'); $tableHead[] = $this->__buildColumnHeader(__('Query (Raw)'), 'keywords', 'asc'); $tableHead[] = $this->__buildColumnHeader(__('Frequency'), 'count', 'desc'); $tableHead[] = array(__('%'), 'col'); $tableHead[] = array(__('Cumulative %'), 'col'); $tableHead[] = $this->__buildColumnHeader(__('Avg. results'), 'average_results', 'desc'); $tableHead[] = $this->__buildColumnHeader(__('Avg. depth'), 'average_depth', 'desc'); // no rows if (!is_array($rows) or empty($rows)) { $tableBody = array(Widget::TableRow(array(Widget::TableData(__('None Found.'), 'inactive', NULL, count($tableHead))))); } else { // if not on the first page, the cululative percent column needs to start from the // column total of the previous page. Calling this method queries a dataset the size // of all previous pages, sums and returns the totals from all if ($pagination->{'current-page'} > 1) { $cumulative_total = ElasticSearchLogs::getCumulativeSearchCount($sort->column, $sort->direction, $pagination->{'current-page'}, $pagination->{'per-page'}, $filter); } // rank starts from 1 on first page $rank = $pagination->start == 1 ? $pagination->start : $pagination->start + 1; // initial percentage to start from (cumulative) $cumulative_percent = $cumulative_total / $total_search_count * 100; foreach ($rows as $row) { $row_percent = $row['count'] / $total_search_count * 100; $cumulative_percent += $row_percent; $r = array(); $r[] = Widget::TableData($rank, 'rank'); $r[] = Widget::TableData(empty($row['keywords']) ? __('None') : stripslashes($row['keywords']), empty($row['keywords']) ? 'inactive query' : 'query'); $r[] = Widget::TableData(empty($row['keywords']) ? __('None') : htmlentities(stripslashes($row['keywords_raw'])), 'inactive query'); $r[] = Widget::TableData($row['count'], 'count'); $r[] = Widget::TableData(number_format($row_percent, 2) . '%', 'percent'); $r[] = Widget::TableData(number_format($cumulative_percent, 2) . '%', 'percent'); $r[] = Widget::TableData(number_format($row['average_results'], 1), 'average-results'); $r[] = Widget::TableData(number_format($row['average_depth'], 1), 'average-depth'); $tableBody[] = Widget::TableRow($r); $rank++; } } if ($output_mode == 'csv') { $file_path = sprintf('%s/search-index.query-log.%d.csv', TMP, time()); $csv = fopen($file_path, 'w'); $columns = array(); foreach ($tableHead as $i => $heading) { $element = reset($heading); if ($element instanceof XMLElement) { $columns[] = reset($heading)->getValue(); } else { $columns[] = (string) $element; } } fputcsv($csv, $columns, ',', '"'); foreach ($tableBody as $tr) { $cells = $tr->getChildren(); $data = array(); foreach ($cells as $td) { $data[] = $td->getValue(); } fputcsv($csv, $data, ',', '"'); } fclose($csv); header('Content-type: application/csv'); header('Content-Disposition: attachment; filename="' . end(explode('/', $file_path)) . '"'); readfile($file_path); unlink($file_path); exit; } // append the table $table = Widget::Table(Widget::TableHead($tableHead), NULL, Widget::TableBody($tableBody)); $this->Form->appendChild($table); $this->Form->appendChild(new XMLElement('div', NULL, array('class' => 'actions'))); // build pagination if ($pagination->{'total-pages'} > 1) { $this->Form->appendChild($this->__buildPagination($pagination)); } }
public function view() { $this->addStylesheetToHead(URL . '/extensions/elasticsearch/assets/elasticsearch.stats.css', 'screen', 102); $this->addStylesheetToHead(URL . '/extensions/elasticsearch/assets/elasticsearch.drawer.css', 'screen', 103); $this->addScriptToHead(URL . '/extensions/elasticsearch/assets/elasticsearch.drawer.js', 103); $this->addScriptToHead(URL . '/extensions/elasticsearch/assets/elasticsearch.jquery.ui.js', 104); $this->addStylesheetToHead(URL . '/extensions/elasticsearch/assets/elasticsearch.jquery.daterangepicker.css', 'screen', 105); $this->addScriptToHead(URL . '/extensions/elasticsearch/assets/elasticsearch.jquery.daterangepicker.js', 106); parent::view(FALSE); // Get URL parameters, set defaults /*-----------------------------------------------------------------------*/ $sort = (object) $_GET['sort']; $filter = (object) $_GET['filter']; $pagination = (object) $_GET['pagination']; if (!isset($sort->column)) { $sort->column = 'date'; } if (!isset($sort->direction)) { $sort->direction = 'desc'; } if (!isset($filter->keywords) || empty($filter->keywords)) { $filter->keywords = NULL; } if (!isset($filter->date_from) || empty($filter->date_from)) { $filter->date_from = date('Y-m-d', strtotime('last month')); } if (!isset($filter->date_to) || empty($filter->date_to)) { $filter->date_to = date('Y-m-d', strtotime('today')); } if (!isset($filter->results['value']) || !is_numeric($filter->results['value'])) { $filter->results = NULL; } if (!isset($filter->depth['value']) || !is_numeric($filter->depth['value'])) { $filter->depth = NULL; } if (!isset($filter->session_id) || empty($filter->session_id)) { $filter->session_id = NULL; } if (!isset($filter->user_agent) || empty($filter->user_agent)) { $filter->user_agent = NULL; } if (!isset($filter->ip) || empty($filter->ip)) { $filter->ip = NULL; } if (is_array($filter->results)) { $filter->results = implode('', $filter->results); } if (is_array($filter->depth)) { $filter->depth = implode('', $filter->depth); } $output_mode = $_GET['output']; if (!isset($output_mode)) { $output_mode = 'table'; } // Build pagination and fetch rows /*-----------------------------------------------------------------------*/ $pagination->{'per-page'} = (int) Symphony::Configuration()->get('pagination_maximum_rows', 'symphony'); $pagination->{'current-page'} = @(int) $pagination->{'current-page'} > 1 ? (int) $pagination->{'current-page'} : 1; // get the logs! $rows = ElasticSearchLogs::getSessions($sort->column, $sort->direction, $pagination->{'current-page'}, $pagination->{'per-page'}, $filter); // total number of unique query terms $pagination->{'total-entries'} = ElasticSearchLogs::getTotalSessions($filter); $pagination->start = max(1, ($pagination->{'current-page'} - 1) * $pagination->{'per-page'}); $pagination->end = $pagination->start == 1 ? $pagination->{'per-page'} : $pagination->start + count($rows); $pagination->{'total-pages'} = ceil($pagination->{'total-entries'} / $pagination->{'per-page'}); // cache amended filters for use elsewhere $this->sort = $sort; $this->filter = $filter; $this->pagination = $pagination; // Set up page meta data /*-----------------------------------------------------------------------*/ $this->setPageType('table'); $this->setTitle(__('Symphony') . ' – ' . __('ElasticSearch') . ' – ' . __('Session Logs')); $this->insertDrawer(Widget::Drawer('elasticsearch', __('Filter Sessions'), $this->__buildDrawerHTML($filter), 'opened'), 'horizontal'); $this->appendSubheading(__('Session Logs'), Widget::Anchor(__('Export CSV'), $this->__buildURL(NULL, array('output' => 'csv')), NULL, 'button')); $tableHead = array(); $tableBody = array(); // append table headings $tableHead[] = $this->__buildColumnHeader(__('Date'), 'date', 'desc'); $tableHead[] = array(__('Query'), 'keywords'); $tableHead[] = $this->__buildColumnHeader(__('Results'), 'results', 'desc'); $tableHead[] = $this->__buildColumnHeader(__('Depth'), 'depth', 'desc'); $tableHead[] = array(__('Session ID')); $tableHead[] = array(__('IP Address')); $tableHead[] = array(__('Browser')); if (!is_array($rows) or empty($rows)) { $tableBody = array(Widget::TableRow(array(Widget::TableData(__('None Found.'), 'inactive', null, count($tableHead))))); } else { $browscap = new Browscap(CACHE); $alt = FALSE; foreach ($rows as $row) { if (!empty($row['user_agent'])) { $browser = $browscap->getBrowser($row['user_agent']); $browser_string = sprintf('%s %s (%s)', $browser->Browser, $browser->MajorVer, $browser->Platform); } else { $browser_string = ''; } $searches = ElasticSearchLogs::getSessionSearches($row['session_id']); foreach ($searches as $i => $search) { $r = array(); //$r[] = Widget::TableData('', NULL, NULL, 3); $r[] = Widget::TableData(DateTimeObj::get(__SYM_DATETIME_FORMAT__, strtotime($search['date'])), 'date'); $keywords = $search['keywords']; $keywords_class = ''; if ($keywords == '') { $keywords = __('None'); $keywords_class = 'inactive'; } $r[] = Widget::TableData(stripslashes($keywords), $keywords_class . ' keywords'); $r[] = Widget::TableData($search['results'], 'results'); $r[] = Widget::TableData($search['page'], 'depth'); if ($i == 0) { $r[] = Widget::TableData($row['session_id'], 'inactive'); $r[] = Widget::TableData(empty($row['ip']) ? __('None') : $row['ip'], 'inactive'); $r[] = Widget::TableData(empty($browser_string) ? __('None') : '<span title="' . $row['user_agent'] . '">' . $browser_string . '</span>', 'inactive'); } else { $r[] = Widget::TableData('', NULL, NULL, 3); } $tableBody[] = Widget::TableRow($r, 'search ' . ($alt ? 'alt' : '') . ($i == count($searches) - 1 ? ' last' : '')); } $alt = !$alt; } } if ($output_mode == 'csv') { $file_path = sprintf('%s/search-index.session-log.%d.csv', TMP, time()); $csv = fopen($file_path, 'w'); $columns = array(); foreach ($tableHead as $i => $heading) { $element = reset($heading); if ($element instanceof XMLElement) { $columns[] = reset($heading)->getValue(); } else { $columns[] = (string) $element; } } $columns[] = 'Session ID'; $columns[] = 'User Agent'; $columns[] = 'IP'; fputcsv($csv, $columns, ',', '"'); $meta = array(); foreach ($tableBody as $tr) { $cells = $tr->getChildren(); if (preg_match("/session-meta/", $tr->getAttribute('class'))) { $meta = array(); foreach ($cells as $i => $td) { switch ($i) { case 0: $meta['session_id'] = $td->getValue(); break; case 1: $meta['user_agent'] = $td->getValue(); break; case 2: $meta['ip'] = $td->getValue(); break; } } } else { $data = array(); foreach ($cells as $td) { $data[] = $td->getValue(); } $data[] = $meta['session_id']; $data[] = $meta['user_agent']; $data[] = $meta['ip']; fputcsv($csv, $data, ',', '"'); } } fclose($csv); header('Content-type: application/csv'); header('Content-Disposition: attachment; filename="' . end(explode('/', $file_path)) . '"'); readfile($file_path); unlink($file_path); exit; } $table = Widget::Table(Widget::TableHead($tableHead), NULL, Widget::TableBody($tableBody), 'sessions'); $this->Form->appendChild($table); $this->Form->appendChild(new XMLElement('div', NULL, array('class' => 'actions'))); // build pagination if ($pagination->{'total-pages'} > 1) { $this->Form->appendChild($this->__buildPagination($pagination)); } }