public function appendDocs($context) { $current_page_url = str_replace(SYMPHONY_URL, '', Administration::instance()->getCurrentPageURL()); if (preg_match('/edit/', $current_page_url)) { $pos = strripos($current_page_url, '/edit/'); $current_page_url = substr($current_page_url, 0, $pos + 6); } $pages = Symphony::Database()->fetch("\n\t\t\t\tSELECT\n\t\t\t\t\td.pages, d.id\n\t\t\t\tFROM\n\t\t\t\t\t`tbl_documentation` AS d\n\t\t\t\tORDER BY\n\t\t\t\t\td.pages ASC\n\t\t\t"); foreach ($pages as $key => $value) { if (strstr($value['pages'], ',')) { $list = explode(',', $value['pages']); foreach ($list as $item) { $pages[] = array('id' => $value['id'], 'page' => $item); } unset($pages[$key]); } } ### # Delegate: appendDocsPre # Description: Allow other extensions to add their own documentation page Symphony::ExtensionManager()->notifyMembers('appendDocsPre', '/backend/', array('pages' => &$pages)); // Fetch documentation items $items = array(); foreach ($pages as $page) { if (in_array($current_page_url, $page)) { if (isset($page['id'])) { $items[] = Symphony::Database()->fetchRow(0, "\n\t\t\t\t\t\t\tSELECT\n\t\t\t\t\t\t\t\td.title, d.content_formatted\n\t\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\t\t`tbl_documentation` AS d\n \t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t d.id = '{$page['id']}'\n\t\t\t\t\t\t\tLIMIT 1\n\t\t\t\t\t\t "); } else { ### # Delegate: appendDocsPost # Description: Allows other extensions to insert documentation for the $current_page_url Administration::instance()->ExtensionManager->notifyMembers('appendDocsPost', '/backend/', array('doc_item' => &$doc_items)); } } } // Allows a page to have more then one documentation source if (!empty($items)) { // Generate documentation panel $docs = new XMLElement('div', NULL, array('id' => 'documenter-drawer')); foreach ($items as $item) { // Add title if (isset($item['title'])) { $docs->appendChild(new XMLElement('h2', $item['title'])); } // Add formatted help text $docs->appendChild(new XMLElement('div', $item['content_formatted'], array('class' => 'documenter-content'))); } $button = Symphony::Configuration()->get('button-text', 'Documentation'); $drawer = Widget::Drawer('documenter', $button != '' ? $button : __('Documentation'), $docs, 'closed'); Administration::instance()->Page->insertDrawer($drawer, 'vertical-right'); } }
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)); } }
/** * Prepare a Drawer to visualize section associations * * @param Section $section The current Section object * @throws InvalidArgumentException * @throws Exception */ private function prepareAssociationsDrawer($section) { $entry_id = !is_null($this->_context['entry_id']) ? $this->_context['entry_id'] : null; $show_entries = Symphony::Configuration()->get('association_maximum_rows', 'symphony'); if (is_null($entry_id) && !isset($_GET['prepopulate']) || is_null($show_entries) || $show_entries == 0) { return; } $parent_associations = SectionManager::fetchParentAssociations($section->get('id'), true); $child_associations = SectionManager::fetchChildAssociations($section->get('id'), true); $content = null; $drawer_position = 'vertical-right'; /** * Prepare Associations Drawer from an Extension * * @since Symphony 2.3.3 * @delegate PrepareAssociationsDrawer * @param string $context * '/publish/' * @param integer $entry_id * The entry ID or null * @param array $parent_associations * Array of Sections * @param array $child_associations * Array of Sections * @param string $drawer_position * The position of the Drawer, defaults to `vertical-right`. Available * values of `vertical-left, `vertical-right` and `horizontal` */ Symphony::ExtensionManager()->notifyMembers('PrepareAssociationsDrawer', '/publish/', array('entry_id' => $entry_id, 'parent_associations' => &$parent_associations, 'child_associations' => &$child_associations, 'content' => &$content, 'drawer-position' => &$drawer_position)); // If there are no associations, return now. if ((is_null($parent_associations) || empty($parent_associations)) && (is_null($child_associations) || empty($child_associations))) { return; } if (!$content instanceof XMLElement) { $content = new XMLElement('div', null, array('class' => 'content')); $content->setSelfClosingTag(false); // Process Parent Associations if (!is_null($parent_associations) && !empty($parent_associations)) { foreach ($parent_associations as $as) { if ($field = FieldManager::fetch($as['parent_section_field_id'])) { if (isset($_GET['prepopulate'])) { $prepopulate_field = key($_GET['prepopulate']); } // get associated entries if entry exists, if ($entry_id) { $entry_ids = $field->findParentRelatedEntries($as['child_section_field_id'], $entry_id); // get prepopulated entry otherwise } elseif (isset($_GET['prepopulate'])) { $entry_ids = array(intval(current($_GET['prepopulate']))); } else { $entry_ids = array(); } // Use $schema for perf reasons $schema = array($field->get('element_name')); $where = !empty($entry_ids) ? sprintf(' AND `e`.`id` IN (%s)', implode(', ', $entry_ids)) : null; $entries = !empty($entry_ids) || isset($_GET['prepopulate']) && $field->get('id') === $prepopulate_field ? EntryManager::fetchByPage(1, $as['parent_section_id'], $show_entries, $where, null, false, false, true, $schema) : array(); $has_entries = !empty($entries) && $entries['total-entries'] != 0; if ($has_entries) { $element = new XMLElement('section', null, array('class' => 'association parent')); $header = new XMLElement('header'); $header->appendChild(new XMLElement('p', __('Linked to %s in', array('<a class="association-section" href="' . SYMPHONY_URL . '/publish/' . $as['handle'] . '/">' . $as['name'] . '</a>')))); $element->appendChild($header); $ul = new XMLElement('ul', null, array('class' => 'association-links', 'data-section-id' => $as['child_section_id'], 'data-association-ids' => implode(', ', $entry_ids))); foreach ($entries['records'] as $e) { // let the field create the mark up $li = $field->prepareAssociationsDrawerXMLElement($e, $as); // add it to the unordered list $ul->appendChild($li); } $element->appendChild($ul); $content->appendChild($element); } } } } // Process Child Associations if (!is_null($child_associations) && !empty($child_associations)) { foreach ($child_associations as $as) { // Get the related section $child_section = SectionManager::fetch($as['child_section_id']); if (!$child_section instanceof Section) { continue; } // Get the visible field instance (using the sorting field, this is more flexible than visibleColumns()) // Get the link field instance $visible_field = current($child_section->fetchVisibleColumns()); $relation_field = FieldManager::fetch($as['child_section_field_id']); // Get entries, using $schema for performance reasons. $entry_ids = $relation_field->findRelatedEntries($entry_id, $as['parent_section_field_id']); $schema = $visible_field ? array($visible_field->get('element_name')) : array(); $where = sprintf(' AND `e`.`id` IN (%s)', implode(', ', $entry_ids)); $entries = !empty($entry_ids) ? EntryManager::fetchByPage(1, $as['child_section_id'], $show_entries, $where, null, false, false, true, $schema) : array(); $has_entries = !empty($entries) && $entries['total-entries'] != 0; // Build the HTML of the relationship $element = new XMLElement('section', null, array('class' => 'association child')); $header = new XMLElement('header'); $filter = '?filter[' . $relation_field->get('element_name') . ']=' . $entry_id; $prepopulate = '?prepopulate[' . $as['child_section_field_id'] . ']=' . $entry_id; // Create link with filter or prepopulate $link = SYMPHONY_URL . '/publish/' . $as['handle'] . '/' . $filter; $a = new XMLElement('a', $as['name'], array('class' => 'association-section', 'href' => $link)); // Create new entries $create = new XMLElement('a', __('Create New'), array('class' => 'button association-new', 'href' => SYMPHONY_URL . '/publish/' . $as['handle'] . '/new/' . $prepopulate)); // Display existing entries if ($has_entries) { $header->appendChild(new XMLElement('p', __('Links in %s', array($a->generate())))); $ul = new XMLElement('ul', null, array('class' => 'association-links', 'data-section-id' => $as['child_section_id'], 'data-association-ids' => implode(', ', $entry_ids))); foreach ($entries['records'] as $key => $e) { // let the first visible field create the mark up if ($visible_field) { $li = $visible_field->prepareAssociationsDrawerXMLElement($e, $as, $prepopulate); } else { $li = Field::createAssociationsDrawerXMLElement($e->get('id'), $e, $as, $prepopulate); } // add it to the unordered list $ul->appendChild($li); } $element->appendChild($ul); // If we are only showing 'some' of the entries, then show this on the UI if ($entries['total-entries'] > $show_entries) { $pagination = new XMLElement('li', null, array('class' => 'association-more', 'data-current-page' => '1', 'data-total-pages' => ceil($entries['total-entries'] / $show_entries), 'data-total-entries' => $entries['total-entries'])); $counts = new XMLElement('a', __('Show more entries'), array('href' => $link)); $pagination->appendChild($counts); $ul->appendChild($pagination); } // No entries } else { $element->setAttribute('class', 'association child empty'); $header->appendChild(new XMLElement('p', __('No links in %s', array($a->generate())))); } $header->appendChild($create); $element->prependChild($header); $content->appendChild($element); } } } $drawer = Widget::Drawer('section-associations', __('Show Associations'), $content); $this->insertDrawer($drawer, $drawer_position, 'prepend'); }
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)); } }
/** * Add publish filter */ public function initaliseAdminPageHead($context) { $page = Administration::instance()->Page; $callback = Administration::instance()->getPageCallback(); // Include filter? if ($page instanceof contentPublish && $callback['context']['page'] == 'index') { $sm = new SectionManager(Symphony::Engine()); $section_handle = $page->_context['section_handle']; $section_id = $sm->fetchIDFromHandle($section_handle); if (!$section_id) { return; } $section = $sm->fetch($section_id); $fields = array(); // Section is filterable //if($section->get('filterable') == 'yes') { foreach ($section->fetchFilterableFields() as $field) { if (in_array($field->get('type'), $this->_incompatible_publishpanel)) { continue; } $fields[$field->get('label')]['handle'] = General::sanitize($field->get('element_name')); $html = new XMLElement('html'); /* fields can choose to use getDefaultPublishContent to return a list values only, if their displayPublishPanel HTML is complex https://github.com/nickdunn/publishfiltering/issues/4 */ if (method_exists($field, 'getDefaultPublishContent')) { $field->getDefaultPublishContent($html); } else { $field->displayPublishPanel($html); } // filter out some HTML nasties $html = preg_replace('/&(?!(#[0-9]+|#x[0-9a-f]+|amp|lt|gt);)/i', '&', $html->generate()); $dom = new DomDocument(); libxml_use_internal_errors(true); $dom->loadXML($html); $xml_errors = libxml_get_errors(); // XML is malformed, skip this field :-( if (!empty($xml_errors)) { continue; } $xpath = new DomXPath($dom); $count = 0; foreach ($xpath->query("//*[name()='option'] | //*[name()='li']") as $option) { $value = ''; if ($option->getAttribute('value')) { $value = $option->getAttribute('value'); } else { $value = $option->nodeValue; } if ($value != '') { $fields[$field->get('label')]['options'][$count]['label'] = $option->nodeValue; $fields[$field->get('label')]['options'][$count]['value'] = $value; $count++; } } if ($field->get('type') == 'checkbox') { $fields[$field->get('label')]['options'][] = 'Yes'; $fields[$field->get('label')]['options'][] = 'No'; } } $page->addElementToHead(new XMLElement('script', "Symphony.Context.add('publishfiltering', " . json_encode($fields) . ")", array('type' => 'text/javascript')), 92370001); $page->addStylesheetToHead(URL . '/extensions/publishfiltering/assets/publishfiltering.publish.css', 'screen', 92370002); $page->addScriptToHead(URL . '/extensions/publishfiltering/assets/publishfiltering.publish.js', 92370003); $page->insertDrawer(Widget::Drawer('publish-filtering', __('Filter Entries'), NULL, 'closed', $section_handle), 'horizontal'); //} } }
public function __viewIndex() { $this->setPageType('table'); $this->setTitle(__('Symphony') . ' – ' . __('Search Indexes')); $page = @(int) $_GET['pg'] > 1 ? (int) $_GET['pg'] : 1; $page_size = (int) Symphony::Configuration()->get('pagination_maximum_rows', 'symphony'); $sort_column = 'date'; $sort_order = 'desc'; $filter_keywords = ''; $filter_view = ''; if (isset($_GET['sort'])) { $sort_column = $_GET['sort']; } if (isset($_GET['order'])) { $sort_order = $_GET['order']; } if (isset($_GET['keywords'])) { $filter_keywords = $_GET['keywords']; } if (isset($_GET['view'])) { $filter_view = $_GET['view']; } $logs = SearchIndex::getLogs($sort_column, $sort_order, $filter_view == 'export' ? NULL : $page, $filter_keywords); if ($filter_view == 'export') { $file_path = sprintf('%s/search-index.log.%d.csv', TMP, time()); $csv = fopen($file_path, 'w'); fputcsv($csv, array(__('Date'), __('Keywords'), __('Adjusted Keywords'), __('Results'), __('Depth'), __('Session ID')), ',', '"'); foreach ($logs as $log) { fputcsv($csv, array($log['date'], $log['keywords'], $log['keywords_manipulated'], $log['results'], $log['depth'], $log['session_id']), ',', '"'); } fclose($csv); header('Content-type: application/csv'); header('Content-Disposition: attachment; filename="' . end(explode('/', $file_path)) . '"'); readfile($file_path); unlink($file_path); exit; } $start = max(1, ($page - 1) * $page_size); $end = $start == 1 ? $page_size : $start + count($logs); $total = SearchIndex::countLogs($filter_keywords); $pages = ceil($total / $page_size); $filter_form = Widget::Form($this->_uri . '/logs/', 'get'); $filters = new XMLElement('div', NULL, array('class' => 'search-index-log-filters')); $label = new XMLElement('label', __('Filter searches containing the keywords %s', array(Widget::Input('keywords', $filter_keywords)->generate()))); $filters->appendChild($label); $filters->appendChild(new XMLElement('input', NULL, array('type' => 'submit', 'value' => __('Filter'), 'class' => 'create button'))); $filters->appendChild(Widget::Anchor(__('Clear'), $this->_uri . '/logs/', NULL, 'button clear')); $filter_form->appendChild($filters); $this->insertDrawer(Widget::Drawer('search_index', __('Filter Logs'), $filter_form, 'opened'), 'horizontal'); $this->appendSubheading(__('Logs'), Widget::Anchor(__('Export CSV'), $this->_uri . '/logs/?view=export&sort=' . $sort_column . '&order=' . $sort_order . '&keywords=' . $filter_keywords, NULL, 'button')); $stats = array('unique-users' => SearchIndex::getStatsCount('unique-users', $filter_keywords), 'unique-searches' => SearchIndex::getStatsCount('unique-searches', $filter_keywords), 'unique-terms' => SearchIndex::getStatsCount('unique-terms', $filter_keywords), 'average-results' => SearchIndex::getStatsCount('average-results', $filter_keywords)); $this->addStylesheetToHead(URL . '/extensions/search_index/assets/search_index.css', 'screen', 100); $this->Form->appendChild(new XMLElement('p', sprintf(__('<strong>%s</strong> unique searches from <strong>%s</strong> unique users via <strong>%s</strong> distinct search terms. Each search yielded an average of <strong>%s</strong> results.', array($stats['unique-searches'], $stats['unique-users'], $stats['unique-terms'], $stats['average-results']))), array('class' => 'intro'))); $tableHead = array(); $tableBody = array(); $tableHead = array(array(Widget::Anchor(__('Date'), Administration::instance()->getCurrentPageURL() . '?pg=1&sort=date&order=' . ($sort_column == 'date' && $sort_order == 'desc' ? 'asc' : 'desc') . '&keywords=' . $filter_keywords, '', $sort_column == 'date' ? 'active' : ''), 'col'), array(Widget::Anchor(__('Keywords'), Administration::instance()->getCurrentPageURL() . '?pg=1&sort=keywords&order=' . ($sort_column == 'keywords' && $sort_order == 'asc' ? 'desc' : 'asc') . '&keywords=' . $filter_keywords, '', $sort_column == 'keywords' ? 'active' : ''), 'col'), array(__('Adjusted Keywords'), 'col'), array(Widget::Anchor(__('Results'), Administration::instance()->getCurrentPageURL() . '?pg=1&sort=results&order=' . ($sort_column == 'results' && $sort_order == 'desc' ? 'asc' : 'desc') . '&keywords=' . $filter_keywords, '', $sort_column == 'results' ? 'active' : ''), 'col'), array(Widget::Anchor(__('Depth'), Administration::instance()->getCurrentPageURL() . '?pg=1&sort=depth&order=' . ($sort_column == 'depth' && $sort_order == 'desc' ? 'asc' : 'desc') . '&keywords=' . $filter_keywords, '', $sort_column == 'depth' ? 'active' : ''), 'col'), array(__('Session ID'), 'col')); if (!is_array($logs) or empty($logs)) { $tableBody = array(Widget::TableRow(array(Widget::TableData(__('None Found.'), 'inactive', null, count($tableHead))))); } else { foreach ($logs as $hash => $log) { $row = array(); $row[] = Widget::TableData(DateTimeObj::get(__SYM_DATETIME_FORMAT__, strtotime($log['date']))); $keywords = $log['keywords']; $keywords_class = ''; if ($keywords == '') { $keywords = __('None'); $keywords_class = 'inactive'; } $row[] = Widget::TableData(htmlentities($keywords, ENT_QUOTES), $keywords_class); $adjusted = $log['keywords_manipulated']; $adjusted_class = ''; if ($log['keywords_manipulated'] == '' || strtolower(trim($log['keywords'])) == strtolower(trim($log['keywords_manipulated']))) { $adjusted = __('None'); $adjusted_class = 'inactive'; } $row[] = Widget::TableData(htmlentities($adjusted, ENT_QUOTES), $adjusted_class); $row[] = Widget::TableData($log['results']); $row[] = Widget::TableData($log['depth']); $row[] = Widget::TableData($log['session_id']); //$row[] = Widget::TableData($log['session_id'] . Widget::Input("items[{$log['id']}]", null, 'checkbox')->generate()); $tableBody[] = Widget::TableRow($row); } } $table = Widget::Table(Widget::TableHead($tableHead), null, Widget::TableBody($tableBody)); $this->Form->appendChild($table); $div = new XMLElement('div'); $div->setAttribute('class', 'actions'); $this->Form->appendChild($div); // Pagination: if ($pages > 1) { $ul = new XMLElement('ul'); $ul->setAttribute('class', 'page'); ## First $li = new XMLElement('li'); if ($page > 1) { $li->appendChild(Widget::Anchor(__('First'), Administration::instance()->getCurrentPageURL() . '?pg=1&sort=' . $sort_column . '&order=' . $sort_order . '&keywords=' . $filter_keywords)); } else { $li->setValue(__('First')); } $ul->appendChild($li); ## Previous $li = new XMLElement('li'); if ($page > 1) { $li->appendChild(Widget::Anchor(__('← Previous'), Administration::instance()->getCurrentPageURL() . '?pg=' . ($page - 1) . '&sort=' . $sort_column . '&order=' . $sort_order . '&keywords=' . $filter_keywords)); } else { $li->setValue('← ' . __('Previous')); } $ul->appendChild($li); ## Summary $li = new XMLElement('li'); $li->setAttribute('title', __('Viewing %1$s - %2$s of %3$s entries', array($start, $end, $total))); $pgform = Widget::Form(Administration::instance()->getCurrentPageURL(), 'get', 'paginationform'); $pgmax = max($page, $pages); $pgform->appendChild(Widget::Input('pg', NULL, 'text', array('data-active' => __('Go to page …'), 'data-inactive' => __('Page %1$s of %2$s', array((string) $page, $pgmax)), 'data-max' => $pgmax))); $li->appendChild($pgform); $ul->appendChild($li); ## Next $li = new XMLElement('li'); if ($page < $pages) { $li->appendChild(Widget::Anchor(__('Next →'), Administration::instance()->getCurrentPageURL() . '?pg=' . ($page + 1) . '&sort=' . $sort_column . '&order=' . $sort_order . '&keywords=' . $filter_keywords)); } else { $li->setValue(__('Next') . ' →'); } $ul->appendChild($li); ## Last $li = new XMLElement('li'); if ($page < $pages) { $li->appendChild(Widget::Anchor(__('Last'), Administration::instance()->getCurrentPageURL() . '?pg=' . $pages . '&sort=' . $sort_column . '&order=' . $sort_order . '&keywords=' . $filter_keywords)); } else { $li->setValue(__('Last')); } $ul->appendChild($li); $this->Contents->appendChild($ul); } }
public function __viewIndex() { $this->setPageType('form'); $this->setTitle(__('Symphony') . ' – ' . __('Dashboard')); $this->addScriptToHead(URL . '/extensions/dashboard/assets/jquery-ui-1.11.4.custom.min.js', 29421); $this->addStylesheetToHead(URL . '/extensions/dashboard/assets/dashboard.index.css', 'screen', 29422); $this->addScriptToHead(URL . '/extensions/dashboard/assets/dashboard.index.js', 29423); // https://github.com/symphonycms/symphony-2/wiki/Migration-Guide-to-2.5-for-Developers#properties $author = null; if (is_callable(array('Symphony', 'Author'))) { $author = Symphony::Author(); } else { $author = Administration::instance()->Author; } // Add welcome message $hour = date('H'); $welcome = __('Nice to meet you'); if ($author->get('last_see') != NULL) { if ($hour < 10) { $welcome = __('Good morning'); } elseif ($hour < 17) { $welcome = __('Welcome back'); } else { $welcome = __('Good evening'); } } $panel_types = array(); /** * Ask panel extensions to list their panel types. * * @delegate DashboardPanelTypes * @param string $context * '/backend/' * @param array $types */ Symphony::ExtensionManager()->notifyMembers('DashboardPanelTypes', '/backend/', array('types' => &$panel_types)); if ($author->isDeveloper()) { $panel_types_options = array(array('', FALSE, __('New Panel'))); natsort($panel_types); foreach ($panel_types as $handle => $name) { $panel_types_options[] = array($handle, false, $name); } $actions = array(); $actions[] = Widget::Select('panel-type', $panel_types_options); $actions[] = Widget::Anchor(__('Enable Editing'), '#', __('Disable Editing'), 'edit-mode button'); } $this->Form->setAttribute('class', 'two columns'); $this->appendSubheading($welcome . ', ' . $author->get('first_name'), $actions); $this->insertDrawer(Widget::Drawer('dashboard', 'Dashboard', new XMLElement('span', ''), 'closed', time()), 'horizontal', FALSE); $container = new XMLElement('div', NULL, array('id' => 'dashboard')); $primary = new XMLElement('div', NULL, array('class' => 'primary column sortable-container')); $secondary = new XMLElement('div', NULL, array('class' => 'secondary column sortable-container')); $panels = Extension_Dashboard::getPanels(); foreach ($panels as $p) { $html = Extension_Dashboard::buildPanelHTML($p); switch ($p['placement']) { case 'primary': $primary->appendChild($html); break; case 'secondary': $secondary->appendChild($html); break; } } $container->appendChild($primary); $container->appendChild($secondary); $this->Form->appendChild($container); }