public function dAdminPagePreGenerate($context) { $callback = Administration::instance()->getPageCallback(); if ($callback['context']['page'] === 'edit') { /** @var $cxt XMLElement */ $cxt = $context['oPage']->Context; if (!$cxt instanceof XMLElement) { return; } $actions = $cxt->getChildByName('ul', 0); // append list of actions if missing if (!$actions instanceof XMLElement) { $ul = new XMLelement('ul', null, array('class' => 'actions')); $cxt->appendChild($ul); $actions = $cxt->getChildByName('ul', 0); } // fetch entries $section_id = SectionManager::fetchIDFromHandle($callback['context']['section_handle']); $section = SectionManager::fetch($section_id); EntryManager::setFetchSorting($section->getSortingField(), $section->getSortingOrder()); $entries = EntryManager::fetch(null, $section_id, null, null, null, null, null, false, false); // get next and prev $entry_id = $prev_id = $next_id = $callback['context']['entry_id']; $count = count($entries); for ($i = 0; $i < $count; $i++) { if ($entries[$i]['id'] == $entry_id) { $prev_id = $i == 0 ? $entries[$count - 1]['id'] : $entries[$i - 1]['id']; $next_id = $i == $count - 1 ? $entries[0]['id'] : $entries[$i + 1]['id']; break; } } if ($prev_id == $entry_id && $next_id == $entry_id) { return; } // add buttons $li = new XMLelement('li', null, array('class' => 'entry-nav')); if ($prev_id !== $entry_id) { $li->appendChild(Widget::Anchor(__('← Previous'), SYMPHONY_URL . $callback['pageroot'] . 'edit/' . $prev_id, null, 'button entry-nav-prev', null, array('accesskey' => 'z'))); } if ($next_id !== $entry_id) { $li->appendChild(Widget::Anchor(__('Next →'), SYMPHONY_URL . $callback['pageroot'] . 'edit/' . $next_id, null, 'button entry-nav-next', null, array('accesskey' => 'x'))); } $actions->appendChild($li); } }
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; }
} else { // For deprecated reasons, call the old, typo'd function name until the switch to the // properly named buildDSRetrievalSQL function. if (!$fieldPool[$field_id]->buildDSRetrivalSQL($value, $joins, $where, $filter_type == DS_FILTER_AND ? true : false)) { $this->_force_empty_result = true; 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); } // 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);
public function __viewEdit() { 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); $entry_id = intval($this->_context['entry_id']); EntryManager::setFetchSorting('id', 'DESC'); if (!($existingEntry = EntryManager::fetch($entry_id))) { Administration::instance()->customError(__('Unknown Entry'), __('The entry you are looking for could not be found.')); } $existingEntry = $existingEntry[0]; // If there is post data floating around, due to errors, create an entry object if (isset($_POST['fields'])) { $fields = $_POST['fields']; $entry =& EntryManager::create(); $entry->set('section_id', $existingEntry->get('section_id')); $entry->set('id', $entry_id); $entry->setDataFromPost($fields, $errors, true); } else { $entry = $existingEntry; if (!$section) { $section = SectionManager::fetch($entry->get('section_id')); } } /** * Just prior to rendering of an Entry edit form. * * @delegate EntryPreRender * @param string $context * '/publish/edit/' * @param Section $section * @param Entry $entry * @param array $fields */ Symphony::ExtensionManager()->notifyMembers('EntryPreRender', '/publish/edit/', array('section' => $section, 'entry' => &$entry, 'fields' => $fields)); if (isset($this->_context['flag'])) { $link = 'publish/' . $this->_context['section_handle'] . '/new/'; list($flag, $field_id, $value) = preg_split('/:/i', $this->_context['flag'], 3); if (isset($_REQUEST['prepopulate'])) { $link .= '?'; foreach ($_REQUEST['prepopulate'] as $field_id => $value) { $link .= "prepopulate[{$field_id}]={$value}&"; } $link = preg_replace("/&\$/", '', $link); } // These flags are only relevant if there are no errors if (empty($this->_errors)) { switch ($flag) { case 'saved': $this->pageAlert(__('Entry updated at %s.', array(DateTimeObj::getTimeAgo())) . ' <a href="' . SYMPHONY_URL . '/' . $link . '" accesskey="c">' . __('Create another?') . '</a> <a href="' . SYMPHONY_URL . '/publish/' . $this->_context['section_handle'] . '/" accesskey="a">' . __('View all Entries') . '</a>', Alert::SUCCESS); break; case 'created': $this->pageAlert(__('Entry created at %s.', array(DateTimeObj::getTimeAgo())) . ' <a href="' . SYMPHONY_URL . '/' . $link . '" accesskey="c">' . __('Create another?') . '</a> <a href="' . SYMPHONY_URL . '/publish/' . $this->_context['section_handle'] . '/" accesskey="a">' . __('View all Entries') . '</a>', Alert::SUCCESS); break; } } } // Determine the page title $field_id = Symphony::Database()->fetchVar('id', 0, "SELECT `id` FROM `tbl_fields` WHERE `parent_section` = '" . $section->get('id') . "' ORDER BY `sortorder` LIMIT 1"); $field = FieldManager::fetch($field_id); $title = trim(strip_tags($field->prepareTableValue($existingEntry->getData($field->get('id')), NULL, $entry_id))); if (trim($title) == '') { $title = __('Untitled'); } // Check if there is a field to prepopulate if (isset($_REQUEST['prepopulate'])) { foreach ($_REQUEST['prepopulate'] as $field_id => $value) { $this->Form->prependChild(Widget::Input("prepopulate[{$field_id}]", rawurlencode($value), 'hidden')); } } $this->setPageType('form'); $this->Form->setAttribute('enctype', 'multipart/form-data'); $this->Form->setAttribute('class', 'two columns'); $this->setTitle(__('%1$s – %2$s – %3$s', array($title, $section->get('name'), __('Symphony')))); // Only show the Edit Section button if the Author is a developer. #938 ^BA if (Administration::instance()->Author->isDeveloper()) { $this->appendSubheading($title, Widget::Anchor(__('Edit Section'), SYMPHONY_URL . '/blueprints/sections/edit/' . $section_id, __('Edit Section Configuration'), 'button')); } else { $this->appendSubheading($title); } $this->insertBreadcrumbs(array(Widget::Anchor($section->get('name'), SYMPHONY_URL . '/publish/' . $this->_context['section_handle']))); $this->Form->appendChild(Widget::Input('MAX_FILE_SIZE', Symphony::Configuration()->get('max_upload_size', 'admin'), 'hidden')); $primary = new XMLElement('fieldset'); $primary->setAttribute('class', 'primary column'); $sidebar_fields = $section->fetchFields(NULL, 'sidebar'); $main_fields = $section->fetchFields(NULL, 'main'); if ((!is_array($main_fields) || empty($main_fields)) && (!is_array($sidebar_fields) || empty($sidebar_fields))) { $message = __('Fields must be added to this section before an entry can be created.'); if (Administration::instance()->Author->isDeveloper()) { $message .= ' <a href="' . SYMPHONY_URL . '/blueprints/sections/edit/' . $section->get('id') . '/" accesskey="c">' . __('Add fields') . '</a>'; } $this->pageAlert($message, Alert::ERROR); } else { if (is_array($main_fields) && !empty($main_fields)) { foreach ($main_fields as $field) { $primary->appendChild($this->__wrapFieldWithDiv($field, $entry)); } $this->Form->appendChild($primary); } if (is_array($sidebar_fields) && !empty($sidebar_fields)) { $sidebar = new XMLElement('fieldset'); $sidebar->setAttribute('class', 'secondary column'); foreach ($sidebar_fields as $field) { $sidebar->appendChild($this->__wrapFieldWithDiv($field, $entry)); } $this->Form->appendChild($sidebar); } $div = new XMLElement('div'); $div->setAttribute('class', 'actions'); $div->appendChild(Widget::Input('action[save]', __('Save Changes'), 'submit', array('accesskey' => 's'))); $button = new XMLElement('button', __('Delete')); $button->setAttributeArray(array('name' => 'action[delete]', 'class' => 'button confirm delete', 'title' => __('Delete this entry'), 'type' => 'submit', 'accesskey' => 'd', 'data-message' => __('Are you sure you want to delete this entry?'))); $div->appendChild($button); $this->Form->appendChild($div); } }
public function __viewEdit() { $sectionManager = new SectionManager($this->_Parent); if (!($section_id = $sectionManager->fetchIDFromHandle($this->_context['section_handle']))) { Administration::instance()->customError(__('Unknown Section'), __('The Section you are looking for, <code>%s</code>, could not be found.', array($this->_context['section_handle']))); } $section = $sectionManager->fetch($section_id); $entry_id = intval($this->_context['entry_id']); $entryManager = new EntryManager($this->_Parent); $entryManager->setFetchSorting('id', 'DESC'); if (!($existingEntry = $entryManager->fetch($entry_id))) { Administration::instance()->customError(__('Unknown Entry'), __('The entry you are looking for could not be found.')); } $existingEntry = $existingEntry[0]; // If there is post data floating around, due to errors, create an entry object if (isset($_POST['fields'])) { $fields = $_POST['fields']; $entry =& $entryManager->create(); $entry->set('section_id', $existingEntry->get('section_id')); $entry->set('id', $entry_id); $entry->setDataFromPost($fields, $error, true); } else { $entry = $existingEntry; if (!$section) { $section = $sectionManager->fetch($entry->get('section_id')); } } /** * Just prior to rendering of an Entry edit form. * * @delegate EntryPreRender * @param string $context * '/publish/new/' * @param Section $section * @param Entry $entry * @param array $fields */ Symphony::ExtensionManager()->notifyMembers('EntryPreRender', '/publish/edit/', array('section' => $section, 'entry' => &$entry, 'fields' => $fields)); if (isset($this->_context['flag'])) { $link = 'publish/' . $this->_context['section_handle'] . '/new/'; list($flag, $field_id, $value) = preg_split('/:/i', $this->_context['flag'], 3); if (is_numeric($field_id) && $value) { $link .= "?prepopulate[{$field_id}]={$value}"; $this->Form->prependChild(Widget::Input("prepopulate[{$field_id}]", rawurlencode($value), 'hidden')); } switch ($flag) { case 'saved': $this->pageAlert(__('Entry updated at %1$s. <a href="%2$s" accesskey="c">Create another?</a> <a href="%3$s" accesskey="a">View all Entries</a>', array(DateTimeObj::getTimeAgo(__SYM_TIME_FORMAT__), SYMPHONY_URL . "/{$link}", SYMPHONY_URL . '/publish/' . $this->_context['section_handle'] . '/')), Alert::SUCCESS); break; case 'created': $this->pageAlert(__('Entry created at %1$s. <a href="%2$s" accesskey="c">Create another?</a> <a href="%3$s" accesskey="a">View all Entries</a>', array(DateTimeObj::getTimeAgo(__SYM_TIME_FORMAT__), SYMPHONY_URL . "/{$link}", SYMPHONY_URL . '/publish/' . $this->_context['section_handle'] . '/')), Alert::SUCCESS); break; } } ### Determine the page title $field_id = Symphony::Database()->fetchVar('id', 0, "SELECT `id` FROM `tbl_fields` WHERE `parent_section` = '" . $section->get('id') . "' ORDER BY `sortorder` LIMIT 1"); $field = $entryManager->fieldManager->fetch($field_id); $title = trim(strip_tags($field->prepareTableValue($existingEntry->getData($field->get('id')), NULL, $entry_id))); if (trim($title) == '') { $title = 'Untitled'; } // Check if there is a field to prepopulate if (isset($_REQUEST['prepopulate'])) { $field_id = array_shift(array_keys($_REQUEST['prepopulate'])); $value = stripslashes(rawurldecode(array_shift($_REQUEST['prepopulate']))); $this->Form->prependChild(Widget::Input("prepopulate[{$field_id}]", rawurlencode($value), 'hidden')); } $this->setPageType('form'); $this->Form->setAttribute('enctype', 'multipart/form-data'); $this->setTitle(__('%1$s – %2$s – %3$s', array(__('Symphony'), $section->get('name'), $title))); $this->appendSubheading($title); $this->Form->appendChild(Widget::Input('MAX_FILE_SIZE', Symphony::Configuration()->get('max_upload_size', 'admin'), 'hidden')); ### $primary = new XMLElement('fieldset'); $primary->setAttribute('class', 'primary'); $sidebar_fields = $section->fetchFields(NULL, 'sidebar'); $main_fields = $section->fetchFields(NULL, 'main'); if ((!is_array($main_fields) || empty($main_fields)) && (!is_array($sidebar_fields) || empty($sidebar_fields))) { $primary->appendChild(new XMLElement('p', __('It looks like you\'re trying to create an entry. Perhaps you want fields first? <a href="%s">Click here to create some.</a>', array(SYMPHONY_URL . '/blueprints/sections/edit/' . $section->get('id') . '/')))); } else { if (is_array($main_fields) && !empty($main_fields)) { foreach ($main_fields as $field) { $primary->appendChild($this->__wrapFieldWithDiv($field, $entry)); } $this->Form->appendChild($primary); } if (is_array($sidebar_fields) && !empty($sidebar_fields)) { $sidebar = new XMLElement('fieldset'); $sidebar->setAttribute('class', 'secondary'); foreach ($sidebar_fields as $field) { $sidebar->appendChild($this->__wrapFieldWithDiv($field, $entry)); } $this->Form->appendChild($sidebar); } } $div = new XMLElement('div'); $div->setAttribute('class', 'actions'); $div->appendChild(Widget::Input('action[save]', __('Save Changes'), 'submit', array('accesskey' => 's'))); $button = new XMLElement('button', __('Delete')); $button->setAttributeArray(array('name' => 'action[delete]', 'class' => 'button confirm delete', 'title' => __('Delete this entry'), 'type' => 'submit', 'accesskey' => 'd', 'data-message' => __('Are you sure you want to delete this entry?'))); $div->appendChild($button); $this->Form->appendChild($div); }
public function __viewEdit() { if (!($section_id = SectionManager::fetchIDFromHandle($this->_context['section_handle']))) { Administration::instance()->throwCustomError(__('The Section, %s, could not be found.', array('<code>' . $this->_context['section_handle'] . '</code>')), __('Unknown Section'), Page::HTTP_STATUS_NOT_FOUND); } $section = SectionManager::fetch($section_id); $entry_id = intval($this->_context['entry_id']); $base = '/publish/' . $this->_context['section_handle'] . '/'; $new_link = $base . 'new/'; $filter_link = $base; EntryManager::setFetchSorting('id', 'DESC'); if (!($existingEntry = EntryManager::fetch($entry_id))) { Administration::instance()->throwCustomError(__('Unknown Entry'), __('The Entry, %s, could not be found.', array($entry_id)), Page::HTTP_STATUS_NOT_FOUND); } $existingEntry = $existingEntry[0]; // If there is post data floating around, due to errors, create an entry object if (isset($_POST['fields'])) { $fields = $_POST['fields']; $entry = EntryManager::create(); $entry->set('id', $entry_id); $entry->set('author_id', $existingEntry->get('author_id')); $entry->set('section_id', $existingEntry->get('section_id')); $entry->set('creation_date', $existingEntry->get('creation_date')); $entry->set('modification_date', $existingEntry->get('modification_date')); $entry->setDataFromPost($fields, $errors, true); // Editing an entry, so need to create some various objects } else { $entry = $existingEntry; $fields = array(); if (!$section) { $section = SectionManager::fetch($entry->get('section_id')); } } /** * Just prior to rendering of an Entry edit form. * * @delegate EntryPreRender * @param string $context * '/publish/edit/' * @param Section $section * @param Entry $entry * @param array $fields */ Symphony::ExtensionManager()->notifyMembers('EntryPreRender', '/publish/edit/', array('section' => $section, 'entry' => &$entry, 'fields' => $fields)); // Iterate over the `prepopulate` parameters to build a URL // to remember this state for Create New, View all Entries and // Breadcrumb links. If `prepopulate` doesn't exist, this will // just use the standard pages (ie. no filtering) if (isset($_REQUEST['prepopulate'])) { $new_link .= $this->getPrepopulateString(); $filter_link .= $this->getFilterString(); } if (isset($this->_context['flag'])) { // These flags are only relevant if there are no errors if (empty($this->_errors)) { $time = Widget::Time(); switch ($this->_context['flag']) { case 'saved': $message = __('Entry updated at %s.', array($time->generate())); break; case 'created': $message = __('Entry created at %s.', array($time->generate())); } $this->pageAlert($message . ' <a href="' . SYMPHONY_URL . $new_link . '" accesskey="c">' . __('Create another?') . '</a> <a href="' . SYMPHONY_URL . $filter_link . '" accesskey="a">' . __('View all Entries') . '</a>', Alert::SUCCESS); } } // Determine the page title $field_id = Symphony::Database()->fetchVar('id', 0, sprintf("\n SELECT `id`\n FROM `tbl_fields`\n WHERE `parent_section` = %d\n ORDER BY `sortorder` LIMIT 1", $section->get('id'))); if (!is_null($field_id)) { $field = FieldManager::fetch($field_id); } if ($field) { $title = $field->prepareReadableValue($existingEntry->getData($field->get('id')), $entry_id, true); } else { $title = ''; } if (trim($title) == '') { $title = __('Untitled'); } // Check if there is a field to prepopulate if (isset($_REQUEST['prepopulate'])) { foreach ($_REQUEST['prepopulate'] as $field_id => $value) { $this->Form->prependChild(Widget::Input("prepopulate[{$field_id}]", rawurlencode($value), 'hidden')); } } $this->setPageType('form'); $this->Form->setAttribute('enctype', 'multipart/form-data'); $this->setTitle(__('%1$s – %2$s – %3$s', array($title, $section->get('name'), __('Symphony')))); $sidebar_fields = $section->fetchFields(null, 'sidebar'); $main_fields = $section->fetchFields(null, 'main'); if (!empty($sidebar_fields) && !empty($main_fields)) { $this->Form->setAttribute('class', 'two columns'); } else { $this->Form->setAttribute('class', 'columns'); } // Only show the Edit Section button if the Author is a developer. #938 ^BA if (Symphony::Author()->isDeveloper()) { $this->appendSubheading($title, Widget::Anchor(__('Edit Section'), SYMPHONY_URL . '/blueprints/sections/edit/' . $section_id . '/', __('Edit Section Configuration'), 'button')); } else { $this->appendSubheading($title); } $this->insertBreadcrumbs(array(Widget::Anchor($section->get('name'), SYMPHONY_URL . (isset($filter_link) ? $filter_link : $base)))); $this->Form->appendChild(Widget::Input('MAX_FILE_SIZE', Symphony::Configuration()->get('max_upload_size', 'admin'), 'hidden')); $primary = new XMLElement('fieldset'); $primary->setAttribute('class', 'primary column'); if ((!is_array($main_fields) || empty($main_fields)) && (!is_array($sidebar_fields) || empty($sidebar_fields))) { $message = __('Fields must be added to this section before an entry can be created.'); if (Symphony::Author()->isDeveloper()) { $message .= ' <a href="' . SYMPHONY_URL . '/blueprints/sections/edit/' . $section->get('id') . '/" accesskey="c">' . __('Add fields') . '</a>'; } $this->pageAlert($message, Alert::ERROR); } else { if (is_array($main_fields) && !empty($main_fields)) { foreach ($main_fields as $field) { $primary->appendChild($this->__wrapFieldWithDiv($field, $entry)); } $this->Form->appendChild($primary); } if (is_array($sidebar_fields) && !empty($sidebar_fields)) { $sidebar = new XMLElement('fieldset'); $sidebar->setAttribute('class', 'secondary column'); foreach ($sidebar_fields as $field) { $sidebar->appendChild($this->__wrapFieldWithDiv($field, $entry)); } $this->Form->appendChild($sidebar); } $div = new XMLElement('div'); $div->setAttribute('class', 'actions'); $div->appendChild(Widget::Input('action[save]', __('Save Changes'), 'submit', array('accesskey' => 's'))); $button = new XMLElement('button', __('Delete')); $button->setAttributeArray(array('name' => 'action[delete]', 'class' => 'button confirm delete', 'title' => __('Delete this entry'), 'type' => 'submit', 'accesskey' => 'd', 'data-message' => __('Are you sure you want to delete this entry?'))); $div->appendChild($button); $this->Form->appendChild($div); // Create a Drawer for Associated Sections $this->prepareAssociationsDrawer($section); } }
protected function findRelatedValues(array $relation_id = array()) { // 1. Get the field instances from the SBL's related_field_id's // FieldManager->fetch doesn't take an array of ID's (unlike other managers) // so instead we'll instead build a custom where to emulate the same result // We also cache the result of this where to prevent subsequent calls to this // field repeating the same query. $where = ' AND id IN (' . implode(',', $this->get('related_field_id')) . ') '; $hash = md5($where); if (!isset(self::$cache[$hash]['fields'])) { $fields = FieldManager::fetch(null, null, 'ASC', 'sortorder', null, null, $where); if (!is_array($fields)) { $fields = array($fields); } self::$cache[$hash]['fields'] = $fields; } else { $fields = self::$cache[$hash]['fields']; } if (empty($fields)) { return array(); } // 2. Find all the provided `relation_id`'s related section // We also cache the result using the `relation_id` as identifier // to prevent unnecessary queries $relation_id = array_filter($relation_id); if (empty($relation_id)) { return array(); } $hash = md5(serialize($relation_id) . $this->get('element_name')); if (!isset(self::$cache[$hash]['relation_data'])) { $relation_ids = Symphony::Database()->fetch(sprintf("SELECT e.id, e.section_id, s.name, s.handle\n FROM `tbl_entries` AS `e`\n LEFT JOIN `tbl_sections` AS `s` ON (s.id = e.section_id)\n WHERE e.id IN (%s)", implode(',', $relation_id))); // 3. Group the `relation_id`'s by section_id $section_ids = array(); $section_info = array(); foreach ($relation_ids as $relation_information) { $section_ids[$relation_information['section_id']][] = $relation_information['id']; if (!array_key_exists($relation_information['section_id'], $section_info)) { $section_info[$relation_information['section_id']] = array('name' => $relation_information['name'], 'handle' => $relation_information['handle']); } } // 4. Foreach Group, use the EntryManager to fetch the entry information // using the schema option to only return data for the related field $relation_data = array(); foreach ($section_ids as $section_id => $entry_data) { $schema = array(); // Get schema foreach ($fields as $field) { if ($field->get('parent_section') == $section_id) { $schema = array($field->get('element_name')); break; } } $section = SectionManager::fetch($section_id); if ($section instanceof Section === false) { continue; } EntryManager::setFetchSorting($section->getSortingField(), $section->getSortingOrder()); $entries = EntryManager::fetch(array_values($entry_data), $section_id, null, null, null, null, false, true, $schema); foreach ($entries as $entry) { $field_data = $entry->getData($field->get('id')); if (is_array($field_data) === false || empty($field_data)) { continue; } // Get unformatted content: if ($field instanceof ExportableField && in_array(ExportableField::UNFORMATTED, $field->getExportModes())) { $value = $field->prepareExportValue($field_data, ExportableField::UNFORMATTED, $entry->get('id')); } else { if ($field instanceof ExportableField && in_array(ExportableField::VALUE, $field->getExportModes())) { // Get values: $value = $field->prepareExportValue($field_data, ExportableField::VALUE, $entry->get('id')); } else { // Handle fields that are not exportable: $value = $field->getParameterPoolValue($field_data, $entry->get('id')); if (is_array($value) && count($value) === 1) { $value = implode($value); } } } /** * To ensure that the output is 'safe' for whoever consumes this function, * we will sanitize the value. Before sanitizing, we will reverse sanitise * the value to handle the scenario where the Field has been good and * has already sanitized the value. * * @see https://github.com/symphonycms/symphony-2/issues/2318 */ $value = General::sanitize(General::reverse_sanitize($value)); $relation_data[] = array('id' => $entry->get('id'), 'section_handle' => $section_info[$section_id]['handle'], 'section_name' => $section_info[$section_id]['name'], 'value' => $value); } } self::$cache[$hash]['relation_data'] = $relation_data; } else { $relation_data = self::$cache[$hash]['relation_data']; } // 6. Return the resulting array containing the id, section_handle, section_name and value return $relation_data; }
function __viewEdit() { $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 for, <code>%s</code>, could not be found.', array($this->_context['section_handle'])), false, true); } $section = $sectionManager->fetch($section_id); $entry_id = intval($this->_context['entry_id']); $entryManager = new EntryManager($this->_Parent); $entryManager->setFetchSorting('id', 'DESC'); if (!($existingEntry = $entryManager->fetch($entry_id))) { $this->_Parent->customError(E_USER_ERROR, __('Unknown Entry'), __('The entry you are looking for could not be found.'), false, true); } $existingEntry = $existingEntry[0]; // If there is post data floating around, due to errors, create an entry object if (isset($_POST['fields'])) { $fields = $_POST['fields']; $entry =& $entryManager->create(); $entry->set('section_id', $existingEntry->get('section_id')); $entry->set('id', $entry_id); $entry->setDataFromPost($fields, $error, true); } else { $entry = $existingEntry; if (!$section) { $section = $sectionManager->fetch($entry->get('section_id')); } } if (isset($this->_context['flag'])) { $link = 'publish/' . $this->_context['section_handle'] . '/new/'; list($flag, $field_id, $value) = preg_split('/:/i', $this->_context['flag'], 3); if (is_numeric($field_id) && $value) { $link .= "?prepopulate[{$field_id}]={$value}"; } switch ($flag) { case 'saved': $this->pageAlert(__('Entry updated at %1$s. <a href="%2$s">Create another?</a> <a href="%3$s">View all Entries</a>', array(DateTimeObj::getTimeAgo(__SYM_TIME_FORMAT__), URL . "/symphony/{$link}", URL . '/symphony/publish/' . $this->_context['section_handle'] . '/')), Alert::SUCCESS); break; case 'created': $this->pageAlert(__('Entry created at %1$s. <a href="%2$s">Create another?</a> <a href="%3$s">View all Entries</a>', array(DateTimeObj::getTimeAgo(__SYM_TIME_FORMAT__), URL . "/symphony/{$link}", URL . '/symphony/publish/' . $this->_context['section_handle'] . '/')), Alert::SUCCESS); break; } } ### Determine the page title $field_id = $this->_Parent->Database->fetchVar('id', 0, "SELECT `id` FROM `tbl_fields` WHERE `parent_section` = '" . $section->get('id') . "' ORDER BY `sortorder` LIMIT 1"); $field = $entryManager->fieldManager->fetch($field_id); $title = trim(strip_tags($field->prepareTableValue($existingEntry->getData($field->get('id')), NULL, $entry_id))); if (trim($title) == '') { $title = 'Untitled'; } $this->setPageType('form'); $this->Form->setAttribute('enctype', 'multipart/form-data'); $this->setTitle(__('%1$s – %2$s – %3$s', array(__('Symphony'), $section->get('name'), $title))); $this->appendSubheading($title); $this->Form->appendChild(Widget::Input('MAX_FILE_SIZE', $this->_Parent->Configuration->get('max_upload_size', 'admin'), 'hidden')); ### $primary = new XMLElement('fieldset'); $primary->setAttribute('class', 'primary'); $sidebar_fields = $section->fetchFields(NULL, 'sidebar'); $main_fields = $section->fetchFields(NULL, 'main'); if ((!is_array($main_fields) || empty($main_fields)) && (!is_array($sidebar_fields) || empty($sidebar_fields))) { $primary->appendChild(new XMLElement('p', __('It looks like your trying to create an entry. Perhaps you want custom fields first? <a href="%s">Click here to create some.</a>', array(URL . '/symphony/blueprints/sections/edit/' . $section->get('id') . '/')))); } else { if (is_array($main_fields) && !empty($main_fields)) { foreach ($main_fields as $field) { $primary->appendChild($this->__wrapFieldWithDiv($field, $entry)); } $this->Form->appendChild($primary); } if (is_array($sidebar_fields) && !empty($sidebar_fields)) { $sidebar = new XMLElement('fieldset'); $sidebar->setAttribute('class', 'secondary'); foreach ($sidebar_fields as $field) { $sidebar->appendChild($this->__wrapFieldWithDiv($field, $entry)); } $this->Form->appendChild($sidebar); } } $div = new XMLElement('div'); $div->setAttribute('class', 'actions'); $div->appendChild(Widget::Input('action[save]', __('Save Changes'), 'submit', array('accesskey' => 's'))); $button = new XMLElement('button', __('Delete')); $button->setAttributeArray(array('name' => 'action[delete]', 'class' => 'confirm delete', 'title' => __('Delete this entry'))); $div->appendChild($button); $this->Form->appendChild($div); }
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; }
public function prepareTableValue($data, XMLElement $link = null, $entry_id = null) { header('content-type: text/plain'); $sectionManager = new SectionManager($this->_engine); $section = $sectionManager->fetch($this->get('linked_section_id')); $entryManager = new EntryManager($this->_engine); $fieldManager = new FieldManager($this->_engine); $linked = $fieldManager->fetch($this->get('linked_field_id')); $custom_link = null; $more_link = null; // Not setup correctly: if (!$section instanceof Section) { return parent::prepareTableValue(array(), $link, $entry_id); } if ($section instanceof Section) { $field = current($section->fetchVisibleColumns()); $data = $this->prepareData($data); if (!is_null($field)) { if ($this->get('column_mode') != 'count') { if ($this->get('column_mode') == 'last-item') { $order = 'ASC'; } else { $order = 'DESC'; } $entryManager->setFetchSorting('date', $order); $entries = $entryManager->fetch($data['linked_entry_id'], $this->get('linked_section_id'), 1); if (is_array($entries) and !empty($entries)) { $entry = current($entries); $value = $field->prepareTableValue($entry->getData($field->get('id')), new XMLElement('span')); $custom_link = new XMLElement('a'); $custom_link->setAttribute('href', sprintf('%s/symphony/publish/%s/edit/%s/', URL, $section->get('handle'), $entry->get('id'))); if ($value instanceof XMLElement) { $value = $value->generate(); } $custom_link->setValue(strip_tags($value)); $more_link = new XMLElement('a'); $more_link->setValue(__('more →')); $more_link->setAttribute('href', sprintf('%s/symphony/publish/%s/?filter=%s:%s', URL, $section->get('handle'), $linked->get('element_name'), $entry_id)); } } else { $joins = null; $where = null; $linked->buildDSRetrivalSQL(array($entry_id), $joins, $where, false); $count = $entryManager->fetchCount($this->get('linked_section_id'), $where, $joins); if ($count > 0) { $custom_link = new XMLElement('a'); $custom_link->setValue($count . __(' →')); $custom_link->setAttribute('href', sprintf('%s/symphony/publish/%s/?filter=%s:%s', URL, $section->get('handle'), $linked->get('element_name'), $entry_id)); } } } } if (is_null($custom_link)) { $custom_link = new XMLElement('a'); $custom_link->setValue(__('0 →')); $custom_link->setAttribute('href', sprintf('%s/symphony/publish/%s/?filter=%s:%s', URL, $section->get('handle'), $linked->get('element_name'), $entry_id)); if ($this->get('column_mode') != 'count') { $more_link = $custom_link; $more_link->setValue(__('more →')); $custom_link = new XMLElement('span'); $custom_link->setAttribute('class', 'inactive'); $custom_link->setValue(__('None')); } } if ($link) { $link->setValue($custom_link->getValue()); return $link->generate(); } if ($this->get('column_mode') != 'count') { $wrapper = new XMLElement('span'); $wrapper->setValue(sprintf('%s, %s', $custom_link->generate(), $more_link->generate())); return $wrapper; } return $custom_link; }