public function view() { $section_handle = (string) $this->context[0]; $page = isset($this->context[1]) ? (int) $this->context[1] : 1; if (empty($section_handle)) { die('Invalid section handle'); } $config = (object) Symphony::Configuration()->get('elasticsearch'); ElasticSearch::init(); $type = ElasticSearch::getTypeByHandle($section_handle); if ($page === 1) { // delete all documents in this index $query = new Elastica_Query(array('query' => array('match_all' => array()))); $type->type->deleteByQuery($query); } // get new entries $em = new EntryManager(Symphony::Engine()); $entries = $em->fetchByPage($page, $type->section->get('id'), (int) $config->{'reindex-batch-size'}, NULL, NULL, FALSE, FALSE, TRUE); foreach ($entries['records'] as $entry) { ElasticSearch::indexEntry($entry, $type->section); } $entries['total-entries'] = 0; // last page, count how many entries in the index if ($entries['remaining-pages'] == 0) { // wait a few seconds, allow HTTP requests to complete... sleep(5); $entries['total-entries'] = $type->type->count(); } header('Content-type: application/json'); echo json_encode(array('pagination' => array('total-pages' => (int) $entries['total-pages'], 'total-entries' => (int) $entries['total-entries'], 'remaining-pages' => (int) $entries['remaining-pages'], 'next-page' => $page + 1))); exit; }
/** * Fetch raw recipient data. * * Usage of the getSlice function, which also parses the XSLT for the name * and checks the email is recommended. This function is here mainly for * internal reasons. * * Be advised, this function returns an array of entry objects. * * @todo bugtesting and error handling * @return array */ public function grab() { parent::grab(); $where_and_joins = $this->getWhereJoinsAndGroup(); $entries = EntryManager::fetchByPage($this->dsParamSTARTPAGE > 0 ? $this->dsParamSTARTPAGE : 1, $this->getSource(), $this->dsParamLIMIT >= 0 ? $this->dsParamLIMIT : NULL, $where_and_joins['where'], $where_and_joins['joins'], false, false, true, array_merge(array($this->emailField), $this->nameFields)); // The count method of the entrymanager does not work properly, so this hack is needed :( $count = $this->getCount(); $entries['total-entries'] = $count; $entries['total-pages'] = ceil($count / $this->dsParamLIMIT); $entries['remaining-pages'] = $entries['total-pages'] - $entries['current-page']; return $entries; }
public function execute(array &$param_pool) { $result = new XMLElement($this->dsParamROOTELEMENT); $this->_param_pool = $param_pool; $where = NULL; $joins = NULL; $group = false; include_once TOOLKIT . '/class.entrymanager.php'; if (!($section = SectionManager::fetch((int) $this->getSource()))) { $about = $this->about(); trigger_error(__('The section associated with the data source %s could not be found.', array('<code>' . $about['name'] . '</code>')), E_USER_ERROR); } $sectioninfo = new XMLElement('section', General::sanitize($section->get('name')), array('id' => $section->get('id'), 'handle' => $section->get('handle'))); if ($this->_force_empty_result == true) { $this->_force_empty_result = false; //this is so the section info element doesn't disappear. $result = $this->emptyXMLSet(); $result->prependChild($sectioninfo); return; } if (is_array($this->dsParamINCLUDEDELEMENTS)) { $include_pagination_element = in_array('system:pagination', $this->dsParamINCLUDEDELEMENTS); } else { $this->dsParamINCLUDEDELEMENTS = array(); } if (isset($this->dsParamPARAMOUTPUT) && !is_array($this->dsParamPARAMOUTPUT)) { $this->dsParamPARAMOUTPUT = array($this->dsParamPARAMOUTPUT); } $this->_can_process_system_parameters = $this->canProcessSystemParameters(); if (!isset($this->dsParamPAGINATERESULTS)) { $this->dsParamPAGINATERESULTS = 'yes'; } // Process Filters $this->processFilters($where, $joins, $group); // Process Sorting if ($this->dsParamSORT == 'system:id') { EntryManager::setFetchSorting('id', $this->dsParamORDER); } else { if ($this->dsParamSORT == 'system:date') { EntryManager::setFetchSorting('date', $this->dsParamORDER); } else { EntryManager::setFetchSorting(FieldManager::fetchFieldIDFromElementName($this->dsParamSORT, $this->getSource()), $this->dsParamORDER); } } // combine `INCLUDEDELEMENTS`, `PARAMOUTPUT` and `GROUP` into an // array of field handles to optimise the `EntryManager` queries $datasource_schema = $this->dsParamINCLUDEDELEMENTS; if (is_array($this->dsParamPARAMOUTPUT)) { $datasource_schema = array_merge($datasource_schema, $this->dsParamPARAMOUTPUT); } if ($this->dsParamGROUP) { $datasource_schema[] = FieldManager::fetchHandleFromID($this->dsParamGROUP); } $entries = EntryManager::fetchByPage($this->dsParamPAGINATERESULTS == 'yes' && $this->dsParamSTARTPAGE > 0 ? $this->dsParamSTARTPAGE : 1, $this->getSource(), $this->dsParamPAGINATERESULTS == 'yes' && $this->dsParamLIMIT >= 0 ? $this->dsParamLIMIT : NULL, $where, $joins, $group, !$include_pagination_element ? true : false, true, array_unique($datasource_schema)); /** * Immediately after building entries allow modification of the Data Source entry list * * @delegate DataSourceEntriesBuilt * @param string $context * '/frontend/' * @param Datasource $datasource * @param array $entries * @param array $filters */ Symphony::ExtensionManager()->notifyMembers('DataSourceEntriesBuilt', '/frontend/', array('datasource' => &$this, 'entries' => &$entries, 'filters' => $this->dsParamFILTERS)); if (($entries['total-entries'] <= 0 || $include_pagination_element === true) && (!is_array($entries['records']) || empty($entries['records'])) || $this->dsParamSTARTPAGE == '0') { if ($this->dsParamREDIRECTONEMPTY == 'yes') { throw new FrontendPageNotFoundException(); } $this->_force_empty_result = false; $result = $this->emptyXMLSet(); $result->prependChild($sectioninfo); if ($include_pagination_element) { $pagination_element = General::buildPaginationElement(); if ($pagination_element instanceof XMLElement && $result instanceof XMLElement) { $result->prependChild($pagination_element); } } } else { if (!$this->_param_output_only) { $result->appendChild($sectioninfo); if ($include_pagination_element) { $t = $this->dsParamPAGINATERESULTS == 'yes' && isset($this->dsParamLIMIT) && $this->dsParamLIMIT >= 0 ? $this->dsParamLIMIT : $entries['total-entries']; $pagination_element = General::buildPaginationElement($entries['total-entries'], $entries['total-pages'], $t, $this->dsParamPAGINATERESULTS == 'yes' && $this->dsParamSTARTPAGE > 0 ? $this->dsParamSTARTPAGE : 1); if ($pagination_element instanceof XMLElement && $result instanceof XMLElement) { $result->prependChild($pagination_element); } } } // If this datasource has a Limit greater than 0 or the Limit is not set if (!isset($this->dsParamLIMIT) || $this->dsParamLIMIT > 0) { if (!isset($this->dsParamASSOCIATEDENTRYCOUNTS) || $this->dsParamASSOCIATEDENTRYCOUNTS == 'yes') { $this->_associated_sections = $section->fetchAssociatedSections(); } // If the datasource require's GROUPING if (isset($this->dsParamGROUP)) { self::$_fieldPool[$this->dsParamGROUP] =& FieldManager::fetch($this->dsParamGROUP); $groups = self::$_fieldPool[$this->dsParamGROUP]->groupRecords($entries['records']); foreach ($groups as $element => $group) { foreach ($group as $g) { $result->appendChild($this->processRecordGroup($element, $g)); } } } else { if (isset($entries['records'][0])) { $data = $entries['records'][0]->getData(); $pool = FieldManager::fetch(array_keys($data)); self::$_fieldPool += $pool; } foreach ($entries['records'] as $entry) { $xEntry = $this->processEntry($entry); if ($xEntry instanceof XMLElement) { $result->appendChild($xEntry); } } } } } $param_pool = $this->_param_pool; return $result; }
} // combine INCLUDEDELEMENTS and PARAMOUTPUT into an array of field names $datasource_schema = $this->dsParamINCLUDEDELEMENTS; if (!is_array($datasource_schema)) { $datasource_schema = array(); } if ($this->dsParamPARAMOUTPUT) { $datasource_schema[] = $this->dsParamPARAMOUTPUT; } if ($this->dsParamGROUP) { $datasource_schema[] = $entryManager->fieldManager->fetchHandleFromID($this->dsParamGROUP); } if (!isset($this->dsParamPAGINATERESULTS)) { $this->dsParamPAGINATERESULTS = 'yes'; } $entries = $entryManager->fetchByPage($this->dsParamPAGINATERESULTS == 'yes' && $this->dsParamSTARTPAGE > 0 ? $this->dsParamSTARTPAGE : 1, $this->getSource(), $this->dsParamPAGINATERESULTS == 'yes' && $this->dsParamLIMIT >= 0 ? $this->dsParamLIMIT : NULL, $where, $joins, $group, !$include_pagination_element ? true : false, true, $datasource_schema); /** * Immediately after building entries allow modification of the Data Source entry list * * @delegate DataSourceEntriesBuilt * @param string $context * '/frontend/' * @param Datasource $datasource * @param array $entries * @param array $filters */ Symphony::ExtensionManager()->notifyMembers('DataSourceEntriesBuilt', '/frontend/', array('datasource' => &$this, 'entries' => &$entries, 'filters' => $this->dsParamFILTERS)); if (($entries['total-entries'] <= 0 || $include_pagination_element === true) && (!is_array($entries['records']) || empty($entries['records'])) || $this->dsParamSTARTPAGE == '0') { if ($this->dsParamREDIRECTONEMPTY == 'yes') { throw new FrontendPageNotFoundException(); }
public function __viewIndex() { if (!($section_id = SectionManager::fetchIDFromHandle($this->_context['section_handle']))) { Administration::instance()->customError(__('Unknown Section'), __('The Section you are looking for, %s, could not be found.', array('<code>' . $this->_context['section_handle'] . '</code>'))); } $section = SectionManager::fetch($section_id); $this->setPageType('table'); $this->setTitle(__('%1$s – %2$s', array($section->get('name'), __('Symphony')))); $this->Form->setAttribute("class", $this->_context['section_handle']); $filters = array(); $filter_querystring = $prepopulate_querystring = $where = $joins = NULL; $current_page = isset($_REQUEST['pg']) && is_numeric($_REQUEST['pg']) ? max(1, intval($_REQUEST['pg'])) : 1; if (isset($_REQUEST['filter'])) { // legacy implementation, convert single filter to an array // split string in the form ?filter=handle:value if (!is_array($_REQUEST['filter'])) { list($field_handle, $filter_value) = explode(':', $_REQUEST['filter'], 2); $filters[$field_handle] = rawurldecode($filter_value); } else { $filters = $_REQUEST['filter']; } foreach ($filters as $handle => $value) { $field_id = FieldManager::fetchFieldIDFromElementName(Symphony::Database()->cleanValue($handle), $section->get('id')); $field = FieldManager::fetch($field_id); if ($field instanceof Field) { // For deprecated reasons, call the old, typo'd function name until the switch to the // properly named buildDSRetrievalSQL function. $field->buildDSRetrivalSQL(array($value), $joins, $where, false); $filter_querystring .= sprintf("filter[%s]=%s&", $handle, rawurlencode($value)); $prepopulate_querystring .= sprintf("prepopulate[%d]=%s&", $field_id, rawurlencode($value)); } else { unset($filters[$handle]); } } $filter_querystring = preg_replace("/&\$/", '', $filter_querystring); $prepopulate_querystring = preg_replace("/&\$/", '', $prepopulate_querystring); } Sortable::initialize($this, $entries, $sort, $order, array('current-section' => $section, 'filters' => $filter_querystring ? "&" . $filter_querystring : '', 'unsort' => isset($_REQUEST['unsort']))); $this->Form->setAttribute('action', Administration::instance()->getCurrentPageURL() . '?pg=' . $current_page . ($filter_querystring ? "&" . $filter_querystring : '')); $subheading_buttons = array(Widget::Anchor(__('Create New'), Administration::instance()->getCurrentPageURL() . 'new/' . ($filter_querystring ? '?' . $prepopulate_querystring : ''), __('Create a new entry'), 'create button', NULL, array('accesskey' => 'c'))); // Only show the Edit Section button if the Author is a developer. #938 ^BA if (Administration::instance()->Author->isDeveloper()) { array_unshift($subheading_buttons, Widget::Anchor(__('Edit Section'), SYMPHONY_URL . '/blueprints/sections/edit/' . $section_id, __('Edit Section Configuration'), 'button')); } $this->appendSubheading($section->get('name'), $subheading_buttons); // Check that the filtered query fails that the filter is dropped and an // error is logged. #841 ^BA try { $entries = EntryManager::fetchByPage($current_page, $section_id, Symphony::Configuration()->get('pagination_maximum_rows', 'symphony'), $where, $joins); } catch (DatabaseException $ex) { $this->pageAlert(__('An error occurred while retrieving filtered entries. Showing all entries instead.'), Alert::ERROR); $filter_querystring = null; Symphony::Log()->pushToLog(sprintf('%s - %s%s%s', $section->get('name') . ' Publish Index', $ex->getMessage(), $ex->getFile() ? " in file " . $ex->getFile() : null, $ex->getLine() ? " on line " . $ex->getLine() : null), E_NOTICE, true); $entries = EntryManager::fetchByPage($current_page, $section_id, Symphony::Configuration()->get('pagination_maximum_rows', 'symphony')); } $visible_columns = $section->fetchVisibleColumns(); $columns = array(); if (is_array($visible_columns) && !empty($visible_columns)) { foreach ($visible_columns as $column) { $columns[] = array('label' => $column->get('label'), 'sortable' => $column->isSortable(), 'handle' => $column->get('id'), 'attrs' => array('id' => 'field-' . $column->get('id'), 'class' => 'field-' . $column->get('type'))); } } else { $columns[] = array('label' => __('ID'), 'sortable' => true, 'handle' => 'id'); } $aTableHead = Sortable::buildTableHeaders($columns, $sort, $order, $filter_querystring ? "&" . $filter_querystring : ''); $child_sections = array(); $associated_sections = $section->fetchAssociatedSections(true); if (is_array($associated_sections) && !empty($associated_sections)) { foreach ($associated_sections as $key => $as) { $child_sections[$key] = SectionManager::fetch($as['child_section_id']); $aTableHead[] = array($child_sections[$key]->get('name'), 'col'); } } /** * Allows the creation of custom entries tablecolumns. Called * after all the Section Visible columns have been added as well * as the Section Associations * * @delegate AddCustomPublishColumn * @since Symphony 2.2 * @param string $context * '/publish/' * @param array $tableHead * An array of the current columns, passed by reference * @param integer $section_id * The current Section ID */ Symphony::ExtensionManager()->notifyMembers('AddCustomPublishColumn', '/publish/', array('tableHead' => &$aTableHead, 'section_id' => $section->get('id'))); // Table Body $aTableBody = array(); if (!is_array($entries['records']) || empty($entries['records'])) { $aTableBody = array(Widget::TableRow(array(Widget::TableData(__('None found.'), 'inactive', NULL, count($aTableHead))), 'odd')); } else { $field_pool = array(); if (is_array($visible_columns) && !empty($visible_columns)) { foreach ($visible_columns as $column) { $field_pool[$column->get('id')] = $column; } } $link_column = end(array_reverse($visible_columns)); reset($visible_columns); foreach ($entries['records'] as $entry) { $tableData = array(); // Setup each cell if (!is_array($visible_columns) || empty($visible_columns)) { $tableData[] = Widget::TableData(Widget::Anchor($entry->get('id'), Administration::instance()->getCurrentPageURL() . 'edit/' . $entry->get('id') . '/')); } else { $link = Widget::Anchor(__('None'), Administration::instance()->getCurrentPageURL() . 'edit/' . $entry->get('id') . '/', $entry->get('id'), 'content'); foreach ($visible_columns as $position => $column) { $data = $entry->getData($column->get('id')); $field = $field_pool[$column->get('id')]; $value = $field->prepareTableValue($data, $column == $link_column ? $link : null, $entry->get('id')); if (!is_object($value) && (strlen(trim($value)) == 0 || $value == __('None'))) { $value = $position == 0 ? $link->generate() : __('None'); } if ($value == __('None')) { $tableData[] = Widget::TableData($value, 'inactive field-' . $column->get('type') . ' field-' . $column->get('id')); } else { $tableData[] = Widget::TableData($value, 'field-' . $column->get('type') . ' field-' . $column->get('id')); } unset($field); } } if (is_array($child_sections) && !empty($child_sections)) { foreach ($child_sections as $key => $as) { $field = FieldManager::fetch((int) $associated_sections[$key]['child_section_field_id']); $parent_section_field_id = (int) $associated_sections[$key]['parent_section_field_id']; if (!is_null($parent_section_field_id)) { $search_value = $field->fetchAssociatedEntrySearchValue($entry->getData($parent_section_field_id), $parent_section_field_id, $entry->get('id')); } else { $search_value = $entry->get('id'); } if (!is_array($search_value)) { $associated_entry_count = $field->fetchAssociatedEntryCount($search_value); $tableData[] = Widget::TableData(Widget::Anchor(sprintf('%d →', max(0, intval($associated_entry_count))), sprintf('%s/publish/%s/?filter=%s:%s', SYMPHONY_URL, $as->get('handle'), $field->get('element_name'), rawurlencode($search_value)), $entry->get('id'), 'content')); } } } /** * Allows Extensions to inject custom table data for each Entry * into the Publish Index * * @delegate AddCustomPublishColumnData * @since Symphony 2.2 * @param string $context * '/publish/' * @param array $tableData * An array of `Widget::TableData`, passed by reference * @param integer $section_id * The current Section ID * @param integer $entry_id * The Entry ID for this row */ Symphony::ExtensionManager()->notifyMembers('AddCustomPublishColumnData', '/publish/', array('tableData' => &$tableData, 'section_id' => $section->get('id'), 'entry_id' => $entry)); $tableData[count($tableData) - 1]->appendChild(Widget::Input('items[' . $entry->get('id') . ']', NULL, 'checkbox')); // Add a row to the body array, assigning each cell to the row $aTableBody[] = Widget::TableRow($tableData, NULL, 'id-' . $entry->get('id')); } } $table = Widget::Table(Widget::TableHead($aTableHead), NULL, Widget::TableBody($aTableBody), 'selectable'); $this->Form->appendChild($table); $tableActions = new XMLElement('div'); $tableActions->setAttribute('class', 'actions'); $options = array(array(NULL, false, __('With Selected...')), array('delete', false, __('Delete'), 'confirm', null, array('data-message' => __('Are you sure you want to delete the selected entries?')))); $toggable_fields = $section->fetchToggleableFields(); if (is_array($toggable_fields) && !empty($toggable_fields)) { $index = 2; foreach ($toggable_fields as $field) { $options[$index] = array('label' => __('Set %s', array($field->get('label'))), 'options' => array()); foreach ($field->getToggleStates() as $value => $state) { $options[$index]['options'][] = array('toggle-' . $field->get('id') . '-' . $value, false, $state); } $index++; } } $tableActions->appendChild(Widget::Apply($options)); $this->Form->appendChild($tableActions); if ($entries['total-pages'] > 1) { $ul = new XMLElement('ul'); $ul->setAttribute('class', 'page'); // First $li = new XMLElement('li'); if ($current_page > 1) { $li->appendChild(Widget::Anchor(__('First'), Administration::instance()->getCurrentPageURL() . '?pg=1' . ($filter_querystring ? "&" . $filter_querystring : ''))); } else { $li->setValue(__('First')); } $ul->appendChild($li); // Previous $li = new XMLElement('li'); if ($current_page > 1) { $li->appendChild(Widget::Anchor(__('← Previous'), Administration::instance()->getCurrentPageURL() . '?pg=' . ($current_page - 1) . ($filter_querystring ? "&" . $filter_querystring : ''))); } 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($entries['start'], $current_page != $entries['total-pages'] ? $current_page * Symphony::Configuration()->get('pagination_maximum_rows', 'symphony') : $entries['total-entries'], $entries['total-entries']))); $pgform = Widget::Form(Administration::instance()->getCurrentPageURL(), 'get', 'paginationform'); $pgmax = max($current_page, $entries['total-pages']); $pgform->appendChild(Widget::Input('pg', NULL, 'text', array('data-active' => __('Go to page …'), 'data-inactive' => __('Page %1$s of %2$s', array((string) $current_page, $pgmax)), 'data-max' => $pgmax))); $li->appendChild($pgform); $ul->appendChild($li); // Next $li = new XMLElement('li'); if ($current_page < $entries['total-pages']) { $li->appendChild(Widget::Anchor(__('Next →'), Administration::instance()->getCurrentPageURL() . '?pg=' . ($current_page + 1) . ($filter_querystring ? "&" . $filter_querystring : ''))); } else { $li->setValue(__('Next →')); } $ul->appendChild($li); // Last $li = new XMLElement('li'); if ($current_page < $entries['total-pages']) { $li->appendChild(Widget::Anchor(__('Last'), Administration::instance()->getCurrentPageURL() . '?pg=' . $entries['total-pages'] . ($filter_querystring ? "&" . $filter_querystring : ''))); } else { $li->setValue(__('Last')); } $ul->appendChild($li); $this->Contents->appendChild($ul); } }
public function __viewIndex() { $sectionManager = new SectionManager($this->_Parent); if (!($section_id = $sectionManager->fetchIDFromHandle($this->_context['section_handle']))) { Administration::instance()->customError(__('Unknown Section'), __('The Section you are looking, <code>%s</code> for could not be found.', array($this->_context['section_handle']))); } $section = $sectionManager->fetch($section_id); $this->setPageType('table'); $this->setTitle(__('%1$s – %2$s', array(__('Symphony'), $section->get('name')))); $this->Form->setAttribute("class", $this->_context['section_handle']); $entryManager = new EntryManager($this->_Parent); $filter = $filter_value = $where = $joins = NULL; $current_page = isset($_REQUEST['pg']) && is_numeric($_REQUEST['pg']) ? max(1, intval($_REQUEST['pg'])) : 1; if (isset($_REQUEST['filter'])) { list($field_handle, $filter_value) = explode(':', $_REQUEST['filter'], 2); $field_names = explode(',', $field_handle); foreach ($field_names as $field_name) { $filter_value = rawurldecode($filter_value); $filter = Symphony::Database()->fetchVar('id', 0, "SELECT `f`.`id`\n\t\t\t\t\t\t\t\t\t\t FROM `tbl_fields` AS `f`, `tbl_sections` AS `s`\n\t\t\t\t\t\t\t\t\t\t WHERE `s`.`id` = `f`.`parent_section`\n\t\t\t\t\t\t\t\t\t\t AND f.`element_name` = '{$field_name}'\n\t\t\t\t\t\t\t\t\t\t AND `s`.`handle` = '" . $section->get('handle') . "' LIMIT 1"); $field =& $entryManager->fieldManager->fetch($filter); if ($field instanceof Field) { // For deprecated reasons, call the old, typo'd function name until the switch to the // properly named buildDSRetrievalSQL function. $field->buildDSRetrivalSQL(array($filter_value), $joins, $where, false); $filter_value = rawurlencode($filter_value); } } if (!is_null($where)) { $where = str_replace('AND', 'OR', $where); // multiple fields need to be OR $where = trim($where); $where = ' AND (' . substr($where, 2, strlen($where)) . ')'; // replace leading OR with AND } } if (isset($_REQUEST['sort']) && is_numeric($_REQUEST['sort'])) { $sort = intval($_REQUEST['sort']); $order = $_REQUEST['order'] ? strtolower($_REQUEST['order']) : 'asc'; if ($section->get('entry_order') != $sort || $section->get('entry_order_direction') != $order) { $sectionManager->edit($section->get('id'), array('entry_order' => $sort, 'entry_order_direction' => $order)); redirect(Administration::instance()->getCurrentPageURL() . ($filter ? "?filter={$field_handle}:{$filter_value}" : '')); } } elseif (isset($_REQUEST['unsort'])) { $sectionManager->edit($section->get('id'), array('entry_order' => NULL, 'entry_order_direction' => NULL)); redirect(Administration::instance()->getCurrentPageURL()); } $this->Form->setAttribute('action', Administration::instance()->getCurrentPageURL() . '?pg=' . $current_page . ($filter ? "&filter={$field_handle}:{$filter_value}" : '')); $this->appendSubheading($section->get('name'), Widget::Anchor(__('Create New'), Administration::instance()->getCurrentPageURL() . 'new/' . ($filter ? '?prepopulate[' . $filter . ']=' . $filter_value : ''), __('Create a new entry'), 'create button', NULL, array('accesskey' => 'c'))); if (is_null($entryManager->getFetchSorting()->field) && is_null($entryManager->getFetchSorting()->direction)) { $entryManager->setFetchSortingDirection('DESC'); } $entries = $entryManager->fetchByPage($current_page, $section_id, Symphony::Configuration()->get('pagination_maximum_rows', 'symphony'), $where, $joins); $aTableHead = array(); $visible_columns = $section->fetchVisibleColumns(); if (is_array($visible_columns) && !empty($visible_columns)) { foreach ($visible_columns as $column) { $label = $column->get('label'); if ($column->isSortable()) { if ($column->get('id') == $section->get('entry_order')) { $link = Administration::instance()->getCurrentPageURL() . '?pg=' . $current_page . '&sort=' . $column->get('id') . '&order=' . ($section->get('entry_order_direction') == 'desc' ? 'asc' : 'desc') . ($filter ? "&filter={$field_handle}:{$filter_value}" : ''); $anchor = Widget::Anchor($label, $link, __('Sort by %1$s %2$s', array($section->get('entry_order_direction') == 'desc' ? __('ascending') : __('descending'), strtolower($column->get('label')))), 'active'); } else { $link = Administration::instance()->getCurrentPageURL() . '?pg=' . $current_page . '&sort=' . $column->get('id') . '&order=asc' . ($filter ? "&filter={$field_handle}:{$filter_value}" : ''); $anchor = Widget::Anchor($label, $link, __('Sort by %1$s %2$s', array(__('ascending'), strtolower($column->get('label'))))); } $aTableHead[] = array($anchor, 'col', array('id' => 'field-' . $column->get('id'), 'class' => 'field-' . $column->get('type'))); } else { $aTableHead[] = array($label, 'col', array('id' => 'field-' . $column->get('id'), 'class' => 'field-' . $column->get('type'))); } } } else { $aTableHead[] = array(__('ID'), 'col'); } $child_sections = array(); $associated_sections = $section->fetchAssociatedSections(true); if (is_array($associated_sections) && !empty($associated_sections)) { foreach ($associated_sections as $key => $as) { $child_sections[$key] = $sectionManager->fetch($as['child_section_id']); $aTableHead[] = array($child_sections[$key]->get('name'), 'col'); } } /** * Allows the creation of custom entries tablecolumns. Called * after all the Section Visible columns have been added as well * as the Section Associations * * @delegate AddCustomPublishColumn * @since Symphony 2.2 * @param string $context * '/publish/' * @param array $tableHead * An array of the current columns, passed by reference * @param integer $section_id * The current Section ID */ Symphony::ExtensionManager()->notifyMembers('AddCustomPublishColumn', '/publish/', array('tableHead' => &$aTableHead, 'section_id' => $section->get('id'))); ## Table Body $aTableBody = array(); if (!is_array($entries['records']) || empty($entries['records'])) { $aTableBody = array(Widget::TableRow(array(Widget::TableData(__('None found.'), 'inactive', NULL, count($aTableHead))), 'odd')); } else { $field_pool = array(); if (is_array($visible_columns) && !empty($visible_columns)) { foreach ($visible_columns as $column) { $field_pool[$column->get('id')] = $column; } } foreach ($entries['records'] as $entry) { $tableData = array(); ## Setup each cell if (!is_array($visible_columns) || empty($visible_columns)) { $tableData[] = Widget::TableData(Widget::Anchor($entry->get('id'), Administration::instance()->getCurrentPageURL() . 'edit/' . $entry->get('id') . '/')); } else { $link = Widget::Anchor('None', Administration::instance()->getCurrentPageURL() . 'edit/' . $entry->get('id') . '/', $entry->get('id'), 'content'); foreach ($visible_columns as $position => $column) { $data = $entry->getData($column->get('id')); $field = $field_pool[$column->get('id')]; $value = $field->prepareTableValue($data, $position == 0 ? $link : null, $entry->get('id')); if (!is_object($value) && strlen(trim($value)) == 0) { $value = $position == 0 ? $link->generate() : __('None'); } if ($value == 'None') { $tableData[] = Widget::TableData($value, 'inactive field-' . $column->get('type') . ' field-' . $column->get('id')); } else { $tableData[] = Widget::TableData($value, 'field-' . $column->get('type') . ' field-' . $column->get('id')); } unset($field); } } if (is_array($child_sections) && !empty($child_sections)) { foreach ($child_sections as $key => $as) { $field = $entryManager->fieldManager->fetch((int) $associated_sections[$key]['child_section_field_id']); $parent_section_field_id = (int) $associated_sections[$key]['parent_section_field_id']; if (!is_null($parent_section_field_id)) { $search_value = $field->fetchAssociatedEntrySearchValue($entry->getData($parent_section_field_id), $parent_section_field_id, $entry->get('id')); } else { $search_value = $entry->get('id'); } if (!is_array($search_value)) { $associated_entry_count = $field->fetchAssociatedEntryCount($search_value); $tableData[] = Widget::TableData(Widget::Anchor(sprintf('%d →', max(0, intval($associated_entry_count))), sprintf('%s/publish/%s/?filter=%s:%s', SYMPHONY_URL, $as->get('handle'), $field->get('element_name'), rawurlencode($search_value)), $entry->get('id'), 'content')); } } } /** * Allows Extensions to inject custom table data for each Entry * into the Publish Index * * @delegate AddCustomPublishColumnData * @since Symphony 2.2 * @param string $context * '/publish/' * @param array $tableData * An array of `Widget::TableData`, passed by reference * @param integer $section_id * The current Section ID * @param integer $entry_id * The Entry ID for this row */ Symphony::ExtensionManager()->notifyMembers('AddCustomPublishColumnData', '/publish/', array('tableData' => &$tableData, 'section_id' => $section->get('id'), 'entry_id' => $entry)); $tableData[count($tableData) - 1]->appendChild(Widget::Input('items[' . $entry->get('id') . ']', NULL, 'checkbox')); ## Add a row to the body array, assigning each cell to the row $aTableBody[] = Widget::TableRow($tableData, NULL, 'id-' . $entry->get('id')); } } $table = Widget::Table(Widget::TableHead($aTableHead), NULL, Widget::TableBody($aTableBody), 'selectable'); $this->Form->appendChild($table); $tableActions = new XMLElement('div'); $tableActions->setAttribute('class', 'actions'); $options = array(array(NULL, false, __('With Selected...')), array('delete', false, __('Delete'), 'confirm', null, array('data-message' => __('Are you sure you want to delete the selected entries?')))); $toggable_fields = $section->fetchToggleableFields(); if (is_array($toggable_fields) && !empty($toggable_fields)) { $index = 2; foreach ($toggable_fields as $field) { $options[$index] = array('label' => __('Set %s', array($field->get('label'))), 'options' => array()); foreach ($field->getToggleStates() as $value => $state) { $options[$index]['options'][] = array('toggle-' . $field->get('id') . '-' . $value, false, $state); } $index++; } } $tableActions->appendChild(Widget::Select('with-selected', $options)); $tableActions->appendChild(Widget::Input('action[apply]', __('Apply'), 'submit')); $this->Form->appendChild($tableActions); if ($entries['total-pages'] > 1) { $ul = new XMLElement('ul'); $ul->setAttribute('class', 'page'); ## First $li = new XMLElement('li'); if ($current_page > 1) { $li->appendChild(Widget::Anchor(__('First'), Administration::instance()->getCurrentPageURL() . '?pg=1' . ($filter ? "&filter={$field_handle}:{$filter_value}" : ''))); } else { $li->setValue(__('First')); } $ul->appendChild($li); ## Previous $li = new XMLElement('li'); if ($current_page > 1) { $li->appendChild(Widget::Anchor(__('← Previous'), Administration::instance()->getCurrentPageURL() . '?pg=' . ($current_page - 1) . ($filter ? "&filter={$field_handle}:{$filter_value}" : ''))); } else { $li->setValue(__('← Previous')); } $ul->appendChild($li); ## Summary $li = new XMLElement('li', __('Page %1$s of %2$s', array($current_page, max($current_page, $entries['total-pages'])))); $li->setAttribute('title', __('Viewing %1$s - %2$s of %3$s entries', array($entries['start'], $current_page != $entries['total-pages'] ? $current_page * Symphony::Configuration()->get('pagination_maximum_rows', 'symphony') : $entries['total-entries'], $entries['total-entries']))); $ul->appendChild($li); ## Next $li = new XMLElement('li'); if ($current_page < $entries['total-pages']) { $li->appendChild(Widget::Anchor(__('Next →'), Administration::instance()->getCurrentPageURL() . '?pg=' . ($current_page + 1) . ($filter ? "&filter={$field_handle}:{$filter_value}" : ''))); } else { $li->setValue(__('Next →')); } $ul->appendChild($li); ## Last $li = new XMLElement('li'); if ($current_page < $entries['total-pages']) { $li->appendChild(Widget::Anchor(__('Last'), Administration::instance()->getCurrentPageURL() . '?pg=' . $entries['total-pages'] . ($filter ? "&filter={$field_handle}:{$filter_value}" : ''))); } else { $li->setValue(__('Last')); } $ul->appendChild($li); $this->Form->appendChild($ul); } }
/** * 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'); }
function __viewIndex() { $sectionManager = new SectionManager($this->_Parent); if (!($section_id = $sectionManager->fetchIDFromHandle($this->_context['section_handle']))) { $this->_Parent->customError(E_USER_ERROR, __('Unknown Section'), __('The Section you are looking, <code>%s</code> for could not be found.', array($this->_context['section_handle'])), false, true); } $section = $sectionManager->fetch($section_id); $this->setPageType('table'); $this->setTitle(__('%1$s – %2$s', array(__('Symphony'), $section->get('name')))); $this->Form->setAttribute("class", $this->_context['section_handle']); $entryManager = new EntryManager($this->_Parent); $authors = AuthorManager::fetch(); $filter = $filter_value = $where = $joins = NULL; $current_page = isset($_REQUEST['pg']) && is_numeric($_REQUEST['pg']) ? max(1, intval($_REQUEST['pg'])) : 1; if (isset($_REQUEST['filter'])) { list($field_handle, $filter_value) = explode(':', $_REQUEST['filter'], 2); $field_names = explode(',', $field_handle); foreach ($field_names as $field_name) { $filter_value = rawurldecode($filter_value); $filter = Symphony::Database()->fetchVar('id', 0, "SELECT `f`.`id` \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t FROM `tbl_fields` AS `f`, `tbl_sections` AS `s` \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t WHERE `s`.`id` = `f`.`parent_section` \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t AND f.`element_name` = '{$field_name}' \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t AND `s`.`handle` = '" . $section->get('handle') . "' LIMIT 1"); $field =& $entryManager->fieldManager->fetch($filter); if (is_object($field)) { $field->buildDSRetrivalSQL(array($filter_value), $joins, $where, false); $filter_value = rawurlencode($filter_value); } } if ($where != null) { $where = str_replace('AND', 'OR', $where); // multiple fields need to be OR $where = trim($where); $where = ' AND (' . substr($where, 2, strlen($where)) . ')'; // replace leading OR with AND } } if (isset($_REQUEST['sort']) && is_numeric($_REQUEST['sort'])) { $sort = intval($_REQUEST['sort']); $order = $_REQUEST['order'] ? strtolower($_REQUEST['order']) : 'asc'; if ($section->get('entry_order') != $sort || $section->get('entry_order_direction') != $order) { $sectionManager->edit($section->get('id'), array('entry_order' => $sort, 'entry_order_direction' => $order)); redirect($this->_Parent->getCurrentPageURL() . ($filter ? "?filter={$field_handle}:{$filter_value}" : '')); } } elseif (isset($_REQUEST['unsort'])) { $sectionManager->edit($section->get('id'), array('entry_order' => NULL, 'entry_order_direction' => NULL)); redirect($this->_Parent->getCurrentPageURL()); } $this->Form->setAttribute('action', $this->_Parent->getCurrentPageURL() . '?pg=' . $current_page . ($filter ? "&filter={$field_handle}:{$filter_value}" : '')); ## Remove the create button if there is a section link field, and no filtering set for it $section_links = $section->fetchFields('sectionlink'); if (count($section_links) > 1 || !$filter && $section_links || is_object($section_links[0]) && $filter != $section_links[0]->get('id')) { $this->appendSubheading($section->get('name')); } else { $this->appendSubheading($section->get('name'), Widget::Anchor(__('Create New'), $this->_Parent->getCurrentPageURL() . 'new/' . ($filter ? '?prepopulate[' . $filter . ']=' . $filter_value : ''), __('Create a new entry'), 'create button')); } if (is_null($entryManager->getFetchSorting()->field) && is_null($entryManager->getFetchSorting()->direction)) { $entryManager->setFetchSortingDirection('DESC'); } $entries = $entryManager->fetchByPage($current_page, $section_id, Symphony::Configuration()->get('pagination_maximum_rows', 'symphony'), $where, $joins); $aTableHead = array(); $visible_columns = $section->fetchVisibleColumns(); if (is_array($visible_columns) && !empty($visible_columns)) { foreach ($visible_columns as $column) { $label = $column->get('label'); if ($column->isSortable()) { if ($column->get('id') == $section->get('entry_order')) { $link = $this->_Parent->getCurrentPageURL() . '?pg=' . $current_page . '&sort=' . $column->get('id') . '&order=' . ($section->get('entry_order_direction') == 'desc' ? 'asc' : 'desc') . ($filter ? "&filter={$field_handle}:{$filter_value}" : ''); $anchor = Widget::Anchor($label, $link, __('Sort by %1$s %2$s', array($section->get('entry_order_direction') == 'desc' ? __('ascending') : __('descending'), strtolower($column->get('label')))), 'active'); } else { $link = $this->_Parent->getCurrentPageURL() . '?pg=' . $current_page . '&sort=' . $column->get('id') . '&order=asc' . ($filter ? "&filter={$field_handle}:{$filter_value}" : ''); $anchor = Widget::Anchor($label, $link, __('Sort by %1$s %2$s', array(__('ascending'), strtolower($column->get('label'))))); } $aTableHead[] = array($anchor, 'col'); } else { $aTableHead[] = array($label, 'col'); } } } else { $aTableHead[] = array(__('ID'), 'col'); } $child_sections = NULL; $associated_sections = $section->fetchAssociatedSections(); if (is_array($associated_sections) && !empty($associated_sections)) { $child_sections = array(); foreach ($associated_sections as $key => $as) { $child_sections[$key] = $sectionManager->fetch($as['child_section_id']); $aTableHead[] = array($child_sections[$key]->get('name'), 'col'); } } ## Table Body $aTableBody = array(); if (!is_array($entries['records']) || empty($entries['records'])) { $aTableBody = array(Widget::TableRow(array(Widget::TableData(__('None found.'), 'inactive', NULL, count($aTableHead))), 'odd')); } else { $bOdd = true; $field_pool = array(); if (is_array($visible_columns) && !empty($visible_columns)) { foreach ($visible_columns as $column) { $field_pool[$column->get('id')] = $column; } } foreach ($entries['records'] as $entry) { $tableData = array(); ## Setup each cell if (!is_array($visible_columns) || empty($visible_columns)) { $tableData[] = Widget::TableData(Widget::Anchor($entry->get('id'), $this->_Parent->getCurrentPageURL() . 'edit/' . $entry->get('id') . '/')); } else { $link = Widget::Anchor('None', $this->_Parent->getCurrentPageURL() . 'edit/' . $entry->get('id') . '/', $entry->get('id'), 'content'); foreach ($visible_columns as $position => $column) { $data = $entry->getData($column->get('id')); $field = $field_pool[$column->get('id')]; $value = $field->prepareTableValue($data, $position == 0 ? $link : null, $entry->get('id')); if (!is_object($value) && strlen(trim($value)) == 0) { $value = $position == 0 ? $link->generate() : __('None'); } if ($value == 'None') { $tableData[] = Widget::TableData($value, 'inactive'); } else { $tableData[] = Widget::TableData($value); } unset($field); } } if (is_array($child_sections) && !empty($child_sections)) { foreach ($child_sections as $key => $as) { $field = $entryManager->fieldManager->fetch((int) $associated_sections[$key]['child_section_field_id']); $parent_section_field_id = (int) $associated_sections[$key]['parent_section_field_id']; if (!is_null($parent_section_field_id)) { $search_value = $field->fetchAssociatedEntrySearchValue($entry->getData($parent_section_field_id), $parent_section_field_id, $entry->get('id')); } else { $search_value = $entry->get('id'); } $associated_entry_count = $field->fetchAssociatedEntryCount($search_value); $tableData[] = Widget::TableData(Widget::Anchor(sprintf('%d →', max(0, intval($associated_entry_count))), sprintf('%s/symphony/publish/%s/?filter=%s:%s', URL, $as->get('handle'), $field->get('element_name'), rawurlencode($search_value)), $entry->get('id'), 'content')); } } $tableData[count($tableData) - 1]->appendChild(Widget::Input('items[' . $entry->get('id') . ']', NULL, 'checkbox')); ## Add a row to the body array, assigning each cell to the row $aTableBody[] = Widget::TableRow($tableData, $bOdd ? 'odd' : NULL); $bOdd = !$bOdd; } } $table = Widget::Table(Widget::TableHead($aTableHead), NULL, Widget::TableBody($aTableBody)); $this->Form->appendChild($table); $tableActions = new XMLElement('div'); $tableActions->setAttribute('class', 'actions'); $options = array(array(NULL, false, __('With Selected...')), array('delete', false, __('Delete'))); $toggable_fields = $section->fetchToggleableFields(); if (is_array($toggable_fields) && !empty($toggable_fields)) { $index = 2; foreach ($toggable_fields as $field) { $options[$index] = array('label' => __('Set %s', array($field->get('label'))), 'options' => array()); foreach ($field->getToggleStates() as $value => $state) { $options[$index]['options'][] = array('toggle-' . $field->get('id') . '-' . $value, false, $state); } $index++; } } $tableActions->appendChild(Widget::Select('with-selected', $options)); $tableActions->appendChild(Widget::Input('action[apply]', __('Apply'), 'submit')); $this->Form->appendChild($tableActions); if ($entries['total-pages'] > 1) { $ul = new XMLElement('ul'); $ul->setAttribute('class', 'page'); ## First $li = new XMLElement('li'); if ($current_page > 1) { $li->appendChild(Widget::Anchor(__('First'), $this->_Parent->getCurrentPageURL() . '?pg=1' . ($filter ? "&filter={$field_handle}:{$filter_value}" : ''))); } else { $li->setValue(__('First')); } $ul->appendChild($li); ## Previous $li = new XMLElement('li'); if ($current_page > 1) { $li->appendChild(Widget::Anchor(__('← Previous'), $this->_Parent->getCurrentPageURL() . '?pg=' . ($current_page - 1) . ($filter ? "&filter={$field_handle}:{$filter_value}" : ''))); } else { $li->setValue(__('← Previous')); } $ul->appendChild($li); ## Summary $li = new XMLElement('li', __('Page %1$s of %2$s', array($current_page, max($current_page, $entries['total-pages'])))); $li->setAttribute('title', __('Viewing %1$s - %2$s of %3$s entries', array($entries['start'], min($entries['limit'], max(1, $entries['remaining-entries'])), $entries['total-entries']))); $ul->appendChild($li); ## Next $li = new XMLElement('li'); if ($current_page < $entries['total-pages']) { $li->appendChild(Widget::Anchor(__('Next →'), $this->_Parent->getCurrentPageURL() . '?pg=' . ($current_page + 1) . ($filter ? "&filter={$field_handle}:{$filter_value}" : ''))); } else { $li->setValue(__('Next →')); } $ul->appendChild($li); ## Last $li = new XMLElement('li'); if ($current_page < $entries['total-pages']) { $li->appendChild(Widget::Anchor(__('Last'), $this->_Parent->getCurrentPageURL() . '?pg=' . $entries['total-pages'] . ($filter ? "&filter={$field_handle}:{$filter_value}" : ''))); } else { $li->setValue(__('Last')); } $ul->appendChild($li); $this->Form->appendChild($ul); } }
public static function run(SymQLQuery $query, $output = SymQL::RETURN_XML) { self::getQueryCount(); // stores all config locally so that the same SymQL instance can be used for mutliple queries $section = NULL; $section_fields = array(); $where = NULL; $joins = NULL; $entry_ids = array(); // get a section's ID if it was specified by its handle if (!is_numeric($query->section)) { $query->section = SectionManager::fetchIDFromHandle($query->section); } // get the section $section = SectionManager::fetch($query->section); if (!$section instanceof Section) { throw new Exception(sprintf("%s: section '%s' does not not exist", __CLASS__, $query->section)); } // cache the section's fields $fields = $section->fetchFields(); self::$_debug['queries']['Resolve section and fields'] = self::getQueryCount(); // cache list of field objects in this section (id => object) foreach ($fields as $field) { $section_fields[] = $field->get('id'); } $section_fields = self::indexFieldsByID($section_fields, $fields, TRUE); // resolve list of fields from SELECT statement if ($query->fields == '*') { foreach ($fields as $field) { $select_fields[] = $field->get('element_name'); } } else { $select_fields = $query->fields; } $select_fields = self::indexFieldsByID($select_fields, $fields); // resolve list of fields from WHERE statements (filters) $filters = array(); if (is_array($query->filters)) { foreach ($query->filters as $i => $filter) { $field = self::indexFieldsByID($filter['field'], $fields); if ($field) { $filters[$i][reset(array_keys($field))]['value'] = $filter['value']; $filters[$i][reset(array_keys($field))]['type'] = $filter['type']; } } } // resolve sort field if (in_array($query->sort_field, self::$_reserved_fields)) { $handle_exploded = explode(':', $query->sort_field); if (count($handle_exploded) == 2) { EntryManager::setFetchSorting(end($handle_exploded), $query->sort_direction); } } else { $sort_field = self::indexFieldsByID($query->sort_field, $fields); $sort_field = $section_fields[reset(array_keys($sort_field))]; if ($sort_field && $sort_field->isSortable()) { EntryManager::setFetchSorting($sort_field->get('id'), $query->sort_direction); } } $where = NULL; $joins = NULL; foreach ($filters as $filter) { $field_id = reset(array_keys($filter)); $filter = reset($filter); if ($field_id == 'system:id') { $entry_ids[] = (int) $filter['value']; continue; } // get the cached field object $field = $section_fields[$field_id]; if (!$field) { throw new Exception(sprintf("%s: field '%s' does not not exist", __CLASS__, $field_id)); } if (!$field->canFilter() || !method_exists($field, 'buildDSRetrievalSQL')) { throw new Exception(sprintf("%s: field '%s' can not be used as a filter", __CLASS__, $field_id)); } // local $_where = NULL; $_joins = NULL; $filter_type = FALSE === strpos($filter['value'], '+') ? self::DS_FILTER_OR : self::DS_FILTER_AND; $value = preg_split('/' . ($filter_type == self::DS_FILTER_AND ? '\\+' : ',') . '\\s*/', $filter['value'], -1, PREG_SPLIT_NO_EMPTY); $value = array_map('trim', $value); // Get the WHERE and JOIN from the field $where_before = $_where; $field->buildDSRetrievalSQL(array($filter['value']), $_joins, $_where, $filter_type == self::DS_FILTER_AND ? TRUE : FALSE); // HACK: if this is an OR statement, strip the first AND from the returned SQL // and replace with OR. This is quite brittle, but the only way I could think of if ($filter['type'] == SymQL::DS_FILTER_OR) { // get the most recent SQL added $_where_after = substr($_where, strlen($_where_before), strlen($where)); // replace leading AND with OR $_where_after = preg_replace('/^AND/', 'OR', trim($_where_after)); // re-append $_where = $_where_before . ' ' . $_where_after; } $joins .= $_joins; $where .= $_where; } // resolve the SELECT type and fetch entries if (reset(array_keys($select_fields)) == 'system:count') { $select_type = SymQL::SELECT_COUNT; $fetch_result = (int) EntryManager::fetchCount($section->get('id'), $where, $joins); } else { if (count($entry_ids) > 0) { $select_type = SymQL::SELECT_ENTRY_ID; $fetch_result = EntryManager::fetch($entry_ids, $section->get('id'), NULL, NULL, NULL, NULL, FALSE, TRUE, array_values($select_fields)); } else { $select_type = SymQL::SELECT_ENTRIES; $fetch_result = EntryManager::fetchByPage($query->page, $section->get('id'), $query->per_page, $where, $joins, FALSE, FALSE, TRUE, array_values($select_fields)); } } self::$_debug['sql']['joins'] = $joins; self::$_debug['sql']['where'] = $where; self::$_debug['queries']['Fetch entries'] = self::getQueryCount(); // section metadata $section_metadata = array('name' => $section->get('name'), 'id' => $section->get('id'), 'handle' => $section->get('handle')); // build pagination metadata if ($select_type == SymQL::SELECT_ENTRIES) { $pagination = array('total-entries' => (int) $fetch_result['total-entries'], 'total-pages' => (int) $fetch_result['total-pages'], 'per-page' => (int) $fetch_result['limit'], 'current-page' => (int) $query->page); } // find the array of entries returned from EntryManager fetch $entries = array(); switch ($select_type) { case SymQL::SELECT_ENTRY_ID: $entries = $fetch_result; break; case SymQL::SELECT_ENTRIES: $entries = $fetch_result['records']; break; case SymQL::SELECT_COUNT: $count = $fetch_result; break; } // set up result container depending on return type switch ($output) { case SymQL::RETURN_ARRAY: case SymQL::RETURN_RAW_COLUMNS: case SymQL::RETURN_ENTRY_OBJECTS: $result = array(); $result['section'] = $section_metadata; if ($pagination) { $result['pagination'] = $pagination; } break; case SymQL::RETURN_XML: $result = new XMLElement($query->root_element ? $query->root_element : 'symql'); $result->appendChild(new XMLElement('section', $section_metadata['name'], array('id' => $section_metadata['id'], 'handle' => $section_metadata['handle']))); if ($pagination) { $result->appendChild(General::buildPaginationElement($pagination['total-entries'], $pagination['total-pages'], $pagination['per-page'], $pagination['current-page'])); } break; } // append returned entries to results container if ($select_type == SymQL::SELECT_ENTRY_ID || $select_type == SymQL::SELECT_ENTRIES) { foreach ($entries as $entry) { switch ($output) { case SymQL::RETURN_RAW_COLUMNS: $fields = array(); foreach ($entry->getData() as $field_id => $values) { $field = $section_fields[$field_id]; $fields[$field->get('element_name')] = $values; } $result['entries'][$entry->get('id')] = $fields; break; case SymQL::RETURN_ENTRY_OBJECTS: $result['entries'][$entry->get('id')] = $entry; break; case SymQL::RETURN_XML: case SymQL::RETURN_ARRAY: $xml_entry = new XMLElement('entry'); $xml_entry->setAttribute('id', $entry->get('id')); foreach ($entry->getData() as $field_id => $values) { $field = $section_fields[$field_id]; $handle = $field->get('element_name'); $handle_exploded = explode(':', $select_fields[$field_id]); if (count($handle_exploded) == 2) { $mode = end($handle_exploded); } $field->appendFormattedElement($xml_entry, $values, $encode, $mode); } if ($output == SymQL::RETURN_ARRAY) { $result['entries'][] = XMLToArray::convert($xml_entry->generate()); } else { $result->appendChild($xml_entry); } break; } } } elseif ($select_type == SymQL::SELECT_COUNT) { switch ($output) { case SymQL::RETURN_ARRAY: case SymQL::RETURN_RAW_COLUMNS: case SymQL::RETURN_ENTRY_OBJECTS: $result['count'] = $count; break; case SymQL::RETURN_XML: $xml_entry = new XMLElement('count', $count); $result->appendChild($xml_entry); break; } } self::$_debug['queries']['Total'] = Symphony::Database()->queryCount() - self::$_base_querycount; // reset for the next query EntryManager::setFetchSorting(NULL, NULL); self::$_base_querycount = NULL; self::$_cumulative_querycount = NULL; return $result; }
return; } if (!$group) { $group = $fieldPool[$field_id]->requiresSQLGrouping(); } } } } if ($this->dsParamSORT == 'system:id') { $entryManager->setFetchSorting('id', $this->dsParamORDER); } elseif ($this->dsParamSORT == 'system:date') { $entryManager->setFetchSorting('date', $this->dsParamORDER); } else { $entryManager->setFetchSorting($entryManager->fieldManager->fetchFieldIDFromElementName($this->dsParamSORT, $this->getSource()), $this->dsParamORDER); } $entries = $entryManager->fetchByPage($this->dsParamSTARTPAGE, $this->getSource(), $this->dsParamLIMIT >= 0 ? $this->dsParamLIMIT : NULL, $where, $joins, $group, !$include_pagination_element ? true : false, true); if (!($section = $entryManager->sectionManager->fetch($this->getSource()))) { $about = $this->about(); trigger_error(__('The section associated with the data source <code>%s</code> could not be found.', array($about['name'])), E_USER_ERROR); } $sectioninfo = new XMLElement('section', $section->get('name'), array('id' => $section->get('id'), 'handle' => $section->get('handle'))); $key = 'ds-' . $this->dsParamROOTELEMENT; if ($entries['total-entries'] <= 0 && (!is_array($entries['records']) || empty($entries['records']))) { if ($this->dsParamREDIRECTONEMPTY == 'yes') { $this->__redirectToErrorPage(); } $this->_force_empty_result = false; $result = $this->emptyXMLSet(); $result->prependChild($sectioninfo); if ($include_pagination_element) { $pagination_element = General::buildPaginationElement();
public function dashboardPanelRender($context) { if ($context['type'] != 'piwik') { return; } $config = $context['config']; $panel = $context['panel']; $panel->setAttribute('class', 'panel-inner piwik'); $em = new EntryManager(); $sm = new SectionManager(); // Get section information: $section = $sm->fetch($config['section']); $fields = $section->fetchVisibleColumns(); $fields = array_splice($fields, 0, isset($config['columns']) ? $config['columns'] : 4); $section_url = sprintf('%s/publish/%s/', SYMPHONY_URL, $section->get('handle')); // Get entry information: $entries = $em->fetchByPage(1, $section->get('id'), isset($config['entries']) ? $config['entries'] : 4); // Build table: $table = new XMLElement('table'); $table_head = new XMLElement('thead'); $table->appendChild($table_head); $table_body = new XMLElement('tbody'); $table->appendChild($table_body); $panel->appendChild($table); // Add table headers: $row = new XMLElement('tr'); $table_head->appendChild($row); foreach ($fields as $field) { $cell = new XMLElement('th'); $cell->setValue($field->get('label')); $row->appendChild($cell); } // Add table body: foreach ($entries['records'] as $entry) { $row = new XMLElement('tr'); $table_body->appendChild($row); $entry_url = $section_url . 'edit/' . $entry->get('id') . '/'; foreach ($fields as $position => $field) { $data = $entry->getData($field->get('id')); $cell = new XMLElement('td'); $row->appendChild($cell); $link = $position === 0 ? Widget::Anchor(__('None'), $entry_url, $entry->get('id'), 'content') : null; $value = $field->prepareTableValue($data, $link, $entry->get('id')); if (isset($link)) { $value = $link->generate(); } if ($value == 'None' || strlen($value) === 0) { $cell->setAttribute('class', 'inactive'); $cell->setValue(__('None')); } else { $cell->setValue($value); } } } }