This class is designed to work in the Symphony backend only, and not on the Frontend.
 public function __viewIndex()
 {
     $this->setPageType('table');
     $this->setTitle(__('%1$s – %2$s', array(__('Authors'), __('Symphony'))));
     if (Administration::instance()->Author->isDeveloper()) {
         $this->appendSubheading(__('Authors'), Widget::Anchor(__('Create New'), Administration::instance()->getCurrentPageURL() . 'new/', __('Create a new author'), 'create button', NULL, array('accesskey' => 'c')));
     } else {
         $this->appendSubheading(__('Authors'));
     }
     Sortable::initialize($this, $authors, $sort, $order);
     $columns = array(array('label' => __('Name'), 'sortable' => true, 'handle' => 'name'), array('label' => __('Email Address'), 'sortable' => true, 'handle' => 'email'), array('label' => __('Last Seen'), 'sortable' => true, 'handle' => 'last_seen'));
     if (Administration::instance()->Author->isDeveloper()) {
         $columns = array_merge($columns, array(array('label' => __('User Type'), 'sortable' => true, 'handle' => 'user_type'), array('label' => __('Language'), 'sortable' => true, 'handle' => 'language')));
     }
     $aTableHead = Sortable::buildTableHeaders($columns, $sort, $order, isset($_REQUEST['filter']) ? '&filter=' . $_REQUEST['filter'] : '');
     $aTableBody = array();
     if (!is_array($authors) || empty($authors)) {
         $aTableBody = array(Widget::TableRow(array(Widget::TableData(__('None found.'), 'inactive', NULL, count($aTableHead))), 'odd'));
     } else {
         foreach ($authors as $a) {
             // Setup each cell
             if (Administration::instance()->Author->isDeveloper() || Administration::instance()->Author->get('id') == $a->get('id')) {
                 $td1 = Widget::TableData(Widget::Anchor($a->getFullName(), Administration::instance()->getCurrentPageURL() . 'edit/' . $a->get('id') . '/', $a->get('username'), 'author'));
             } else {
                 $td1 = Widget::TableData($a->getFullName(), 'inactive');
             }
             $td2 = Widget::TableData(Widget::Anchor($a->get('email'), 'mailto:' . $a->get('email'), __('Email this author')));
             if (!is_null($a->get('last_seen'))) {
                 $td3 = Widget::TableData(DateTimeObj::format($a->get('last_seen'), __SYM_DATETIME_FORMAT__));
             } else {
                 $td3 = Widget::TableData(__('Unknown'), 'inactive');
             }
             $td4 = Widget::TableData($a->isDeveloper() ? __("Developer") : __("Author"));
             $languages = Lang::getAvailableLanguages();
             $td5 = Widget::TableData($a->get("language") == NULL ? __("System Default") : $languages[$a->get("language")]);
             if (Administration::instance()->Author->isDeveloper()) {
                 if ($a->get('id') != Administration::instance()->Author->get('id')) {
                     $td3->appendChild(Widget::Input('items[' . $a->get('id') . ']', NULL, 'checkbox'));
                 }
             }
             // Add a row to the body array, assigning each cell to the row
             if (Administration::instance()->Author->isDeveloper()) {
                 $aTableBody[] = Widget::TableRow(array($td1, $td2, $td3, $td4, $td5));
             } else {
                 $aTableBody[] = Widget::TableRow(array($td1, $td2, $td3));
             }
         }
     }
     $table = Widget::Table(Widget::TableHead($aTableHead), NULL, Widget::TableBody($aTableBody), 'selectable');
     $this->Form->appendChild($table);
     if (Administration::instance()->Author->isDeveloper()) {
         $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 authors?'))));
         $tableActions->appendChild(Widget::Apply($options));
         $this->Form->appendChild($tableActions);
     }
 }
Пример #2
0
 /**
  * This function contains the minimal amount of logic for generating the
  * index table of a given `$resource_type`. The table has name, source, pages
  * release date and author columns. The values for these columns are determined
  * by the resource's `about()` method.
  *
  * As Datasources types can be installed using Providers, the Source column
  * can be overridden with a Datasource's `getSourceColumn` method (if it exists).
  *
  * @param integer $resource_type
  *  Either `RESOURCE_TYPE_EVENT` or `RESOURCE_TYPE_DATASOURCE`
  * @throws InvalidArgumentException
  */
 public function __viewIndex($resource_type)
 {
     $manager = ResourceManager::getManagerFromType($resource_type);
     $friendly_resource = $resource_type === RESOURCE_TYPE_EVENT ? __('Event') : __('DataSource');
     $this->setPageType('table');
     Sortable::initialize($this, $resources, $sort, $order, array('type' => $resource_type));
     $columns = array(array('label' => __('Name'), 'sortable' => true, 'handle' => 'name'), array('label' => __('Source'), 'sortable' => true, 'handle' => 'source'), array('label' => __('Pages'), 'sortable' => false), array('label' => __('Author'), 'sortable' => true, 'handle' => 'author'));
     $aTableHead = Sortable::buildTableHeaders($columns, $sort, $order, isset($_REQUEST['filter']) ? '&filter=' . $_REQUEST['filter'] : '');
     $aTableBody = array();
     if (!is_array($resources) || empty($resources)) {
         $aTableBody = array(Widget::TableRow(array(Widget::TableData(__('None found.'), 'inactive', null, count($aTableHead))), 'odd'));
     } else {
         $context = Administration::instance()->getPageCallback();
         foreach ($resources as $r) {
             $action = 'edit';
             $status = null;
             $locked = null;
             // Locked resources
             if (isset($r['can_parse']) && $r['can_parse'] !== true) {
                 $action = 'info';
                 $status = 'status-notice';
                 $locked = array('data-status' => ' — ' . __('read only'));
             }
             // Resource name
             $action = isset($r['can_parse']) && $r['can_parse'] === true ? 'edit' : 'info';
             $name = Widget::TableData(Widget::Anchor($r['name'], SYMPHONY_URL . $context['pageroot'] . $action . '/' . $r['handle'] . '/', $r['handle'], 'resource-' . $action, null, $locked));
             $name->appendChild(Widget::Label(__('Select ' . $friendly_resource . ' %s', array($r['name'])), null, 'accessible', null, array('for' => 'resource-' . $r['handle'])));
             $name->appendChild(Widget::Input('items[' . $r['handle'] . ']', 'on', 'checkbox', array('id' => 'resource-' . $r['handle'])));
             // Resource type/source
             if (isset($r['source'], $r['source']['id'])) {
                 $section = Widget::TableData(Widget::Anchor($r['source']['name'], SYMPHONY_URL . '/blueprints/sections/edit/' . $r['source']['id'] . '/', $r['source']['handle']));
             } elseif (isset($r['source']) && class_exists($r['source']['name']) && method_exists($r['source']['name'], 'getSourceColumn')) {
                 $class = call_user_func(array($manager, '__getClassName'), $r['handle']);
                 $section = Widget::TableData(call_user_func(array($class, 'getSourceColumn'), $r['handle']));
             } elseif (isset($r['source'], $r['source']['name'])) {
                 $section = Widget::TableData($r['source']['name']);
             } else {
                 $section = Widget::TableData(__('Unknown'), 'inactive');
             }
             // Attached pages
             $pages = ResourceManager::getAttachedPages($resource_type, $r['handle']);
             $pagelinks = array();
             $i = 0;
             foreach ($pages as $p) {
                 ++$i;
                 $pagelinks[] = Widget::Anchor($p['title'], SYMPHONY_URL . '/blueprints/pages/edit/' . $p['id'] . '/')->generate() . (count($pages) > $i ? $i % 10 == 0 ? '<br />' : ', ' : '');
             }
             $pages = implode('', $pagelinks);
             if ($pages == '') {
                 $pagelinks = Widget::TableData(__('None'), 'inactive');
             } else {
                 $pagelinks = Widget::TableData($pages, 'pages');
             }
             // Authors
             $author = $r['author']['name'];
             if ($author) {
                 if (isset($r['author']['website'])) {
                     $author = Widget::Anchor($r['author']['name'], General::validateURL($r['author']['website']));
                 } elseif (isset($r['author']['email'])) {
                     $author = Widget::Anchor($r['author']['name'], 'mailto:' . $r['author']['email']);
                 }
             }
             $author = Widget::TableData($author);
             $aTableBody[] = Widget::TableRow(array($name, $section, $pagelinks, $author), $status);
         }
     }
     $table = Widget::Table(Widget::TableHead($aTableHead), null, Widget::TableBody($aTableBody), 'selectable', null, array('role' => 'directory', 'aria-labelledby' => 'symphony-subheading', 'data-interactive' => 'data-interactive'));
     $this->Form->appendChild($table);
     $version = new XMLElement('p', 'Symphony ' . Symphony::Configuration()->get('version', 'symphony'), array('id' => 'version'));
     $this->Form->appendChild($version);
     $tableActions = new XMLElement('div');
     $tableActions->setAttribute('class', 'actions');
     $options = array(array(null, false, __('With Selected...')), array('delete', false, __('Delete'), 'confirm'));
     $pages = $this->pagesFlatView();
     $group_attach = array('label' => __('Attach to Page'), 'options' => array());
     $group_detach = array('label' => __('Detach from Page'), 'options' => array());
     $group_attach['options'][] = array('attach-all-pages', false, __('All'));
     $group_detach['options'][] = array('detach-all-pages', false, __('All'));
     foreach ($pages as $p) {
         $group_attach['options'][] = array('attach-to-page-' . $p['id'], false, $p['title']);
         $group_detach['options'][] = array('detach-from-page-' . $p['id'], false, $p['title']);
     }
     $options[] = $group_attach;
     $options[] = $group_detach;
     /**
      * Allows an extension to modify the existing options for this page's
      * With Selected menu. If the `$options` parameter is an empty array,
      * the 'With Selected' menu will not be rendered.
      *
      * @delegate AddCustomActions
      * @since Symphony 2.3.2
      * @param string $context
      * '/blueprints/datasources/' or '/blueprints/events/'
      * @param array $options
      *  An array of arrays, where each child array represents an option
      *  in the With Selected menu. Options should follow the same format
      *  expected by `Widget::__SelectBuildOption`. Passed by reference.
      */
     Symphony::ExtensionManager()->notifyMembers('AddCustomActions', $context['pageroot'], array('options' => &$options));
     if (!empty($options)) {
         $tableActions->appendChild(Widget::Apply($options));
         $this->Form->appendChild($tableActions);
     }
 }
Пример #3
0
                            </a>
                            <a href="?page_view=grid" >
                                <i class="fa fa-th" title="Таблица"></i>
                            </a>
                        </div>
                    </div>
                    <div class="col-md-5 text-right">
                        <label class="control-label">Сортировать по:</label>
                    </div>
                    <div class="col-md-2 text-right">
                        <div class="sort_list">
                            <?php 
echo Sortable::get_button('price', 'цене', null, true);
?>
                            <?php 
echo Sortable::get_button('name', 'названию', null, true);
?>
                        </div>
                    </div>
                </div>
            </div>
            <!-- Product Filter Ends -->
            <!-- Product Grid Display Starts -->
            <section class="products-list">
                <div class="row">
                    <?php 
foreach ($product as $index => $prod) {
    if ($prod->new_price) {
        $price = $prod->new_price;
    } else {
        $price = $prod->price;
 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 &ndash; %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&amp;", $handle, rawurlencode($value));
                 $prepopulate_querystring .= sprintf("prepopulate[%d]=%s&amp;", $field_id, rawurlencode($value));
             } else {
                 unset($filters[$handle]);
             }
         }
         $filter_querystring = preg_replace("/&amp;\$/", '', $filter_querystring);
         $prepopulate_querystring = preg_replace("/&amp;\$/", '', $prepopulate_querystring);
     }
     Sortable::initialize($this, $entries, $sort, $order, array('current-section' => $section, 'filters' => $filter_querystring ? "&amp;" . $filter_querystring : '', 'unsort' => isset($_REQUEST['unsort'])));
     $this->Form->setAttribute('action', Administration::instance()->getCurrentPageURL() . '?pg=' . $current_page . ($filter_querystring ? "&amp;" . $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 ? "&amp;" . $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 &rarr;', 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 ? "&amp;" . $filter_querystring : '')));
         } else {
             $li->setValue(__('First'));
         }
         $ul->appendChild($li);
         // Previous
         $li = new XMLElement('li');
         if ($current_page > 1) {
             $li->appendChild(Widget::Anchor(__('&larr; Previous'), Administration::instance()->getCurrentPageURL() . '?pg=' . ($current_page - 1) . ($filter_querystring ? "&amp;" . $filter_querystring : '')));
         } else {
             $li->setValue(__('&larr; Previous'));
         }
         $ul->appendChild($li);
         // Summary
         $li = new XMLElement('li');
         $li->setAttribute('title', __('Viewing %1$s - %2$s of %3$s entries', array($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 &rarr;'), Administration::instance()->getCurrentPageURL() . '?pg=' . ($current_page + 1) . ($filter_querystring ? "&amp;" . $filter_querystring : '')));
         } else {
             $li->setValue(__('Next &rarr;'));
         }
         $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 ? "&amp;" . $filter_querystring : '')));
         } else {
             $li->setValue(__('Last'));
         }
         $ul->appendChild($li);
         $this->Contents->appendChild($ul);
     }
 }
 public function __viewIndex()
 {
     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);
     } else {
         if (!is_writable(CONFIG)) {
             $this->pageAlert(__('The Symphony configuration file, %s, is not writable. The sort order cannot be modified.', array('<code>/manifest/config.php</code>')), Alert::NOTICE);
         }
     }
     $section = SectionManager::fetch($section_id);
     $this->setPageType('table');
     $this->setTitle(__('%1$s &ndash; %2$s', array($section->get('name'), __('Symphony'))));
     $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) {
             // Handle multiple values through filtering. RE: #2290
             if (is_array($value) && empty($value) || trim($value) == '') {
                 continue;
             }
             if (!is_array($value)) {
                 $filter_type = Datasource::determineFilterType($value);
                 $value = preg_split('/' . ($filter_type == Datasource::FILTER_AND ? '\\+' : '(?<!\\\\),') . '\\s*/', $value, -1, PREG_SPLIT_NO_EMPTY);
                 $value = array_map('trim', $value);
                 $value = array_map(array('Datasource', 'removeEscapedCommas'), $value);
             }
             // Handle date meta data #2003
             $handle = Symphony::Database()->cleanValue($handle);
             if (in_array($handle, array('system:creation-date', 'system:modification-date'))) {
                 $date_joins = '';
                 $date_where = '';
                 $date = new FieldDate();
                 $date->buildDSRetrievalSQL($value, $date_joins, $date_where, $filter_type == Datasource::FILTER_AND ? true : false);
                 // Replace the date field where with the `creation_date` or `modification_date`.
                 $date_where = preg_replace('/`t\\d+`.date/', $field_id !== 'system:modification-date' ? '`e`.creation_date_gmt' : '`e`.modification_date_gmt', $date_where);
                 $where .= $date_where;
             } else {
                 // Handle normal fields
                 $field_id = FieldManager::fetchFieldIDFromElementName($handle, $section->get('id'));
                 $field = FieldManager::fetch($field_id);
                 if ($field instanceof Field) {
                     $field->buildDSRetrievalSQL($value, $joins, $where, $filter_type == Datasource::FILTER_AND ? true : false);
                     $value = implode(',', $value);
                     $encoded_value = rawurlencode($value);
                     $filter_querystring .= sprintf("filter[%s]=%s&amp;", $handle, $encoded_value);
                     // Some fields require that prepopulation be done via ID. RE: #2331
                     if (!is_numeric($value) && method_exists($field, 'fetchIDfromValue')) {
                         $encoded_value = $field->fetchIDfromValue($value);
                     }
                     $prepopulate_querystring .= sprintf("prepopulate[%d]=%s&amp;", $field_id, $encoded_value);
                 } else {
                     unset($filters[$handle]);
                 }
             }
         }
         $filter_querystring = preg_replace("/&amp;\$/", '', $filter_querystring);
         $prepopulate_querystring = preg_replace("/&amp;\$/", '', $prepopulate_querystring);
     }
     Sortable::initialize($this, $entries, $sort, $order, array('current-section' => $section, 'filters' => $filter_querystring ? "&amp;" . $filter_querystring : '', 'unsort' => isset($_REQUEST['unsort'])));
     $this->Form->setAttribute('action', Administration::instance()->getCurrentPageURL() . '?pg=' . $current_page . ($filter_querystring ? "&amp;" . $filter_querystring : ''));
     // Build filtering interface
     $this->createFilteringInterface();
     $subheading_buttons = array(Widget::Anchor(__('Create New'), Administration::instance()->getCurrentPageURL() . 'new/' . ($prepopulate_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 (Symphony::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);
     /**
      * Allows adjustments to be made to the SQL where and joins statements
      * before they are used to fetch the entries for the page
      *
      * @delegate AdjustPublishFiltering
      * @since Symphony 2.3.3
      * @param string $context
      * '/publish/'
      * @param integer $section_id
      * An array of the current columns, passed by reference
      * @param string $where
      * The current where statement, or null if not set
      * @param string $joins
      */
     Symphony::ExtensionManager()->notifyMembers('AdjustPublishFiltering', '/publish/', array('section-id' => $section_id, 'where' => &$where, 'joins' => &$joins));
     // 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, true);
     } 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'));
     }
     // Flag filtering
     if (isset($_REQUEST['filter'])) {
         $filter_stats = new XMLElement('p', '<span>– ' . __('%d of %d entries (filtered)', array($entries['total-entries'], EntryManager::fetchCount($section_id))) . '</span>', array('class' => 'inactive'));
     } else {
         $filter_stats = new XMLElement('p', '<span>– ' . __('%d entries', array($entries['total-entries'])) . '</span>', array('class' => 'inactive'));
     }
     $this->Breadcrumbs->appendChild($filter_stats);
     // Build table
     $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 ? "&amp;" . $filter_querystring : '');
     $child_sections = array();
     $associated_sections = $section->fetchChildAssociations(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 table columns for each entry. 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 = array_reverse($visible_columns);
         $link_column = end($link_column);
         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('', Administration::instance()->getCurrentPageURL() . 'edit/' . $entry->get('id') . '/' . ($filter_querystring ? '?' . $prepopulate_querystring : ''), $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 &rarr;', 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 Entry $entry_id
              *  The entry object, please note that this is by error and this will
              *  be removed in Symphony 2.4. The entry object is available in
              *  the 'entry' key as of Symphony 2.3.1.
              * @param Entry $entry
              *  The entry object for this row
              */
             Symphony::ExtensionManager()->notifyMembers('AddCustomPublishColumnData', '/publish/', array('tableData' => &$tableData, 'section_id' => $section->get('id'), 'entry_id' => $entry, 'entry' => $entry));
             $tableData[count($tableData) - 1]->appendChild(Widget::Label(__('Select Entry %d', array($entry->get('id'))), null, 'accessible', null, array('for' => 'entry-' . $entry->get('id'))));
             $tableData[count($tableData) - 1]->appendChild(Widget::Input('items[' . $entry->get('id') . ']', null, 'checkbox', array('id' => 'entry-' . $entry->get('id'))));
             // 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', null, array('role' => 'directory', 'aria-labelledby' => 'symphony-subheading', 'data-interactive' => 'data-interactive'));
     $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) {
             $toggle_states = $field->getToggleStates();
             if (is_array($toggle_states)) {
                 $options[$index] = array('label' => __('Set %s', array($field->get('label'))), 'options' => array());
                 foreach ($toggle_states as $value => $state) {
                     $options[$index]['options'][] = array('toggle-' . $field->get('id') . '-' . $value, false, $state);
                 }
             }
             $index++;
         }
     }
     /**
      * Allows an extension to modify the existing options for this page's
      * With Selected menu. If the `$options` parameter is an empty array,
      * the 'With Selected' menu will not be rendered.
      *
      * @delegate AddCustomActions
      * @since Symphony 2.3.2
      * @param string $context
      * '/publish/'
      * @param array $options
      *  An array of arrays, where each child array represents an option
      *  in the With Selected menu. Options should follow the same format
      *  expected by `Widget::__SelectBuildOption`. Passed by reference.
      */
     Symphony::ExtensionManager()->notifyMembers('AddCustomActions', '/publish/', array('options' => &$options));
     if (!empty($options)) {
         $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 ? "&amp;" . $filter_querystring : '')));
         } else {
             $li->setValue(__('First'));
         }
         $ul->appendChild($li);
         // Previous
         $li = new XMLElement('li');
         if ($current_page > 1) {
             $li->appendChild(Widget::Anchor(__('&larr; Previous'), Administration::instance()->getCurrentPageURL() . '?pg=' . ($current_page - 1) . ($filter_querystring ? "&amp;" . $filter_querystring : '')));
         } else {
             $li->setValue(__('&larr; Previous'));
         }
         $ul->appendChild($li);
         // Summary
         $li = new XMLElement('li');
         $li->setAttribute('title', __('Viewing %1$s - %2$s of %3$s entries', array($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 &rarr;'), Administration::instance()->getCurrentPageURL() . '?pg=' . ($current_page + 1) . ($filter_querystring ? "&amp;" . $filter_querystring : '')));
         } else {
             $li->setValue(__('Next &rarr;'));
         }
         $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 ? "&amp;" . $filter_querystring : '')));
         } else {
             $li->setValue(__('Last'));
         }
         $ul->appendChild($li);
         $this->Contents->appendChild($ul);
     }
 }
Пример #6
0
 public function __viewIndex()
 {
     $this->setPageType('table');
     $this->setTitle(__('%1$s &ndash; %2$s', array(__('Authors'), __('Symphony'))));
     if (Symphony::Author()->isDeveloper() || Symphony::Author()->isManager()) {
         $this->appendSubheading(__('Authors'), Widget::Anchor(__('Create New'), Administration::instance()->getCurrentPageURL() . 'new/', __('Create a new author'), 'create button', null, array('accesskey' => 'c')));
     } else {
         $this->appendSubheading(__('Authors'));
     }
     Sortable::initialize($this, $authors, $sort, $order);
     $columns = array(array('label' => __('Name'), 'sortable' => true, 'handle' => 'name'), array('label' => __('Email Address'), 'sortable' => true, 'handle' => 'email'), array('label' => __('Last Seen'), 'sortable' => true, 'handle' => 'last_seen'));
     if (Symphony::Author()->isDeveloper() || Symphony::Author()->isManager()) {
         $columns = array_merge($columns, array(array('label' => __('User Type'), 'sortable' => true, 'handle' => 'user_type'), array('label' => __('Language'), 'sortable' => true, 'handle' => 'language')));
     }
     $aTableHead = Sortable::buildTableHeaders($columns, $sort, $order, isset($_REQUEST['filter']) ? '&amp;filter=' . $_REQUEST['filter'] : '');
     $aTableBody = array();
     if (!is_array($authors) || empty($authors)) {
         $aTableBody = array(Widget::TableRow(array(Widget::TableData(__('None found.'), 'inactive', null, count($aTableHead))), 'odd'));
     } else {
         foreach ($authors as $a) {
             // Setup each cell
             if (Symphony::Author()->isDeveloper() || Symphony::Author()->isManager() && !$a->isDeveloper() || Symphony::Author()->get('id') == $a->get('id')) {
                 $td1 = Widget::TableData(Widget::Anchor($a->getFullName(), Administration::instance()->getCurrentPageURL() . 'edit/' . $a->get('id') . '/', $a->get('username'), 'author'));
             } else {
                 $td1 = Widget::TableData($a->getFullName(), 'inactive');
             }
             // Can this Author be edited by the current Author?
             if (Symphony::Author()->isDeveloper() || Symphony::Author()->isManager()) {
                 if ($a->get('id') != Symphony::Author()->get('id')) {
                     $td1->appendChild(Widget::Label(__('Select Author %s', array($a->getFullName())), null, 'accessible', null, array('for' => 'author-' . $a->get('id'))));
                     $td1->appendChild(Widget::Input('items[' . $a->get('id') . ']', 'on', 'checkbox', array('id' => 'author-' . $a->get('id'))));
                 }
             }
             $td2 = Widget::TableData(Widget::Anchor($a->get('email'), 'mailto:' . $a->get('email'), __('Email this author')));
             if (!is_null($a->get('last_seen'))) {
                 $td3 = Widget::TableData(DateTimeObj::format($a->get('last_seen'), __SYM_DATETIME_FORMAT__));
             } else {
                 $td3 = Widget::TableData(__('Unknown'), 'inactive');
             }
             if ($a->isDeveloper()) {
                 $type = 'Developer';
             } elseif ($a->isManager()) {
                 $type = 'Manager';
             } else {
                 $type = 'Author';
             }
             $td4 = Widget::TableData(__($type));
             $languages = Lang::getAvailableLanguages();
             $td5 = Widget::TableData($a->get("language") == null ? __("System Default") : $languages[$a->get("language")]);
             // Add a row to the body array, assigning each cell to the row
             if (Symphony::Author()->isDeveloper() || Symphony::Author()->isManager()) {
                 $aTableBody[] = Widget::TableRow(array($td1, $td2, $td3, $td4, $td5));
             } else {
                 $aTableBody[] = Widget::TableRow(array($td1, $td2, $td3));
             }
         }
     }
     $table = Widget::Table(Widget::TableHead($aTableHead), null, Widget::TableBody($aTableBody), 'selectable', null, array('role' => 'directory', 'aria-labelledby' => 'symphony-subheading'));
     $this->Form->appendChild($table);
     $version = new XMLElement('p', 'Symphony ' . Symphony::Configuration()->get('version', 'symphony'), array('id' => 'version'));
     $this->Form->appendChild($version);
 }
 public function __viewIndex()
 {
     $this->setPageType('table');
     $this->setTitle(__('%1$s &ndash; %2$s', array(__('Extensions'), __('Symphony'))));
     $this->appendSubheading(__('Extensions'));
     $this->Form->setAttribute('action', SYMPHONY_URL . '/system/extensions/');
     Sortable::initialize($this, $extensions, $sort, $order);
     $columns = array(array('label' => __('Name'), 'sortable' => true, 'handle' => 'name'), array('label' => __('Version'), 'sortable' => false), array('label' => __('Status'), 'sortable' => false), array('label' => __('Links'), 'sortable' => false, 'handle' => 'links'), array('label' => __('Authors'), 'sortable' => true, 'handle' => 'author'));
     $aTableHead = Sortable::buildTableHeaders($columns, $sort, $order, isset($_REQUEST['filter']) ? '&amp;filter=' . $_REQUEST['filter'] : '');
     $aTableBody = array();
     if (!is_array($extensions) || empty($extensions)) {
         $aTableBody = array(Widget::TableRow(array(Widget::TableData(__('None found.'), 'inactive', null, count($aTableHead))), 'odd'));
     } else {
         foreach ($extensions as $name => $about) {
             // Name
             $td1 = Widget::TableData($about['name']);
             $td1->appendChild(Widget::Label(__('Select %s Extension', array($about['name'])), null, 'accessible', null, array('for' => 'extension-' . $name)));
             $td1->appendChild(Widget::Input('items[' . $name . ']', 'on', 'checkbox', array('id' => 'extension-' . $name)));
             // Version
             $installed_version = Symphony::ExtensionManager()->fetchInstalledVersion($name);
             if (in_array(Extension::EXTENSION_NOT_INSTALLED, $about['status'])) {
                 $td2 = Widget::TableData($about['version']);
             } elseif (in_array(Extension::EXTENSION_REQUIRES_UPDATE, $about['status'])) {
                 $td2 = Widget::TableData($installed_version . '<i> → ' . $about['version'] . '</i>');
             } else {
                 $td2 = Widget::TableData($installed_version);
             }
             // Status
             $trClasses = array();
             $trStatus = '';
             $tdMessage = __('Status unavailable');
             if (in_array(Extension::EXTENSION_NOT_INSTALLED, $about['status'])) {
                 $tdMessage = __('Not installed');
                 $trClasses[] = 'inactive';
                 $trClasses[] = 'extension-can-install';
             }
             if (in_array(Extension::EXTENSION_DISABLED, $about['status'])) {
                 $tdMessage = __('Disabled');
                 $trStatus = 'status-notice';
             }
             if (in_array(Extension::EXTENSION_ENABLED, $about['status'])) {
                 $tdMessage = __('Enabled');
             }
             if (in_array(Extension::EXTENSION_REQUIRES_UPDATE, $about['status'])) {
                 $tdMessage = __('Update available');
                 $trClasses[] = 'extension-can-update';
                 $trStatus = 'status-ok';
             }
             if (in_array(Extension::EXTENSION_NOT_COMPATIBLE, $about['status'])) {
                 $tdMessage .= ', ' . __('requires Symphony %s', array($about['required_version']));
                 $trStatus = 'status-error';
             }
             $trClasses[] = $trStatus;
             $td3 = Widget::TableData($tdMessage);
             // Links
             $tdLinks = array();
             if ($about['github'] != '') {
                 $tdLinks['github'] = Widget::Anchor(__('GitHub'), General::validateURL($about['github']))->generate();
             }
             if ($about['discuss'] != '') {
                 $tdLinks['discuss'] = Widget::Anchor(__('Discuss'), General::validateURL($about['discuss']))->generate();
                 // Update links to point to our 'new' domain, RE: #1995
                 $tdLinks['discuss'] = str_replace('symphony-cms.com', 'getsymphony.com', $tdLinks['discuss']);
             }
             if ($about['homepage'] != '') {
                 $tdLinks['homepage'] = Widget::Anchor(__('Homepage'), General::validateURL($about['homepage']))->generate();
             }
             if ($about['wiki'] != '') {
                 $tdLinks['wiki'] = Widget::Anchor(__('Wiki'), General::validateURL($about['wiki']))->generate();
             }
             if ($about['issues'] != '') {
                 $tdLinks['issues'] = Widget::Anchor(__('Issues'), General::validateURL($about['issues']))->generate();
             }
             $td4 = Widget::TableData($tdLinks);
             // Authors
             $tdAuthors = array();
             if (!is_array($about['author'])) {
                 $about['author'] = array($about['author']);
             }
             foreach ($about['author'] as $author) {
                 if (isset($author['website'])) {
                     $tdAuthors[] = Widget::Anchor($author['name'], General::validateURL($author['website']))->generate();
                 } elseif (isset($author['github'])) {
                     $tdAuthors[] = Widget::Anchor($author['name'], General::validateURL('https://github.com/' . $author['github']))->generate();
                 } elseif (isset($author['email'])) {
                     $tdAuthors[] = Widget::Anchor($author['name'], 'mailto:' . $author['email'])->generate();
                 } else {
                     $tdAuthors[] = $author['name'];
                 }
             }
             $td5 = Widget::TableData($tdAuthors);
             // Create the table row
             $tr = Widget::TableRow(array($td1, $td2, $td3, $td4, $td5), implode(' ', $trClasses));
             // Add some attributes about the extension
             $tr->setAttribute('data-handle', $name);
             $tr->setAttribute('data-installed-version', $installed_version);
             $tr->setAttribute('data-meta-version', $about['version']);
             // Add a row to the body array, assigning each cell to the row
             $aTableBody[] = $tr;
         }
     }
     $table = Widget::Table(Widget::TableHead($aTableHead), null, Widget::TableBody($aTableBody), 'selectable', null, array('role' => 'directory', 'aria-labelledby' => 'symphony-subheading', 'data-interactive' => 'data-interactive'));
     $this->Form->appendChild($table);
     $version = new XMLElement('p', 'Symphony ' . Symphony::Configuration()->get('version', 'symphony'), array('id' => 'version'));
     $this->Form->appendChild($version);
     $tableActions = new XMLElement('div');
     $tableActions->setAttribute('class', 'actions');
     $options = array(array(null, false, __('With Selected...')), array('enable', false, __('Enable')), array('disable', false, __('Disable')), array('uninstall', false, __('Uninstall'), 'confirm', null, array('data-message' => __('Are you sure you want to uninstall the selected extensions?'))));
     /**
      * Allows an extension to modify the existing options for this page's
      * With Selected menu. If the `$options` parameter is an empty array,
      * the 'With Selected' menu will not be rendered.
      *
      * @delegate AddCustomActions
      * @since Symphony 2.3.2
      * @param string $context
      * '/system/extensions/'
      * @param array $options
      *  An array of arrays, where each child array represents an option
      *  in the With Selected menu. Options should follow the same format
      *  expected by `Widget::__SelectBuildOption`. Passed by reference.
      */
     Symphony::ExtensionManager()->notifyMembers('AddCustomActions', '/system/extensions/', array('options' => &$options));
     if (!empty($options)) {
         $tableActions->appendChild(Widget::Apply($options));
         $this->Form->appendChild($tableActions);
     }
 }
 /**
  * This function contains the minimal amount of logic for generating the
  * index table of a given `$resource_type`. The table has name, source, pages
  * release date and author columns. The values for these columns are determined
  * by the resource's `about()` method.
  *
  * As Datasources types can be installed using Providers, the Source column
  * can be overridden with a Datasource's `getSourceColumn` method (if it exists).
  *
  * @param integer $resource_type
  *  Either `RESOURCE_TYPE_EVENT` or `RESOURCE_TYPE_DATASOURCE`
  */
 public function __viewIndex($resource_type)
 {
     $manager = ResourceManager::getManagerFromType($resource_type);
     $this->setPageType('table');
     Sortable::initialize($this, $resources, $sort, $order, array('type' => $resource_type));
     $columns = array(array('label' => __('Name'), 'sortable' => true, 'handle' => 'name'), array('label' => __('Source'), 'sortable' => true, 'handle' => 'source'), array('label' => __('Pages'), 'sortable' => false), array('label' => __('Release Date'), 'sortable' => true, 'handle' => 'release-date'), array('label' => __('Author'), 'sortable' => true, 'handle' => 'author'));
     $aTableHead = Sortable::buildTableHeaders($columns, $sort, $order, isset($_REQUEST['filter']) ? '&amp;filter=' . $_REQUEST['filter'] : '');
     $aTableBody = array();
     if (!is_array($resources) || empty($resources)) {
         $aTableBody = array(Widget::TableRow(array(Widget::TableData(__('None found.'), 'inactive', NULL, count($aTableHead))), 'odd'));
     } else {
         foreach ($resources as $r) {
             // Resource name
             $action = isset($r['can_parse']) && $r['can_parse'] === true ? 'edit' : 'info';
             $name = Widget::TableData(Widget::Anchor($r['name'], SYMPHONY_URL . $_REQUEST['symphony-page'] . $action . '/' . $r['handle'] . '/', $r['handle']));
             // Resource type/source
             if (isset($r['source'], $r['source']['id'])) {
                 $section = Widget::TableData(Widget::Anchor($r['source']['name'], SYMPHONY_URL . '/blueprints/sections/edit/' . $r['source']['id'] . '/', $r['source']['handle']));
             } else {
                 if (isset($r['source']) && class_exists($r['source']['name']) && method_exists($r['source']['name'], 'getSourceColumn')) {
                     $class = call_user_func(array($manager, '__getClassName'), $r['handle']);
                     $section = Widget::TableData(call_user_func(array($class, 'getSourceColumn'), $r['handle']));
                 } else {
                     if (isset($r['source'], $r['source']['name'])) {
                         $section = Widget::TableData($r['source']['name']);
                     } else {
                         $section = Widget::TableData(__('Unknown'), 'inactive');
                     }
                 }
             }
             // Attached pages
             $pages = ResourceManager::getAttachedPages($resource_type, $r['handle']);
             $pagelinks = array();
             $i = 0;
             foreach ($pages as $p) {
                 ++$i;
                 $pagelinks[] = Widget::Anchor($p['title'], SYMPHONY_URL . '/blueprints/pages/edit/' . $p['id'] . '/')->generate() . (count($pages) > $i ? $i % 10 == 0 ? '<br />' : ', ' : '');
             }
             $pages = implode('', $pagelinks);
             if ($pages == '') {
                 $pagelinks = Widget::TableData(__('None'), 'inactive');
             } else {
                 $pagelinks = Widget::TableData($pages, 'pages');
             }
             // Release date
             $releasedate = Widget::TableData(Lang::localizeDate(DateTimeObj::format($r['release-date'], __SYM_DATETIME_FORMAT__)));
             // Authors
             $author = $r['author']['name'];
             if ($author) {
                 if (isset($r['author']['website'])) {
                     $author = Widget::Anchor($r['author']['name'], General::validateURL($r['author']['website']));
                 } else {
                     if (isset($r['author']['email'])) {
                         $author = Widget::Anchor($r['author']['name'], 'mailto:' . $r['author']['email']);
                     }
                 }
             }
             $author = Widget::TableData($author);
             $author->appendChild(Widget::Input('items[' . $r['handle'] . ']', null, 'checkbox'));
             $aTableBody[] = Widget::TableRow(array($name, $section, $pagelinks, $releasedate, $author));
         }
     }
     $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'));
     $pages = $this->pagesFlatView();
     $group_attach = array('label' => __('Attach to Page'), 'options' => array());
     $group_detach = array('label' => __('Detach from Page'), 'options' => array());
     $group_attach['options'][] = array('attach-all-pages', false, __('All'));
     $group_detach['options'][] = array('detach-all-pages', false, __('All'));
     foreach ($pages as $p) {
         $group_attach['options'][] = array('attach-to-page-' . $p['id'], false, $p['title']);
         $group_detach['options'][] = array('detach-from-page-' . $p['id'], false, $p['title']);
     }
     $options[] = $group_attach;
     $options[] = $group_detach;
     /**
      * Allows an extension to modify the existing options for this page's
      * With Selected menu. If the `$options` parameter is an empty array,
      * the 'With Selected' menu will not be rendered.
      *
      * @delegate AddCustomActions
      * @since Symphony 2.3.2
      * @param string $context
      * '/blueprints/datasources/' or '/blueprints/events/'
      * @param array $options
      *  An array of arrays, where each child array represents an option
      *  in the With Selected menu. Options should follow the same format
      *  expected by `Widget::__SelectBuildOption`. Passed by reference.
      */
     Symphony::ExtensionManager()->notifyMembers('AddCustomActions', $_REQUEST['symphony-page'], array('options' => &$options));
     if (!empty($options)) {
         $tableActions->appendChild(Widget::Apply($options));
         $this->Form->appendChild($tableActions);
     }
 }
 public function __viewIndex()
 {
     $this->setPageType('table');
     $this->setTitle(__('%1$s &ndash; %2$s', array(__('Authors'), __('Symphony'))));
     if (Administration::instance()->Author->isDeveloper()) {
         $this->appendSubheading(__('Authors'), Widget::Anchor(__('Create New'), Administration::instance()->getCurrentPageURL() . 'new/', __('Create a new author'), 'create button', NULL, array('accesskey' => 'c')));
     } else {
         $this->appendSubheading(__('Authors'));
     }
     Sortable::initialize($this, $authors, $sort, $order);
     $columns = array(array('label' => __('Name'), 'sortable' => true, 'handle' => 'name'), array('label' => __('Email Address'), 'sortable' => true, 'handle' => 'email'), array('label' => __('Last Seen'), 'sortable' => true, 'handle' => 'last_seen'));
     if (Administration::instance()->Author->isDeveloper()) {
         $columns = array_merge($columns, array(array('label' => __('User Type'), 'sortable' => true, 'handle' => 'user_type'), array('label' => __('Language'), 'sortable' => true, 'handle' => 'language')));
     }
     $aTableHead = Sortable::buildTableHeaders($columns, $sort, $order, isset($_REQUEST['filter']) ? '&amp;filter=' . $_REQUEST['filter'] : '');
     $aTableBody = array();
     if (!is_array($authors) || empty($authors)) {
         $aTableBody = array(Widget::TableRow(array(Widget::TableData(__('None found.'), 'inactive', NULL, count($aTableHead))), 'odd'));
     } else {
         foreach ($authors as $a) {
             // Setup each cell
             if (Administration::instance()->Author->isDeveloper() || Administration::instance()->Author->get('id') == $a->get('id')) {
                 $td1 = Widget::TableData(Widget::Anchor($a->getFullName(), Administration::instance()->getCurrentPageURL() . 'edit/' . $a->get('id') . '/', $a->get('username'), 'author'));
             } else {
                 $td1 = Widget::TableData($a->getFullName(), 'inactive');
             }
             $td2 = Widget::TableData(Widget::Anchor($a->get('email'), 'mailto:' . $a->get('email'), __('Email this author')));
             if (!is_null($a->get('last_seen'))) {
                 $td3 = Widget::TableData(DateTimeObj::format($a->get('last_seen'), __SYM_DATETIME_FORMAT__));
             } else {
                 $td3 = Widget::TableData(__('Unknown'), 'inactive');
             }
             $td4 = Widget::TableData($a->isDeveloper() ? __("Developer") : __("Author"));
             $languages = Lang::getAvailableLanguages();
             $td5 = Widget::TableData($a->get("language") == NULL ? __("System Default") : $languages[$a->get("language")]);
             if (Administration::instance()->Author->isDeveloper()) {
                 if ($a->get('id') != Administration::instance()->Author->get('id')) {
                     $td3->appendChild(Widget::Input('items[' . $a->get('id') . ']', NULL, 'checkbox'));
                 }
             }
             // Add a row to the body array, assigning each cell to the row
             if (Administration::instance()->Author->isDeveloper()) {
                 $aTableBody[] = Widget::TableRow(array($td1, $td2, $td3, $td4, $td5));
             } else {
                 $aTableBody[] = Widget::TableRow(array($td1, $td2, $td3));
             }
         }
     }
     $table = Widget::Table(Widget::TableHead($aTableHead), NULL, Widget::TableBody($aTableBody), 'selectable');
     $this->Form->appendChild($table);
     if (Administration::instance()->Author->isDeveloper()) {
         $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 authors?'))));
         /**
          * Allows an extension to modify the existing options for this page's
          * With Selected menu. If the `$options` parameter is an empty array,
          * the 'With Selected' menu will not be rendered.
          *
          * @delegate AddCustomActions
          * @since Symphony 2.3.2
          * @param string $context
          * '/system/authors/'
          * @param array $options
          *  An array of arrays, where each child array represents an option
          *  in the With Selected menu. Options should follow the same format
          *  expected by `Widget::__SelectBuildOption`. Passed by reference.
          */
         Symphony::ExtensionManager()->notifyMembers('AddCustomActions', '/system/authors/', array('options' => &$options));
         if (!empty($options)) {
             $tableActions->appendChild(Widget::Apply($options));
             $this->Form->appendChild($tableActions);
         }
     }
 }
Пример #10
0
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//	A S S U M P T I O N S
//
//  INSTRUCTION:
//  A file full of Result objects is what your solution will be generating.
//	A Result simply associates a Product with a list of matching Listing objects.
//	Assumption 1: the results file will ONLY contain products with at least 1 matching listing
//	Assumption 2: only unique listings will be matched to products.  IF there is a duplicate
//					listing entry in the listing data file, it will be ignored
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// 	Lets ensure that the script has enough time to run ..
//	you never know how many products / listings are going to be compared
set_time_limit(0);
// ------------------------------------------------------------
// ------------------------------------------------------------
//	R E Q U I R E S
require "Sortable.class.php";
// the main logic which reads, analyzes and write the challenge results
// these are all of the files needed.
// ------------------------------------------------------------
// ------------------------------------------------------------
//	C O N S T A N T S
define('OUTPUT_FILE', 'results.txt');
define('DUPLICATES_FILE', 'duplicateResults.txt');
define('LISTING_FILE', 'listings.txt');
define('PRODUCTS_FILE', 'products.txt');
// instantiate the class .. and run it
$sortable = new Sortable();
$sortable->run();
 /**
  * This function contains the minimal amount of logic for generating the
  * index table of a given `$resource_type`. The table has name, source, pages
  * release date and author columns. The values for these columns are determined
  * by the resource's `about()` method.
  *
  * As Datasources types can be installed using Providers, the Source column
  * can be overridden with a Datasource's `getSourceColumn` method (if it exists).
  *
  * @param integer $resource_type
  *  Either `RESOURCE_TYPE_EVENT` or `RESOURCE_TYPE_DATASOURCE`
  */
 public function __viewIndex($resource_type)
 {
     $manager = ResourceManager::getManagerFromType($resource_type);
     $this->setPageType('table');
     Sortable::initialize($this, $resources, $sort, $order, array('type' => $resource_type));
     $columns = array(array('label' => __('Name'), 'sortable' => true, 'handle' => 'name'), array('label' => __('Source'), 'sortable' => true, 'handle' => 'source'), array('label' => __('Pages'), 'sortable' => false), array('label' => __('Release Date'), 'sortable' => true, 'handle' => 'release-date'), array('label' => __('Author'), 'sortable' => true, 'handle' => 'author'));
     $aTableHead = Sortable::buildTableHeaders($columns, $sort, $order, isset($_REQUEST['filter']) ? '&amp;filter=' . $_REQUEST['filter'] : '');
     $aTableBody = array();
     if (!is_array($resources) || empty($resources)) {
         $aTableBody = array(Widget::TableRow(array(Widget::TableData(__('None found.'), 'inactive', NULL, count($aTableHead))), 'odd'));
     } else {
         foreach ($resources as $r) {
             // Resource name
             $action = $r['can_parse'] ? 'edit' : 'info';
             $name = Widget::TableData(Widget::Anchor($r['name'], SYMPHONY_URL . $_REQUEST['symphony-page'] . $action . '/' . $r['handle'] . '/', $r['handle']));
             // Resource type/source
             if (isset($r['source']['id'])) {
                 $section = Widget::TableData(Widget::Anchor($r['source']['name'], SYMPHONY_URL . '/blueprints/sections/edit/' . $r['source']['id'] . '/', $r['source']['handle']));
             } else {
                 if (class_exists($r['source']['name']) && method_exists($r['source']['name'], 'getSourceColumn')) {
                     $class = call_user_func(array($manager, '__getClassName'), $r['handle']);
                     $section = Widget::TableData(call_user_func(array($class, 'getSourceColumn'), $r['handle']));
                 } else {
                     if (isset($r['source']['name'])) {
                         $section = Widget::TableData($r['source']['name']);
                     } else {
                         $section = Widget::TableData(__('Unknown'), 'inactive');
                     }
                 }
             }
             // Attached pages
             $pages = ResourceManager::getAttachedPages($resource_type, $r['handle']);
             $pagelinks = array();
             $i = 0;
             foreach ($pages as $p) {
                 ++$i;
                 $pagelinks[] = Widget::Anchor($p['title'], SYMPHONY_URL . '/blueprints/pages/edit/' . $p['id'] . '/')->generate() . (count($pages) > $i ? $i % 10 == 0 ? '<br />' : ', ' : '');
             }
             $pages = implode('', $pagelinks);
             if ($pages == '') {
                 $pagelinks = Widget::TableData(__('None'), 'inactive');
             } else {
                 $pagelinks = Widget::TableData($pages, 'pages');
             }
             // Release date
             $releasedate = Widget::TableData(Lang::localizeDate(DateTimeObj::format($r['release-date'], __SYM_DATETIME_FORMAT__)));
             // Authors
             $author = $r['author']['name'];
             if (isset($r['author']['website'])) {
                 $author = Widget::Anchor($r['author']['name'], General::validateURL($r['author']['website']));
             } else {
                 if (isset($r['author']['email'])) {
                     $author = Widget::Anchor($r['author']['name'], 'mailto:' . $r['author']['email']);
                 }
             }
             $author = Widget::TableData($author);
             $author->appendChild(Widget::Input('items[' . $r['handle'] . ']', null, 'checkbox'));
             $aTableBody[] = Widget::TableRow(array($name, $section, $pagelinks, $releasedate, $author));
         }
     }
     $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'));
     $pages = $this->pagesFlatView();
     $group_attach = array('label' => __('Attach to Page'), 'options' => array());
     $group_detach = array('label' => __('Detach from Page'), 'options' => array());
     $group_attach['options'][] = array('attach-all-pages', false, __('All'));
     $group_detach['options'][] = array('detach-all-pages', false, __('All'));
     foreach ($pages as $p) {
         $group_attach['options'][] = array('attach-to-page-' . $p['id'], false, $p['title']);
         $group_detach['options'][] = array('detach-from-page-' . $p['id'], false, $p['title']);
     }
     $options[] = $group_attach;
     $options[] = $group_detach;
     $tableActions->appendChild(Widget::Apply($options));
     $this->Form->appendChild($tableActions);
 }
 public function __viewIndex()
 {
     $this->setPageType('table');
     $this->setTitle(__('%1$s &ndash; %2$s', array(__('Extensions'), __('Symphony'))));
     $this->appendSubheading(__('Extensions'));
     $this->Form->setAttribute('action', SYMPHONY_URL . '/system/extensions/');
     Sortable::initialize($this, $extensions, $sort, $order);
     $columns = array(array('label' => __('Name'), 'sortable' => true, 'handle' => 'name'), array('label' => __('Installed Version'), 'sortable' => false), array('label' => __('Enabled'), 'sortable' => false), array('label' => __('Authors'), 'sortable' => true, 'handle' => 'author'));
     $aTableHead = Sortable::buildTableHeaders($columns, $sort, $order, isset($_REQUEST['filter']) ? '&amp;filter=' . $_REQUEST['filter'] : '');
     $aTableBody = array();
     if (!is_array($extensions) || empty($extensions)) {
         $aTableBody = array(Widget::TableRow(array(Widget::TableData(__('None found.'), 'inactive', NULL, count($aTableHead))), 'odd'));
     } else {
         foreach ($extensions as $name => $about) {
             $td1 = Widget::TableData($about['name']);
             $installed_version = Symphony::ExtensionManager()->fetchInstalledVersion($name);
             $td2 = Widget::TableData(is_null($installed_version) ? __('Not Installed') : $installed_version);
             // If the extension is using the new `extension.meta.xml` format, check the
             // compatibility of the extension. This won't prevent a user from installing
             // it, but it will let them know that it requires a version of Symphony greater
             // then what they have.
             if (in_array(EXTENSION_NOT_INSTALLED, $about['status'])) {
                 $td3 = Widget::TableData(__('Enable to install %s', array($about['version'])));
             }
             if (in_array(EXTENSION_NOT_COMPATIBLE, $about['status'])) {
                 $td3 = Widget::TableData(__('Requires Symphony %s', array($about['required_version'])));
             }
             if (in_array(EXTENSION_ENABLED, $about['status'])) {
                 $td3 = Widget::TableData(__('Yes'));
             }
             if (in_array(EXTENSION_REQUIRES_UPDATE, $about['status'])) {
                 if (in_array(EXTENSION_NOT_COMPATIBLE, $about['status'])) {
                     $td3 = Widget::TableData(__('New version %1$s, Requires Symphony %2$s', array($about['version'], $about['required_version'])));
                 } else {
                     $td3 = Widget::TableData(__('Enable to update to %s', array($about['version'])));
                 }
             }
             if (in_array(EXTENSION_DISABLED, $about['status'])) {
                 $td3 = Widget::TableData(__('Disabled'));
             }
             $td4 = Widget::TableData(NULL);
             if (isset($about['author'][0]) && is_array($about['author'][0])) {
                 $authors = '';
                 foreach ($about['author'] as $i => $author) {
                     if (isset($author['website'])) {
                         $link = Widget::Anchor($author['name'], General::validateURL($author['website']));
                     } else {
                         if (isset($author['email'])) {
                             $link = Widget::Anchor($author['name'], 'mailto:' . $author['email']);
                         } else {
                             $link = $author['name'];
                         }
                     }
                     $authors .= ($link instanceof XMLElement ? $link->generate() : $link) . ($i != count($about['author']) - 1 ? ", " : "");
                 }
                 $td4->setValue($authors);
             } else {
                 if (isset($about['author']['website'])) {
                     $link = Widget::Anchor($about['author']['name'], General::validateURL($about['author']['website']));
                 } else {
                     if (isset($about['author']['email'])) {
                         $link = Widget::Anchor($about['author']['name'], 'mailto:' . $about['author']['email']);
                     } else {
                         $link = $about['author']['name'];
                     }
                 }
                 $td4->setValue($link instanceof XMLElement ? $link->generate() : $link);
             }
             $td4->appendChild(Widget::Input('items[' . $name . ']', 'on', 'checkbox'));
             // Add a row to the body array, assigning each cell to the row
             $aTableBody[] = Widget::TableRow(array($td1, $td2, $td3, $td4), in_array(EXTENSION_NOT_INSTALLED, $about['status']) ? 'inactive' : NULL);
         }
     }
     $table = Widget::Table(Widget::TableHead($aTableHead), NULL, Widget::TableBody($aTableBody), 'selectable');
     $this->Form->appendChild($table);
     $version = new XMLElement('p', 'Symphony ' . Symphony::Configuration()->get('version', 'symphony'), array('id' => 'version'));
     $this->Form->appendChild($version);
     $tableActions = new XMLElement('div');
     $tableActions->setAttribute('class', 'actions');
     $options = array(array(NULL, false, __('With Selected...')), array('enable', false, __('Enable/Install')), array('disable', false, __('Disable')), array('uninstall', false, __('Uninstall'), 'confirm', null, array('data-message' => __('Are you sure you want to uninstall the selected extensions?'))));
     /**
      * Allows an extension to modify the existing options for this page's
      * With Selected menu. If the `$options` parameter is an empty array,
      * the 'With Selected' menu will not be rendered.
      *
      * @delegate AddCustomActions
      * @since Symphony 2.3.2
      * @param string $context
      * '/system/extensions/'
      * @param array $options
      *  An array of arrays, where each child array represents an option
      *  in the With Selected menu. Options should follow the same format
      *  expected by `Widget::__SelectBuildOption`. Passed by reference.
      */
     Symphony::ExtensionManager()->notifyMembers('AddCustomActions', '/system/extensions/', array('options' => &$options));
     if (!empty($options)) {
         $tableActions->appendChild(Widget::Apply($options));
         $this->Form->appendChild($tableActions);
     }
 }