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');
     }
 }
Esempio n. 2
0
 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') . ' &ndash; ' . __('ElasticSearch') . ' &ndash; ' . __('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', '&amp;', $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');
         //}
     }
 }
Esempio n. 6
0
 public function __viewIndex()
 {
     $this->setPageType('table');
     $this->setTitle(__('Symphony') . ' &ndash; ' . __('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&amp;sort=' . $sort_column . '&amp;order=' . $sort_order . '&amp;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&amp;sort=date&amp;order=' . ($sort_column == 'date' && $sort_order == 'desc' ? 'asc' : 'desc') . '&amp;keywords=' . $filter_keywords, '', $sort_column == 'date' ? 'active' : ''), 'col'), array(Widget::Anchor(__('Keywords'), Administration::instance()->getCurrentPageURL() . '?pg=1&amp;sort=keywords&amp;order=' . ($sort_column == 'keywords' && $sort_order == 'asc' ? 'desc' : 'asc') . '&amp;keywords=' . $filter_keywords, '', $sort_column == 'keywords' ? 'active' : ''), 'col'), array(__('Adjusted Keywords'), 'col'), array(Widget::Anchor(__('Results'), Administration::instance()->getCurrentPageURL() . '?pg=1&amp;sort=results&amp;order=' . ($sort_column == 'results' && $sort_order == 'desc' ? 'asc' : 'desc') . '&amp;keywords=' . $filter_keywords, '', $sort_column == 'results' ? 'active' : ''), 'col'), array(Widget::Anchor(__('Depth'), Administration::instance()->getCurrentPageURL() . '?pg=1&amp;sort=depth&amp;order=' . ($sort_column == 'depth' && $sort_order == 'desc' ? 'asc' : 'desc') . '&amp;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&amp;sort=' . $sort_column . '&amp;order=' . $sort_order . '&amp;keywords=' . $filter_keywords));
         } else {
             $li->setValue(__('First'));
         }
         $ul->appendChild($li);
         ## Previous
         $li = new XMLElement('li');
         if ($page > 1) {
             $li->appendChild(Widget::Anchor(__('&larr; Previous'), Administration::instance()->getCurrentPageURL() . '?pg=' . ($page - 1) . '&amp;sort=' . $sort_column . '&amp;order=' . $sort_order . '&amp;keywords=' . $filter_keywords));
         } else {
             $li->setValue('&larr; ' . __('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 &rarr;'), Administration::instance()->getCurrentPageURL() . '?pg=' . ($page + 1) . '&amp;sort=' . $sort_column . '&amp;order=' . $sort_order . '&amp;keywords=' . $filter_keywords));
         } else {
             $li->setValue(__('Next') . ' &rarr;');
         }
         $ul->appendChild($li);
         ## Last
         $li = new XMLElement('li');
         if ($page < $pages) {
             $li->appendChild(Widget::Anchor(__('Last'), Administration::instance()->getCurrentPageURL() . '?pg=' . $pages . '&amp;sort=' . $sort_column . '&amp;order=' . $sort_order . '&amp;keywords=' . $filter_keywords));
         } else {
             $li->setValue(__('Last'));
         }
         $ul->appendChild($li);
         $this->Contents->appendChild($ul);
     }
 }
Esempio n. 7
0
 public function __viewIndex()
 {
     $this->setPageType('form');
     $this->setTitle(__('Symphony') . ' &ndash; ' . __('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);
 }