public function view()
 {
     $params = array('{$today}', '{$current-time}', '{$this-year}', '{$this-month}', '{$this-day}', '{$timezone}', '{$website-name}', '{$page-title}', '{$root}', '{$workspace}', '{$root-page}', '{$current-page}', '{$current-page-id}', '{$current-path}', '{$current-query-string}', '{$current-url}', '{$cookie-username}', '{$cookie-pass}', '{$page-types}', '{$upload-limit}');
     // Get page parameters
     $pages = PageManager::fetch(true, array('params'));
     foreach ($pages as $key => $pageparams) {
         if (empty($pageparams['params'])) {
             continue;
         }
         $pageparams = explode('/', $pageparams['params']);
         foreach ($pageparams as $pageparam) {
             $param = '{$' . $pageparam . '}';
             if (!in_array($param, $params)) {
                 $params[] = $param;
             }
         }
     }
     // Get Data Sources output parameters
     $datasources = DatasourceManager::listAll();
     foreach ($datasources as $datasource) {
         $current = DatasourceManager::create($datasource['handle'], array(), false);
         $prefix = '{$ds-' . Lang::createHandle($datasource['name']) . '.';
         $suffix = '}';
         // Get parameters
         if (is_array($current->dsParamPARAMOUTPUT)) {
             foreach ($current->dsParamPARAMOUTPUT as $id => $param) {
                 $params[] = $prefix . $param . $suffix;
             }
         }
     }
     sort($params);
     $this->_Result = json_encode($params);
 }
 public function __buildPageXML($page, $page_types, $qf)
 {
     $lang_code = FLang::getLangCode();
     $oPage = new XMLElement('page');
     $oPage->setAttribute('handle', $page['handle']);
     $oPage->setAttribute('id', $page['id']);
     // keep current first
     $oPage->appendChild(new XMLElement('item', General::sanitize($page['plh_t-' . $lang_code]), array('lang' => $lang_code, 'handle' => $page['plh_h-' . $lang_code])));
     // add others
     foreach (FLang::getLangs() as $lc) {
         if ($lang_code != $lc) {
             $oPage->appendChild(new XMLElement('item', General::sanitize($page['plh_t-' . $lc]), array('lang' => $lc, 'handle' => $page['plh_h-' . $lc])));
         }
     }
     if (in_array($page['id'], array_keys($page_types))) {
         $xTypes = new XMLElement('types');
         foreach ($page_types[$page['id']] as $type) {
             $xTypes->appendChild(new XMLElement('type', $type));
         }
         $oPage->appendChild($xTypes);
     }
     if ($page['children'] != '0') {
         if ($children = PageManager::fetch(false, array($qf . 'id, handle, title'), array(sprintf('`parent` = %d', $page['id'])))) {
             foreach ($children as $c) {
                 $oPage->appendChild($this->__buildPageXML($c, $page_types, $qf));
             }
         }
     }
     return $oPage;
 }
Esempio n. 3
0
 public function grab(&$param_pool = null)
 {
     $result = new XMLElement('plh-page');
     $langs = FLang::getLangs();
     $fields = array('id', 'handle', 'parent');
     foreach ($langs as $lc) {
         $fields[] = "`plh_t-{$lc}`";
         $fields[] = "`plh_h-{$lc}`";
     }
     $pages = array();
     foreach (PageManager::fetch(null, $fields) as $page) {
         $pages[$page['id']] = $page;
     }
     $this->appendPage($pages, $this->_env['param']['current-page-id'], $langs, $result);
     return $result;
 }
 private function __getPageParams()
 {
     $params = array();
     $pages = PageManager::fetch(true, array('params'));
     foreach ($pages as $key => $pageparams) {
         if (empty($pageparams['params'])) {
             continue;
         }
         $pageparams = explode('/', $pageparams['params']);
         foreach ($pageparams as $pageparam) {
             $param = sprintf($this->template, $pageparam);
             if (!in_array($param, $params)) {
                 $params[] = $param;
             }
         }
     }
     return $params;
 }
 public function __buildPageXML($page, $page_types)
 {
     $oPage = new XMLElement('page');
     $oPage->setAttribute('handle', $page['handle']);
     $oPage->setAttribute('id', $page['id']);
     $oPage->appendChild(new XMLElement('name', General::sanitize($page['title'])));
     if (in_array($page['id'], array_keys($page_types))) {
         $xTypes = new XMLElement('types');
         foreach ($page_types[$page['id']] as $type) {
             $xTypes->appendChild(new XMLElement('type', $type));
         }
         $oPage->appendChild($xTypes);
     }
     if ($page['children'] != '0') {
         if ($children = PageManager::fetch(false, array('id, handle, title'), array(sprintf('`parent` = %d', $page['id'])))) {
             foreach ($children as $c) {
                 $oPage->appendChild($this->__buildPageXML($c, $page_types));
             }
         }
     }
     return $oPage;
 }
 private function buildTree($parent = null, $indent = 0)
 {
     if ($parent == null) {
         $results = PageManager::fetch(true, array(), array('`parent` IS NULL'), '`sortorder` ASC');
     } else {
         $results = PageManager::fetch(true, array(), array('`parent` = ' . $parent), '`sortorder` ASC');
     }
     $tree = array();
     foreach ($results as $result) {
         // Check if the page should be shown:
         if (!in_array('ck_hide', $result['type'])) {
             $prefix = '';
             $info = array('handle' => $result['handle'], 'path' => $result['path']);
             if ($result['path'] == null) {
                 $info['url'] = '/' . $result['handle'] . '/';
                 $info['title'] = $result['title'];
             } else {
                 $info['url'] = '/' . $result['path'] . '/' . $result['handle'] . '/';
                 for ($i = 0; $i < $indent; $i++) {
                     $prefix .= ' ';
                     // Please note: this might look like an empty space (nbsp) but it's an em space (emsp).
                     // This was necessary because &nbsp; kept showing as plain text in the dropdown.
                 }
                 $info['title'] = $prefix . ' › ' . General::sanitize($result['title']);
             }
             $tree[] = $info;
             // Check if there are templates for this page:
             $tree = array_merge($tree, $this->checkTemplates($result['id'], $prefix . ' '));
             // also an emsp
             // Get the children:
             $children = $this->buildTree($result['id'], $indent + 1);
             // Join arrays:
             $tree = array_merge($tree, $children);
         }
     }
     return $tree;
 }
 /**
  * Append presets
  * @param $context
  */
 public function appendPresets($context)
 {
     Symphony::Engine()->Page->addScriptToHead(URL . '/extensions/ckeditor/assets/preferences.js', 4676);
     $wrapper = $context['wrapper'];
     $fieldset = new XMLElement('fieldset', '', array('class' => 'settings'));
     $fieldset->appendChild(new XMLElement('legend', __('CKEditor File Browser')));
     $sectionManager = new SectionManager($this);
     $sections = $sectionManager->fetch();
     // Check which sections are allowed:
     $data = Symphony::Configuration()->get('sections', 'ckeditor');
     $checkedSections = $data != false ? explode(',', $data) : array();
     // If there are no sections found:
     if ($sections) {
         $options = array();
         foreach ($sections as $section) {
             $options[] = array($section->get('id'), in_array($section->get('id'), $checkedSections), $section->get('name'));
         }
         $label = Widget::Label(__('Permitted sections for the file browser:'));
         $label->appendChild(Widget::Select('ckeditor_sections[]', $options, array('multiple' => 'multiple')));
         $fieldset->appendChild($label);
     }
     // Link templates for CKEditor:
     $sections = SectionManager::fetch();
     $dbpages = PageManager::fetch();
     $pages = array();
     // Filter out the ck_hide:
     foreach ($dbpages as $page) {
         $types = PageManager::fetchPageTypes($page['id']);
         if (!in_array('ck_hide', $types)) {
             $pages[] = $page;
         }
     }
     // Adjust page title:
     foreach ($pages as &$_page) {
         $p = $_page;
         $title = $_page['title'];
         while (!is_null($p['parent'])) {
             $p = PageManager::fetch(false, array(), array('id' => $p['parent']));
             $title = $p['title'] . ' : ' . $title;
         }
         $_page['title'] = $title;
     }
     // Sort the array:
     $titles = array();
     foreach ($pages as $key => $row) {
         $titles[$key] = strtolower($row['title']);
     }
     array_multisort($titles, SORT_ASC, $pages);
     $this->sections = array();
     foreach ($sections as $s) {
         $a = array('id' => $s->get('id'), 'name' => $s->get('name'), 'fields' => array());
         $fields = FieldManager::fetch(null, $s->get('id'));
         foreach ($fields as $field) {
             // For now, only allow fields of the type 'input' to be used as a handle:
             if ($field->get('type') == 'input') {
                 $a['fields'][] = array('id' => $field->get('id'), 'label' => $field->get('label'), 'element_name' => $field->get('element_name'));
             }
         }
         $this->sections[] = $a;
     }
     $fieldset->appendChild(new XMLElement('p', __('Link templates:'), array('class' => 'label')));
     $ol = new XMLElement('ol');
     $ol->setAttribute('class', 'ckeditor-duplicator');
     $templates = Symphony::Database()->fetch('SELECT * FROM `tbl_ckeditor_link_templates`;');
     if (!is_array($pages)) {
         $pages = array($pages);
     }
     foreach ($pages as $page) {
         foreach ($templates as $template) {
             if ($template['page_id'] != $page['id']) {
                 continue;
             }
             $duplicator = $this->__buildDuplicatorItem($page, $template);
             $ol->appendChild($duplicator);
         }
         $duplicator = $this->__buildDuplicatorItem($page, NULL);
         $ol->appendChild($duplicator);
     }
     $fieldset->appendChild($ol);
     // Plugin presets:
     $fieldset->appendChild(new XMLElement('p', __('Plugin presets:'), array('class' => 'label')));
     $ol = new XMLElement('ol');
     $ol->setAttribute('class', 'ckeditor-duplicator');
     // Create template:
     $template = new XMLElement('li', null, array('class' => 'template'));
     $template->appendChild(new XMLElement('header', '<h3>' . __('New Preset') . '</h3>'));
     $template->appendChild(Widget::Label(__('Name'), Widget::Input('ckeditor_presets[-1][name]')));
     $template->appendChild(Widget::Label(__('Toolbar'), Widget::Textarea('ckeditor_presets[-1][toolbar]', 5, 50)));
     $template->appendChild(Widget::Label(__('Plugins'), Widget::Textarea('ckeditor_presets[-1][plugins]', 5, 50)));
     $template->appendChild(Widget::Label(__('%s Enable resizing', array(Widget::Input('ckeditor_presets[-1][resize]', 'yes', 'checkbox')->generate()))));
     $template->appendChild(Widget::Label(__('%s Show outline blocks', array(Widget::Input('ckeditor_presets[-1][outline]', 'yes', 'checkbox')->generate()))));
     $ol->appendChild($template);
     // Append all the fields:
     $presets = Symphony::Database()->fetch('SELECT * FROM `tbl_ckeditor_presets');
     $index = 0;
     foreach ($presets as $preset) {
         $template = new XMLElement('li');
         $template->appendChild(new XMLElement('header', '<h3>' . $preset['name'] . '</h3>'));
         $template->appendChild(Widget::Label(__('Name'), Widget::Input('ckeditor_presets[' . $index . '][name]', $preset['name'])));
         $template->appendChild(Widget::Label(__('Toolbar'), Widget::Textarea('ckeditor_presets[' . $index . '][toolbar]', 5, 50, $preset['toolbar'])));
         $template->appendChild(Widget::Label(__('Plugins'), Widget::Textarea('ckeditor_presets[' . $index . '][plugins]', 5, 50, $preset['plugins'])));
         $template->appendChild(Widget::Label(__('%s Enable resizing', array(Widget::Input('ckeditor_presets[' . $index . '][resize]', '1', 'checkbox', $preset['resize'] == 1 ? array('checked' => 'checked') : null)->generate()))));
         $template->appendChild(Widget::Label(__('%s Show outline blocks', array(Widget::Input('ckeditor_presets[' . $index . '][outline]', '1', 'checkbox', $preset['outline'] == 1 ? array('checked' => 'checked') : null)->generate()))));
         $ol->appendChild($template);
         $index++;
     }
     $fieldset->appendChild($ol);
     // Styles:
     $fieldset->appendChild(new XMLElement('p', __('Styles: (one style per line: <code>h3.example { color: #f00; background: #0f0; }</code>) Class name is converted to name (h3.hello-world = Hello World).'), array('class' => 'label')));
     $textarea = Widget::Textarea('ckeditor[styles]', 5, 50, Symphony::Configuration()->get('styles', 'ckeditor'));
     $fieldset->appendChild($textarea);
     $wrapper->appendChild($fieldset);
 }
 public function __formAction()
 {
     $fields = $_POST['fields'];
     $this->_errors = array();
     $providers = Symphony::ExtensionManager()->getProvidersOf(iProvider::EVENT);
     $providerClass = null;
     if (trim($fields['name']) == '') {
         $this->_errors['name'] = __('This is a required field');
     }
     if (trim($fields['source']) == '') {
         $this->_errors['source'] = __('This is a required field');
     }
     $filters = isset($fields['filters']) ? $fields['filters'] : array();
     // See if a Provided Datasource is saved
     if (!empty($providers)) {
         foreach ($providers as $providerClass => $provider) {
             if ($fields['source'] == call_user_func(array($providerClass, 'getSource'))) {
                 call_user_func_array(array($providerClass, 'validate'), array(&$fields, &$this->_errors));
                 break;
             }
             unset($providerClass);
         }
     }
     $classname = Lang::createHandle($fields['name'], 255, '_', false, true, array('@^[^a-z\\d]+@i' => '', '/[^\\w-\\.]/i' => ''));
     $rootelement = str_replace('_', '-', $classname);
     $extends = 'SectionEvent';
     // Check to make sure the classname is not empty after handlisation.
     if (empty($classname) && !isset($this->_errors['name'])) {
         $this->_errors['name'] = __('Please ensure name contains at least one Latin-based character.', array($classname));
     }
     $file = EVENTS . '/event.' . $classname . '.php';
     $isDuplicate = false;
     $queueForDeletion = null;
     if ($this->_context[0] == 'new' && is_file($file)) {
         $isDuplicate = true;
     } elseif ($this->_context[0] == 'edit') {
         $existing_handle = $this->_context[1];
         if ($classname != $existing_handle && is_file($file)) {
             $isDuplicate = true;
         } elseif ($classname != $existing_handle) {
             $queueForDeletion = EVENTS . '/event.' . $existing_handle . '.php';
         }
     }
     // Duplicate
     if ($isDuplicate) {
         $this->_errors['name'] = __('An Event with the name %s already exists', array('<code>' . $classname . '</code>'));
     }
     if (empty($this->_errors)) {
         $multiple = in_array('expect-multiple', $filters);
         $elements = null;
         $placeholder = '<!-- GRAB -->';
         $source = $fields['source'];
         $params = array('rootelement' => $rootelement);
         $about = array('name' => $fields['name'], 'version' => 'Symphony ' . Symphony::Configuration()->get('version', 'symphony'), 'release date' => DateTimeObj::getGMT('c'), 'author name' => Symphony::Author()->getFullName(), 'author website' => URL, 'author email' => Symphony::Author()->get('email'));
         // If there is a provider, get their template
         if ($providerClass) {
             $eventShell = file_get_contents(call_user_func(array($providerClass, 'getTemplate')));
         } else {
             $eventShell = file_get_contents($this->getTemplate('blueprints.event'));
             $about['trigger condition'] = $rootelement;
         }
         $this->__injectAboutInformation($eventShell, $about);
         // Replace the name
         $eventShell = str_replace('<!-- CLASS NAME -->', $classname, $eventShell);
         // Build the templates
         if ($providerClass) {
             $eventShell = call_user_func(array($providerClass, 'prepare'), $fields, $params, $eventShell);
         } else {
             $this->__injectFilters($eventShell, $filters);
             // Add Documentation
             require_once CONTENT . '/content.ajaxeventdocumentation.php';
             $ajaxEventDoc = new contentAjaxEventDocumentation();
             $documentation = null;
             $doc_parts = array();
             // Add Documentation (Success/Failure)
             $ajaxEventDoc->addEntrySuccessDoc($doc_parts, $rootelement, $fields['source'], $filters);
             $ajaxEventDoc->addEntryFailureDoc($doc_parts, $rootelement, $fields['source'], $filters);
             // Filters
             $ajaxEventDoc->addDefaultFiltersDoc($doc_parts, $rootelement, $fields['source'], $filters);
             // Frontend Markup
             $ajaxEventDoc->addFrontendMarkupDoc($doc_parts, $rootelement, $fields['source'], $filters);
             $ajaxEventDoc->addSendMailFilterDoc($doc_parts, $rootelement, $fields['source'], $filters);
             /**
              * Allows adding documentation for new filters. A reference to the $documentation
              * array is provided, along with selected filters
              * @delegate AppendEventFilterDocumentation
              * @param string $context
              * '/blueprints/events/(edit|new|info)/'
              * @param array $selected
              *  An array of all the selected filters for this Event
              * @param array $documentation
              *  An array of all the documentation XMLElements, passed by reference
              */
             Symphony::ExtensionManager()->notifyMembers('AppendEventFilterDocumentation', '/blueprints/events/' . $rootelement . '/', array('selected' => $filters, 'documentation' => &$doc_parts));
             $documentation = join(PHP_EOL, array_map(create_function('$x', 'return rtrim($x->generate(true, 4));'), $doc_parts));
             $documentation = str_replace('\'', '\\\'', $documentation);
             $eventShell = str_replace('<!-- CLASS EXTENDS -->', $extends, $eventShell);
             $eventShell = str_replace('<!-- DOCUMENTATION -->', General::tabsToSpaces($documentation, 4), $eventShell);
         }
         $eventShell = str_replace('<!-- ROOT ELEMENT -->', $rootelement, $eventShell);
         $eventShell = str_replace('<!-- CLASS NAME -->', $classname, $eventShell);
         $eventShell = str_replace('<!-- SOURCE -->', $source, $eventShell);
         // Remove left over placeholders
         $eventShell = preg_replace(array('/<!--[\\w ]++-->/'), '', $eventShell);
         if ($this->_context[0] == 'new') {
             /**
              * Prior to creating an Event, the file path where it will be written to
              * is provided and well as the contents of that file.
              *
              * @delegate EventsPreCreate
              * @since Symphony 2.2
              * @param string $context
              * '/blueprints/events/'
              * @param string $file
              *  The path to the Event file
              * @param string $contents
              *  The contents for this Event as a string passed by reference
              * @param array $filters
              *  An array of the filters attached to this event
              */
             Symphony::ExtensionManager()->notifyMembers('EventPreCreate', '/blueprints/events/', array('file' => $file, 'contents' => &$eventShell, 'filters' => $filters));
         } else {
             /**
              * Prior to editing an Event, the file path where it will be written to
              * is provided and well as the contents of that file.
              *
              * @delegate EventPreEdit
              * @since Symphony 2.2
              * @param string $context
              * '/blueprints/events/'
              * @param string $file
              *  The path to the Event file
              * @param string $contents
              *  The contents for this Event as a string passed by reference
              * @param array $filters
              *  An array of the filters attached to this event
              */
             Symphony::ExtensionManager()->notifyMembers('EventPreEdit', '/blueprints/events/', array('file' => $file, 'contents' => &$eventShell, 'filters' => $filters));
         }
         // Write the file
         if (!is_writable(dirname($file)) || !($write = General::writeFile($file, $eventShell, Symphony::Configuration()->get('write_mode', 'file')))) {
             $this->pageAlert(__('Failed to write Event to disk.') . ' ' . __('Please check permissions on %s.', array('<code>/workspace/events</code>')), Alert::ERROR);
             // Write successful
         } else {
             if (function_exists('opcache_invalidate')) {
                 opcache_invalidate($file, true);
             }
             // Attach this event to pages
             $connections = $fields['connections'];
             ResourceManager::setPages(RESOURCE_TYPE_EVENT, is_null($existing_handle) ? $classname : $existing_handle, $connections);
             if ($queueForDeletion) {
                 General::deleteFile($queueForDeletion);
                 $pages = PageManager::fetch(false, array('events', 'id'), array("\n                        `events` REGEXP '[[:<:]]" . $existing_handle . "[[:>:]]'\n                    "));
                 if (is_array($pages) && !empty($pages)) {
                     foreach ($pages as $page) {
                         $page['events'] = preg_replace('/\\b' . $existing_handle . '\\b/i', $classname, $page['events']);
                         PageManager::edit($page['id'], $page);
                     }
                 }
             }
             if ($this->_context[0] == 'new') {
                 /**
                  * After creating the Event, the path to the Event file is provided
                  *
                  * @delegate EventPostCreate
                  * @since Symphony 2.2
                  * @param string $context
                  * '/blueprints/events/'
                  * @param string $file
                  *  The path to the Event file
                  */
                 Symphony::ExtensionManager()->notifyMembers('EventPostCreate', '/blueprints/events/', array('file' => $file));
             } else {
                 /**
                  * After editing the Event, the path to the Event file is provided
                  *
                  * @delegate EventPostEdit
                  * @since Symphony 2.2
                  * @param string $context
                  * '/blueprints/events/'
                  * @param string $file
                  *  The path to the Event file
                  * @param string $previous_file
                  *  The path of the previous Event file in the case where an Event may
                  *  have been renamed. To get the handle from this value, see
                  *  `EventManager::__getHandleFromFilename`
                  */
                 Symphony::ExtensionManager()->notifyMembers('EventPostEdit', '/blueprints/events/', array('file' => $file, 'previous_file' => $queueForDeletion ? $queueForDeletion : null));
             }
             redirect(SYMPHONY_URL . '/blueprints/events/edit/' . $classname . '/' . ($this->_context[0] == 'new' ? 'created' : 'saved') . '/');
         }
     }
 }
 /**
  * Given a resource type, a handle and a page, this function detaches
  * the given handle (which represents either a datasource or event) to that page.
  *
  * @param integer $type
  *  The resource type, either `RESOURCE_TYPE_EVENT` or `RESOURCE_TYPE_DS`
  * @param string $r_handle
  *  The handle of the resource.
  * @param integer $page_id
  *  The ID of the page.
  */
 public static function detach($type, $r_handle, $page_id)
 {
     $col = self::getColumnFromType($type);
     $pages = PageManager::fetch(false, array($col), array(sprintf('`id` = %d', $page_id)));
     if (is_array($pages) && count($pages) == 1) {
         $result = $pages[0][$col];
         $values = explode(',', $result);
         $idx = array_search($r_handle, $values, false);
         if ($idx !== false) {
             array_splice($values, $idx, 1);
             $result = implode(',', $values);
             return PageManager::edit($page_id, array($col => MySQL::cleanValue($result)));
         }
     }
     return false;
 }
Esempio n. 10
0
 /**
  * Append presets
  * @param $context
  */
 public function appendPresets($context)
 {
     Symphony::Engine()->Page->addScriptToHead(URL . '/extensions/ckeditor/assets/preferences.js', 4676);
     $wrapper = $context['wrapper'];
     $fieldset = new XMLElement('fieldset', '', array('class' => 'settings'));
     $fieldset->appendChild(new XMLElement('legend', __('CKEditor File Browser')));
     $sectionManager = new SectionManager($this);
     $sections = $sectionManager->fetch();
     // Check which sections are allowed:
     $data = Symphony::Configuration()->get('sections', 'ckeditor');
     $checkedSections = $data != false ? explode(',', $data) : array();
     // If there are no sections found:
     if ($sections) {
         $options = array();
         foreach ($sections as $section) {
             $options[] = array($section->get('id'), in_array($section->get('id'), $checkedSections), $section->get('name'));
         }
         $label = Widget::Label(__('Permitted sections for the file browser:'));
         $label->appendChild(Widget::Select('ckeditor_sections[]', $options, array('multiple' => 'multiple')));
         $fieldset->appendChild($label);
     }
     // Link templates for CKEditor:
     $sections = SectionManager::fetch();
     $dbpages = PageManager::fetch();
     $pages = array();
     // Filter out the ck_hide:
     foreach ($dbpages as $page) {
         $types = PageManager::fetchPageTypes($page['id']);
         if (!in_array('ck_hide', $types)) {
             $pages[] = $page;
         }
     }
     // Adjust page title:
     foreach ($pages as &$_page) {
         $p = $_page;
         $title = $_page['title'];
         while (!is_null($p['parent'])) {
             $p = PageManager::fetch(false, array(), array('id' => $p['parent']));
             $title = $p['title'] . ' : ' . $title;
         }
         $_page['title'] = $title;
     }
     // Sort the array:
     $titles = array();
     foreach ($pages as $key => $row) {
         $titles[$key] = strtolower($row['title']);
     }
     array_multisort($titles, SORT_ASC, $pages);
     $this->sections = array();
     foreach ($sections as $s) {
         $a = array('id' => $s->get('id'), 'name' => $s->get('name'), 'fields' => array());
         $fields = FieldManager::fetch(null, $s->get('id'));
         foreach ($fields as $field) {
             // For now, only allow fields of the type 'input' to be used as a handle:
             if ($field->get('type') == 'input') {
                 $a['fields'][] = array('id' => $field->get('id'), 'label' => $field->get('label'), 'element_name' => $field->get('element_name'));
             }
         }
         $this->sections[] = $a;
     }
     $fieldset->appendChild(new XMLElement('p', __('Link templates:'), array('class' => 'label')));
     $ol = new XMLElement('ol');
     $ol->setAttribute('class', 'ckeditor-duplicator');
     $templates = Symphony::Database()->fetch('SELECT * FROM `tbl_ckeditor_link_templates`;');
     if (!is_array($pages)) {
         $pages = array($pages);
     }
     foreach ($pages as $page) {
         foreach ($templates as $template) {
             if ($template['page_id'] != $page['id']) {
                 continue;
             }
             $duplicator = $this->__buildDuplicatorItem($page, $template);
             $ol->appendChild($duplicator);
         }
         $duplicator = $this->__buildDuplicatorItem($page, NULL);
         $ol->appendChild($duplicator);
     }
     $fieldset->appendChild($ol);
     $wrapper->appendChild($fieldset);
 }
 public function __formAction()
 {
     $fields = $_POST['fields'];
     $this->_errors = array();
     $providers = Symphony::ExtensionManager()->getProvidersOf(iProvider::DATASOURCE);
     $providerClass = null;
     if (trim($fields['name']) == '') {
         $this->_errors['name'] = __('This is a required field');
     }
     if ($fields['source'] == 'static_xml') {
         if (trim($fields['static_xml']) == '') {
             $this->_errors['static_xml'] = __('This is a required field');
         } else {
             $xml_errors = null;
             include_once TOOLKIT . '/class.xsltprocess.php';
             General::validateXML($fields['static_xml'], $xml_errors, false, new XsltProcess());
             if (!empty($xml_errors)) {
                 $this->_errors['static_xml'] = __('XML is invalid.');
             }
         }
     } elseif (is_numeric($fields['source'])) {
         if (strlen(trim($fields['max_records'])) == 0 || is_numeric($fields['max_records']) && $fields['max_records'] < 1) {
             if ($fields['paginate_results'] === 'yes') {
                 $this->_errors['max_records'] = __('A result limit must be set');
             }
         } elseif (!self::__isValidPageString($fields['max_records'])) {
             $this->_errors['max_records'] = __('Must be a valid number or parameter');
         }
         if (strlen(trim($fields['page_number'])) == 0 || is_numeric($fields['page_number']) && $fields['page_number'] < 1) {
             if ($fields['paginate_results'] === 'yes') {
                 $this->_errors['page_number'] = __('A page number must be set');
             }
         } elseif (!self::__isValidPageString($fields['page_number'])) {
             $this->_errors['page_number'] = __('Must be a valid number or parameter');
         }
         // See if a Provided Datasource is saved
     } elseif (!empty($providers)) {
         foreach ($providers as $providerClass => $provider) {
             if ($fields['source'] == call_user_func(array($providerClass, 'getSource'))) {
                 call_user_func_array(array($providerClass, 'validate'), array(&$fields, &$this->_errors));
                 break;
             }
             unset($providerClass);
         }
     }
     $classname = Lang::createHandle($fields['name'], 255, '_', false, true, array('@^[^a-z\\d]+@i' => '', '/[^\\w-\\.]/i' => ''));
     $rootelement = str_replace('_', '-', $classname);
     // Check to make sure the classname is not empty after handlisation.
     if (empty($classname) && !isset($this->_errors['name'])) {
         $this->_errors['name'] = __('Please ensure name contains at least one Latin-based character.', array($classname));
     }
     $file = DATASOURCES . '/data.' . $classname . '.php';
     $isDuplicate = false;
     $queueForDeletion = null;
     if ($this->_context[0] == 'new' && is_file($file)) {
         $isDuplicate = true;
     } elseif ($this->_context[0] == 'edit') {
         $existing_handle = $this->_context[1];
         if ($classname != $existing_handle && is_file($file)) {
             $isDuplicate = true;
         } elseif ($classname != $existing_handle) {
             $queueForDeletion = DATASOURCES . '/data.' . $existing_handle . '.php';
         }
     }
     // Duplicate
     if ($isDuplicate) {
         $this->_errors['name'] = __('A Data source with the name %s already exists', array('<code>' . $classname . '</code>'));
     }
     if (empty($this->_errors)) {
         $filters = array();
         $elements = null;
         $source = $fields['source'];
         $params = array('rootelement' => $rootelement);
         $about = array('name' => $fields['name'], 'version' => 'Symphony ' . Symphony::Configuration()->get('version', 'symphony'), 'release date' => DateTimeObj::getGMT('c'), 'author name' => Symphony::Author()->getFullName(), 'author website' => URL, 'author email' => Symphony::Author()->get('email'));
         // If there is a provider, get their template
         if ($providerClass) {
             $dsShell = file_get_contents(call_user_func(array($providerClass, 'getTemplate')));
         } else {
             $dsShell = file_get_contents($this->getTemplate('blueprints.datasource'));
         }
         // Author metadata
         self::injectAboutInformation($dsShell, $about);
         // Do dependencies, the template file must have <!-- CLASS NAME -->
         $dsShell = str_replace('<!-- CLASS NAME -->', $classname, $dsShell);
         // If there is a provider, let them do the prepartion work
         if ($providerClass) {
             $dsShell = call_user_func(array($providerClass, 'prepare'), $fields, $params, $dsShell);
         } else {
             switch ($source) {
                 case 'authors':
                     $extends = 'AuthorDatasource';
                     if (isset($fields['filter']['author'])) {
                         $filters = $fields['filter']['author'];
                     }
                     $elements = $fields['xml_elements'];
                     $params['order'] = $fields['order'];
                     $params['redirectonempty'] = $fields['redirect_on_empty'];
                     $params['redirectonforbidden'] = $fields['redirect_on_forbidden'];
                     $params['redirectonrequired'] = $fields['redirect_on_required'];
                     $params['requiredparam'] = trim($fields['required_url_param']);
                     $params['negateparam'] = trim($fields['negate_url_param']);
                     $params['paramoutput'] = $fields['param'];
                     $params['sort'] = $fields['sort'];
                     break;
                 case 'navigation':
                     $extends = 'NavigationDatasource';
                     if (isset($fields['filter']['navigation'])) {
                         $filters = $fields['filter']['navigation'];
                     }
                     $params['order'] = $fields['order'];
                     $params['redirectonempty'] = $fields['redirect_on_empty'];
                     $params['redirectonforbidden'] = $fields['redirect_on_forbidden'];
                     $params['redirectonrequired'] = $fields['redirect_on_required'];
                     $params['requiredparam'] = trim($fields['required_url_param']);
                     $params['negateparam'] = trim($fields['negate_url_param']);
                     break;
                 case 'static_xml':
                     $extends = 'StaticXMLDatasource';
                     $fields['static_xml'] = trim($fields['static_xml']);
                     if (preg_match('/^<\\?xml/i', $fields['static_xml']) == true) {
                         // Need to remove any XML declaration
                         $fields['static_xml'] = preg_replace('/^<\\?xml[^>]+>/i', null, $fields['static_xml']);
                     }
                     $params['static'] = sprintf('%s', trim($fields['static_xml']));
                     break;
                 default:
                     $extends = 'SectionDatasource';
                     $elements = $fields['xml_elements'];
                     if (is_array($fields['filter']) && !empty($fields['filter'])) {
                         $filters = array();
                         foreach ($fields['filter'] as $f) {
                             foreach ($f as $key => $val) {
                                 $filters[$key] = $val;
                             }
                         }
                     }
                     $params['order'] = $fields['order'];
                     $params['group'] = $fields['group'];
                     $params['paginateresults'] = $fields['paginate_results'];
                     $params['limit'] = $fields['max_records'];
                     $params['startpage'] = $fields['page_number'];
                     $params['redirectonempty'] = $fields['redirect_on_empty'];
                     $params['redirectonforbidden'] = $fields['redirect_on_forbidden'];
                     $params['redirectonrequired'] = $fields['redirect_on_required'];
                     $params['requiredparam'] = trim($fields['required_url_param']);
                     $params['negateparam'] = trim($fields['negate_url_param']);
                     $params['paramoutput'] = $fields['param'];
                     $params['sort'] = $fields['sort'];
                     $params['htmlencode'] = $fields['html_encode'];
                     $params['associatedentrycounts'] = $fields['associated_entry_counts'];
                     break;
             }
             $this->__injectVarList($dsShell, $params);
             $this->__injectIncludedElements($dsShell, $elements);
             self::injectFilters($dsShell, $filters);
             if (preg_match_all('@(\\$ds-[0-9a-z_\\.\\-]+)@i', $dsShell, $matches)) {
                 $dependencies = General::array_remove_duplicates($matches[1]);
                 $dsShell = str_replace('<!-- DS DEPENDENCY LIST -->', "'" . implode("', '", $dependencies) . "'", $dsShell);
             }
             $dsShell = str_replace('<!-- CLASS EXTENDS -->', $extends, $dsShell);
             $dsShell = str_replace('<!-- SOURCE -->', $source, $dsShell);
         }
         if ($this->_context[0] == 'new') {
             /**
              * Prior to creating the Datasource, the file path where it will be written to
              * is provided and well as the contents of that file.
              *
              * @delegate DatasourcePreCreate
              * @since Symphony 2.2
              * @param string $context
              * '/blueprints/datasources/'
              * @param string $file
              *  The path to the Datasource file
              * @param string $contents
              *  The contents for this Datasource as a string passed by reference
              * @param array $params
              *  An array of all the `$dsParam*` values
              * @param array $elements
              *  An array of all the elements included in this datasource
              * @param array $filters
              *  An associative array of all the filters for this datasource with the key
              *  being the `field_id` and the value the filter.
              * @param array $dependencies
              *  An array of dependencies that this datasource has
              */
             Symphony::ExtensionManager()->notifyMembers('DatasourcePreCreate', '/blueprints/datasources/', array('file' => $file, 'contents' => &$dsShell, 'params' => $params, 'elements' => $elements, 'filters' => $filters, 'dependencies' => $dependencies));
         } else {
             /**
              * Prior to editing a Datasource, the file path where it will be written to
              * is provided and well as the contents of that file.
              *
              * @delegate DatasourcePreEdit
              * @since Symphony 2.2
              * @param string $context
              * '/blueprints/datasources/'
              * @param string $file
              *  The path to the Datasource file
              * @param string $contents
              *  The contents for this Datasource as a string passed by reference
              * @param array $dependencies
              *  An array of dependencies that this datasource has
              * @param array $params
              *  An array of all the `$dsParam*` values
              * @param array $elements
              *  An array of all the elements included in this datasource
              * @param array $filters
              *  An associative array of all the filters for this datasource with the key
              *  being the `field_id` and the value the filter.
              */
             Symphony::ExtensionManager()->notifyMembers('DatasourcePreEdit', '/blueprints/datasources/', array('file' => $file, 'contents' => &$dsShell, 'dependencies' => $dependencies, 'params' => $params, 'elements' => $elements, 'filters' => $filters));
         }
         // Remove left over placeholders
         $dsShell = preg_replace(array('/<!--[\\w ]++-->/', '/(\\t+[\\r\\n]){2,}/', '/(\\r\\n){2,}/'), '$1', $dsShell);
         // Write the file
         if (!is_writable(dirname($file)) || !General::writeFile($file, $dsShell, Symphony::Configuration()->get('write_mode', 'file'), 'w', true)) {
             $this->pageAlert(__('Failed to write Data source to disk.') . ' ' . __('Please check permissions on %s.', array('<code>/workspace/data-sources</code>')), Alert::ERROR);
             // Write successful
         } else {
             if (function_exists('opcache_invalidate')) {
                 opcache_invalidate($file, true);
             }
             // Attach this datasources to pages
             $connections = $fields['connections'];
             ResourceManager::setPages(ResourceManager::RESOURCE_TYPE_DS, is_null($existing_handle) ? $classname : $existing_handle, $connections);
             // If the datasource has been updated and the name changed, then adjust all the existing pages that have the old datasource name
             if ($queueForDeletion) {
                 General::deleteFile($queueForDeletion);
                 // Update pages that use this DS
                 $pages = PageManager::fetch(false, array('data_sources', 'id'), array("\n                        `data_sources` REGEXP '[[:<:]]" . $existing_handle . "[[:>:]]'\n                    "));
                 if (is_array($pages) && !empty($pages)) {
                     foreach ($pages as $page) {
                         $page['data_sources'] = preg_replace('/\\b' . $existing_handle . '\\b/i', $classname, $page['data_sources']);
                         PageManager::edit($page['id'], $page);
                     }
                 }
             }
             if ($this->_context[0] == 'new') {
                 /**
                  * After creating the Datasource, the path to the Datasource file is provided
                  *
                  * @delegate DatasourcePostCreate
                  * @since Symphony 2.2
                  * @param string $context
                  * '/blueprints/datasources/'
                  * @param string $file
                  *  The path to the Datasource file
                  */
                 Symphony::ExtensionManager()->notifyMembers('DatasourcePostCreate', '/blueprints/datasources/', array('file' => $file));
             } else {
                 /**
                  * After editing the Datasource, the path to the Datasource file is provided
                  *
                  * @delegate DatasourcePostEdit
                  * @since Symphony 2.2
                  * @param string $context
                  * '/blueprints/datasources/'
                  * @param string $file
                  *  The path to the Datasource file
                  * @param string $previous_file
                  *  The path of the previous Datasource file in the case where a Datasource may
                  *  have been renamed. To get the handle from this value, see
                  *  `DatasourceManager::__getHandleFromFilename`
                  */
                 Symphony::ExtensionManager()->notifyMembers('DatasourcePostEdit', '/blueprints/datasources/', array('file' => $file, 'previous_file' => $queueForDeletion ? $queueForDeletion : null));
             }
             redirect(SYMPHONY_URL . '/blueprints/datasources/edit/' . $classname . '/' . ($this->_context[0] == 'new' ? 'created' : 'saved') . '/');
         }
     }
 }
 public function __actionEdit()
 {
     if ($this->_context[0] != 'new' && !($page_id = (int) $this->_context[1])) {
         redirect(SYMPHONY_URL . '/blueprints/pages/');
     }
     $parent_link_suffix = NULL;
     if (isset($_REQUEST['parent']) && is_numeric($_REQUEST['parent'])) {
         $parent_link_suffix = '?parent=' . $_REQUEST['parent'];
     }
     if (@array_key_exists('delete', $_POST['action'])) {
         $this->__actionDelete($page_id, SYMPHONY_URL . '/blueprints/pages/' . $parent_link_suffix);
     }
     if (@array_key_exists('save', $_POST['action'])) {
         $fields = $_POST['fields'];
         $this->_errors = array();
         $autogenerated_handle = false;
         if (!isset($fields['title']) || trim($fields['title']) == '') {
             $this->_errors['title'] = __('This is a required field');
         }
         if (trim($fields['type']) != '' && preg_match('/(index|404|403)/i', $fields['type'])) {
             $types = preg_split('/\\s*,\\s*/', strtolower($fields['type']), -1, PREG_SPLIT_NO_EMPTY);
             if (in_array('index', $types) && PageManager::hasPageTypeBeenUsed($page_id, 'index')) {
                 $this->_errors['type'] = __('An index type page already exists.');
             } elseif (in_array('404', $types) && PageManager::hasPageTypeBeenUsed($page_id, '404')) {
                 $this->_errors['type'] = __('A 404 type page already exists.');
             } elseif (in_array('403', $types) && PageManager::hasPageTypeBeenUsed($page_id, '403')) {
                 $this->_errors['type'] = __('A 403 type page already exists.');
             }
         }
         if (trim($fields['handle']) == '') {
             $fields['handle'] = $fields['title'];
             $autogenerated_handle = true;
         }
         $fields['handle'] = PageManager::createHandle($fields['handle']);
         if (empty($fields['handle']) && !isset($this->_errors['title'])) {
             $this->_errors['handle'] = __('Please ensure handle contains at least one Latin-based character.');
         }
         /**
          * Just after the Symphony validation has run, allows Developers
          * to run custom validation logic on a Page
          *
          * @delegate PagePostValidate
          * @since Symphony 2.2
          * @param string $context
          * '/blueprints/pages/'
          * @param array $fields
          *  The `$_POST['fields']` array. This should be read-only and not changed
          *  through this delegate.
          * @param array $errors
          *  An associative array of errors, with the key matching a key in the
          *  `$fields` array, and the value being the string of the error. `$errors`
          *  is passed by reference.
          */
         Symphony::ExtensionManager()->notifyMembers('PagePostValidate', '/blueprints/pages/', array('fields' => $fields, 'errors' => &$errors));
         if (empty($this->_errors)) {
             $autogenerated_handle = false;
             if ($fields['params']) {
                 $fields['params'] = trim(preg_replace('@\\/{2,}@', '/', $fields['params']), '/');
             }
             // Clean up type list
             $types = preg_split('/\\s*,\\s*/', $fields['type'], -1, PREG_SPLIT_NO_EMPTY);
             $types = @array_map('trim', $types);
             unset($fields['type']);
             $fields['parent'] = $fields['parent'] != __('None') ? $fields['parent'] : null;
             $fields['data_sources'] = is_array($fields['data_sources']) ? implode(',', $fields['data_sources']) : NULL;
             $fields['events'] = is_array($fields['events']) ? implode(',', $fields['events']) : NULL;
             $fields['path'] = null;
             if ($fields['parent']) {
                 $fields['path'] = PageManager::resolvePagePath((int) $fields['parent']);
             }
             // Check for duplicates:
             $current = PageManager::fetchPageByID($page_id);
             if (empty($current)) {
                 $fields['sortorder'] = PageManager::fetchNextSortOrder();
             }
             $where = array();
             if (!empty($current)) {
                 $where[] = "p.id != {$page_id}";
             }
             $where[] = "p.handle = '" . $fields['handle'] . "'";
             $where[] = is_null($fields['path']) ? "p.path IS NULL" : "p.path = '" . $fields['path'] . "'";
             $duplicate = PageManager::fetch(false, array('*'), $where);
             // If duplicate
             if (!empty($duplicate)) {
                 if ($autogenerated_handle) {
                     $this->_errors['title'] = __('A page with that title already exists');
                 } else {
                     $this->_errors['handle'] = __('A page with that handle already exists');
                 }
             } else {
                 // New page?
                 if (empty($current)) {
                     $file_created = PageManager::createPageFiles($fields['path'], $fields['handle']);
                 } else {
                     $file_created = PageManager::createPageFiles($fields['path'], $fields['handle'], $current['path'], $current['handle']);
                 }
                 // If the file wasn't created, it's usually permissions related
                 if (!$file_created) {
                     $redirect = null;
                     return $this->pageAlert(__('Page Template could not be written to disk.') . ' ' . __('Please check permissions on %s.', array('<code>/workspace/pages</code>')), Alert::ERROR);
                 }
                 // Insert the new data:
                 if (empty($current)) {
                     /**
                      * Just prior to creating a new Page record in `tbl_pages`, provided
                      * with the `$fields` associative array. Use with caution, as no
                      * duplicate page checks are run after this delegate has fired
                      *
                      * @delegate PagePreCreate
                      * @since Symphony 2.2
                      * @param string $context
                      * '/blueprints/pages/'
                      * @param array $fields
                      *  The `$_POST['fields']` array passed by reference
                      */
                     Symphony::ExtensionManager()->notifyMembers('PagePreCreate', '/blueprints/pages/', array('fields' => &$fields));
                     if (!($page_id = PageManager::add($fields))) {
                         $this->pageAlert(__('Unknown errors occurred while attempting to save.') . '<a href="' . SYMPHONY_URL . '/system/log/">' . __('Check your activity log') . '</a>.', Alert::ERROR);
                     } else {
                         /**
                          * Just after the creation of a new page in `tbl_pages`
                          *
                          * @delegate PagePostCreate
                          * @since Symphony 2.2
                          * @param string $context
                          * '/blueprints/pages/'
                          * @param integer $page_id
                          *  The ID of the newly created Page
                          * @param array $fields
                          *  An associative array of data that was just saved for this page
                          */
                         Symphony::ExtensionManager()->notifyMembers('PagePostCreate', '/blueprints/pages/', array('page_id' => $page_id, 'fields' => &$fields));
                         $redirect = "/blueprints/pages/edit/{$page_id}/created/{$parent_link_suffix}";
                     }
                 } else {
                     /**
                      * Just prior to updating a Page record in `tbl_pages`, provided
                      * with the `$fields` associative array. Use with caution, as no
                      * duplicate page checks are run after this delegate has fired
                      *
                      * @delegate PagePreEdit
                      * @since Symphony 2.2
                      * @param string $context
                      * '/blueprints/pages/'
                      * @param integer $page_id
                      *  The ID of the Page that is about to be updated
                      * @param array $fields
                      *  The `$_POST['fields']` array passed by reference
                      */
                     Symphony::ExtensionManager()->notifyMembers('PagePreEdit', '/blueprints/pages/', array('page_id' => $page_id, 'fields' => &$fields));
                     if (!PageManager::edit($page_id, $fields, true)) {
                         return $this->pageAlert(__('Unknown errors occurred while attempting to save.') . '<a href="' . SYMPHONY_URL . '/system/log/">' . __('Check your activity log') . '</a>.', Alert::ERROR);
                     } else {
                         /**
                          * Just after updating a page in `tbl_pages`
                          *
                          * @delegate PagePostEdit
                          * @since Symphony 2.2
                          * @param string $context
                          * '/blueprints/pages/'
                          * @param integer $page_id
                          *  The ID of the Page that was just updated
                          * @param array $fields
                          *  An associative array of data that was just saved for this page
                          */
                         Symphony::ExtensionManager()->notifyMembers('PagePostEdit', '/blueprints/pages/', array('page_id' => $page_id, 'fields' => $fields));
                         $redirect = "/blueprints/pages/edit/{$page_id}/saved/{$parent_link_suffix}";
                     }
                 }
             }
             // Only proceed if there was no errors saving/creating the page
             if (empty($this->_errors)) {
                 /**
                  * Just before the page's types are saved into `tbl_pages_types`.
                  * Use with caution as no further processing is done on the `$types`
                  * array to prevent duplicate `$types` from occurring (ie. two index
                  * page types). Your logic can use the PageManger::hasPageTypeBeenUsed
                  * function to perform this logic.
                  *
                  * @delegate PageTypePreCreate
                  * @since Symphony 2.2
                  * @see toolkit.PageManager#hasPageTypeBeenUsed
                  * @param string $context
                  * '/blueprints/pages/'
                  * @param integer $page_id
                  *  The ID of the Page that was just created or updated
                  * @param array $types
                  *  An associative array of the types for this page passed by reference.
                  */
                 Symphony::ExtensionManager()->notifyMembers('PageTypePreCreate', '/blueprints/pages/', array('page_id' => $page_id, 'types' => &$types));
                 // Assign page types:
                 PageManager::addPageTypesToPage($page_id, $types);
                 // Find and update children:
                 if ($this->_context[0] == 'edit') {
                     PageManager::editPageChildren($page_id, $fields['path'] . '/' . $fields['handle']);
                 }
                 if ($redirect) {
                     redirect(SYMPHONY_URL . $redirect);
                 }
             }
         }
         // If there was any errors, either with pre processing or because of a
         // duplicate page, return.
         if (is_array($this->_errors) && !empty($this->_errors)) {
             return $this->pageAlert(__('An error occurred while processing this form. See below for details.'), Alert::ERROR);
         }
     }
 }
    public function __formAction()
    {
        $fields = $_POST['fields'];
        $this->_errors = array();
        $providers = Symphony::ExtensionManager()->getProvidersOf(iProvider::EVENT);
        $providerClass = null;
        if (trim($fields['name']) == '') {
            $this->_errors['name'] = __('This is a required field');
        }
        if (trim($fields['source']) == '') {
            $this->_errors['source'] = __('This is a required field');
        }
        $filters = isset($fields['filters']) ? $fields['filters'] : array();
        // See if a Provided Datasource is saved
        if (!empty($providers)) {
            foreach ($providers as $providerClass => $provider) {
                if ($fields['source'] == call_user_func(array($providerClass, 'getSource'))) {
                    call_user_func_array(array($providerClass, 'validate'), array(&$fields, &$this->_errors));
                    break;
                }
                unset($providerClass);
            }
        }
        $classname = Lang::createHandle($fields['name'], 255, '_', false, true, array('@^[^a-z\\d]+@i' => '', '/[^\\w-\\.]/i' => ''));
        $rootelement = str_replace('_', '-', $classname);
        $extends = 'SectionEvent';
        // Check to make sure the classname is not empty after handlisation.
        if (empty($classname) && !isset($this->_errors['name'])) {
            $this->_errors['name'] = __('Please ensure name contains at least one Latin-based character.', array($classname));
        }
        $file = EVENTS . '/event.' . $classname . '.php';
        $isDuplicate = false;
        $queueForDeletion = NULL;
        if ($this->_context[0] == 'new' && is_file($file)) {
            $isDuplicate = true;
        } else {
            if ($this->_context[0] == 'edit') {
                $existing_handle = $this->_context[1];
                if ($classname != $existing_handle && is_file($file)) {
                    $isDuplicate = true;
                } else {
                    if ($classname != $existing_handle) {
                        $queueForDeletion = EVENTS . '/event.' . $existing_handle . '.php';
                    }
                }
            }
        }
        // Duplicate
        if ($isDuplicate) {
            $this->_errors['name'] = __('An Event with the name %s already exists', array('<code>' . $classname . '</code>'));
        }
        if (empty($this->_errors)) {
            $multiple = in_array('expect-multiple', $filters);
            $elements = NULL;
            $placeholder = '<!-- GRAB -->';
            $source = $fields['source'];
            $params = array('rootelement' => $rootelement);
            $about = array('name' => $fields['name'], 'version' => 'Symphony ' . Symphony::Configuration()->get('version', 'symphony'), 'release date' => DateTimeObj::getGMT('c'), 'author name' => Administration::instance()->Author->getFullName(), 'author website' => URL, 'author email' => Administration::instance()->Author->get('email'));
            // If there is a provider, get their template
            if ($providerClass) {
                $eventShell = file_get_contents(call_user_func(array($providerClass, 'getTemplate')));
            } else {
                $eventShell = file_get_contents($this->getTemplate('blueprints.event'));
                $about['trigger condition'] = $rootelement;
            }
            $this->__injectAboutInformation($eventShell, $about);
            // Replace the name
            $eventShell = str_replace('<!-- CLASS NAME -->', $classname, $eventShell);
            // Build the templates
            if ($providerClass) {
                $eventShell = call_user_func(array($providerClass, 'prepare'), $fields, $params, $eventShell);
            } else {
                $this->__injectFilters($eventShell, $filters);
                // Add Documentation
                $documentation = NULL;
                $documentation_parts = array();
                $documentation_parts[] = new XMLElement('h3', __('Success and Failure XML Examples'));
                $documentation_parts[] = new XMLElement('p', __('When saved successfully, the following XML will be returned:'));
                if ($multiple) {
                    $code = new XMLElement($rootelement);
                    $entry = new XMLElement('entry', NULL, array('index' => '0', 'result' => 'success', 'type' => 'create | edit'));
                    $entry->appendChild(new XMLElement('message', __('Entry [created | edited] successfully.')));
                    $code->appendChild($entry);
                } else {
                    $code = new XMLElement($rootelement, NULL, array('result' => 'success', 'type' => 'create | edit'));
                    $code->appendChild(new XMLElement('message', __('Entry [created | edited] successfully.')));
                }
                $documentation_parts[] = self::processDocumentationCode($code);
                $documentation_parts[] = new XMLElement('p', __('When an error occurs during saving, due to either missing or invalid fields, the following XML will be returned') . ($multiple ? ' (<strong> ' . __('Notice that it is possible to get mixtures of success and failure messages when using the ‘Allow Multiple’ option') . '</strong>)' : NULL) . ':');
                if ($multiple) {
                    $code = new XMLElement($rootelement);
                    $entry = new XMLElement('entry', NULL, array('index' => '0', 'result' => 'error'));
                    $entry->appendChild(new XMLElement('message', __('Entry encountered errors when saving.')));
                    $entry->appendChild(new XMLElement('field-name', NULL, array('type' => 'invalid | missing')));
                    $code->appendChild($entry);
                    $entry = new XMLElement('entry', NULL, array('index' => '1', 'result' => 'success', 'type' => 'create | edit'));
                    $entry->appendChild(new XMLElement('message', __('Entry [created | edited] successfully.')));
                    $code->appendChild($entry);
                } else {
                    $code = new XMLElement($rootelement, NULL, array('result' => 'error'));
                    $code->appendChild(new XMLElement('message', __('Entry encountered errors when saving.')));
                    $code->appendChild(new XMLElement('field-name', NULL, array('type' => 'invalid | missing')));
                }
                $code->setValue('...', false);
                $documentation_parts[] = self::processDocumentationCode($code);
                if (is_array($filters) && !empty($filters)) {
                    $documentation_parts[] = new XMLElement('p', __('The following is an example of what is returned if any options return an error:'));
                    $code = new XMLElement($rootelement, NULL, array('result' => 'error'));
                    $code->appendChild(new XMLElement('message', __('Entry encountered errors when saving.')));
                    $code->appendChild(new XMLElement('filter', NULL, array('name' => 'admin-only', 'status' => 'failed')));
                    $code->appendChild(new XMLElement('filter', __('Recipient not found'), array('name' => 'send-email', 'status' => 'failed')));
                    $code->setValue('...', false);
                    $documentation_parts[] = self::processDocumentationCode($code);
                }
                $documentation_parts[] = new XMLElement('h3', __('Example Front-end Form Markup'));
                $documentation_parts[] = new XMLElement('p', __('This is an example of the form markup you can use on your frontend:'));
                $container = new XMLElement('form', NULL, array('method' => 'post', 'action' => '', 'enctype' => 'multipart/form-data'));
                $container->appendChild(Widget::Input('MAX_FILE_SIZE', (string) min(ini_size_to_bytes(ini_get('upload_max_filesize')), Symphony::Configuration()->get('max_upload_size', 'admin')), 'hidden'));
                if (is_numeric($fields['source'])) {
                    $section = SectionManager::fetch($fields['source']);
                    if ($section instanceof Section) {
                        $section_fields = $section->fetchFields();
                        if (is_array($section_fields) && !empty($section_fields)) {
                            foreach ($section_fields as $f) {
                                if ($f->getExampleFormMarkup() instanceof XMLElement) {
                                    $container->appendChild($f->getExampleFormMarkup());
                                }
                            }
                        }
                    }
                }
                $container->appendChild(Widget::Input('action[' . $rootelement . ']', __('Submit'), 'submit'));
                $code = $container->generate(true);
                $documentation_parts[] = self::processDocumentationCode($multiple ? str_replace('fields[', 'fields[0][', $code) : $code);
                $documentation_parts[] = new XMLElement('p', __('To edit an existing entry, include the entry ID value of the entry in the form. This is best as a hidden field like so:'));
                $documentation_parts[] = self::processDocumentationCode(Widget::Input('id' . ($multiple ? '[0]' : NULL), '23', 'hidden'));
                $documentation_parts[] = new XMLElement('p', __('To redirect to a different location upon a successful save, include the redirect location in the form. This is best as a hidden field like so, where the value is the URL to redirect to:'));
                $documentation_parts[] = self::processDocumentationCode(Widget::Input('redirect', URL . '/success/', 'hidden'));
                if (in_array('send-email', $filters)) {
                    $documentation_parts[] = new XMLElement('h3', __('Send Notification Email'));
                    $documentation_parts[] = new XMLElement('p', __('Upon the event successfully saving the entry, this option takes input from the form and send an email to the desired recipient.') . ' <strong>' . __('It currently does not work with ‘Allow Multiple’') . '</strong>. ' . __('The following are the recognised fields:'));
                    $documentation_parts[] = self::processDocumentationCode('send-email[sender-email] // ' . __('Optional') . PHP_EOL . 'send-email[sender-name] // ' . __('Optional') . PHP_EOL . 'send-email[reply-to-email] // ' . __('Optional') . PHP_EOL . 'send-email[reply-to-name] // ' . __('Optional') . PHP_EOL . 'send-email[subject]' . PHP_EOL . 'send-email[body]' . PHP_EOL . 'send-email[recipient] // ' . __('list of comma-separated author usernames.'));
                    $documentation_parts[] = new XMLElement('p', __('All of these fields can be set dynamically using the exact field name of another field in the form as shown below in the example form:'));
                    $documentation_parts[] = self::processDocumentationCode('<form action="" method="post">
		<fieldset>
			<label>' . __('Name') . ' <input type="text" name="fields[author]" value="" /></label>
			<label>' . __('Email') . ' <input type="text" name="fields[email]" value="" /></label>
			<label>' . __('Message') . ' <textarea name="fields[message]" rows="5" cols="21"></textarea></label>
			<input name="send-email[sender-email]" value="fields[email]" type="hidden" />
			<input name="send-email[sender-name]" value="fields[author]" type="hidden" />
			<input name="send-email[reply-to-email]" value="fields[email]" type="hidden" />
			<input name="send-email[reply-to-name]" value="fields[author]" type="hidden" />
			<input name="send-email[subject]" value="You are being contacted" type="hidden" />
			<input name="send-email[body]" value="fields[message]" type="hidden" />
			<input name="send-email[recipient]" value="fred" type="hidden" />
			<input id="submit" type="submit" name="action[save-contact-form]" value="Send" />
		</fieldset>
	</form>');
                }
                /**
                 * Allows adding documentation for new filters. A reference to the $documentation
                 * array is provided, along with selected filters
                 * @delegate AppendEventFilterDocumentation
                 * @param string $context
                 * '/blueprints/events/(edit|new|info)/'
                 * @param array $selected
                 *  An array of all the selected filters for this Event
                 * @param array $documentation
                 *  An array of all the documentation XMLElements, passed by reference
                 */
                Symphony::ExtensionManager()->notifyMembers('AppendEventFilterDocumentation', '/blueprints/events/' . $this->_context[0] . '/', array('selected' => $filters, 'documentation' => &$documentation_parts));
                $documentation = join(PHP_EOL, array_map(create_function('$x', 'return rtrim($x->generate(true, 4));'), $documentation_parts));
                $documentation = str_replace('\'', '\\\'', $documentation);
                $eventShell = str_replace('<!-- CLASS EXTENDS -->', $extends, $eventShell);
                $eventShell = str_replace('<!-- DOCUMENTATION -->', General::tabsToSpaces($documentation, 2), $eventShell);
            }
            $eventShell = str_replace('<!-- ROOT ELEMENT -->', $rootelement, $eventShell);
            $eventShell = str_replace('<!-- CLASS NAME -->', $classname, $eventShell);
            $eventShell = str_replace('<!-- SOURCE -->', $source, $eventShell);
            // Remove left over placeholders
            $eventShell = preg_replace(array('/<!--[\\w ]++-->/'), '', $eventShell);
            if ($this->_context[0] == 'new') {
                /**
                 * Prior to creating an Event, the file path where it will be written to
                 * is provided and well as the contents of that file.
                 *
                 * @delegate EventsPreCreate
                 * @since Symphony 2.2
                 * @param string $context
                 * '/blueprints/events/'
                 * @param string $file
                 *  The path to the Event file
                 * @param string $contents
                 *  The contents for this Event as a string passed by reference
                 * @param array $filters
                 *  An array of the filters attached to this event
                 */
                Symphony::ExtensionManager()->notifyMembers('EventPreCreate', '/blueprints/events/', array('file' => $file, 'contents' => &$eventShell, 'filters' => $filters));
            } else {
                /**
                 * Prior to editing an Event, the file path where it will be written to
                 * is provided and well as the contents of that file.
                 *
                 * @delegate EventPreEdit
                 * @since Symphony 2.2
                 * @param string $context
                 * '/blueprints/events/'
                 * @param string $file
                 *  The path to the Event file
                 * @param string $contents
                 *  The contents for this Event as a string passed by reference
                 * @param array $filters
                 *  An array of the filters attached to this event
                 */
                Symphony::ExtensionManager()->notifyMembers('EventPreEdit', '/blueprints/events/', array('file' => $file, 'contents' => &$eventShell, 'filters' => $filters));
            }
            // Write the file
            if (!is_writable(dirname($file)) || !($write = General::writeFile($file, $eventShell, Symphony::Configuration()->get('write_mode', 'file')))) {
                $this->pageAlert(__('Failed to write Event to disk.') . ' ' . __('Please check permissions on %s.', array('<code>/workspace/events</code>')), Alert::ERROR);
            } else {
                if ($queueForDeletion) {
                    General::deleteFile($queueForDeletion);
                    $pages = PageManager::fetch(false, array('events', 'id'), array("\n\t\t\t\t\t\t\t`events` REGEXP '[[:<:]]" . $existing_handle . "[[:>:]]'\n\t\t\t\t\t\t"));
                    if (is_array($pages) && !empty($pages)) {
                        foreach ($pages as $page) {
                            $page['events'] = preg_replace('/\\b' . $existing_handle . '\\b/i', $classname, $page['events']);
                            PageManager::edit($page['id'], $page);
                        }
                    }
                }
                if ($this->_context[0] == 'new') {
                    /**
                     * After creating the Event, the path to the Event file is provided
                     *
                     * @delegate EventPostCreate
                     * @since Symphony 2.2
                     * @param string $context
                     * '/blueprints/events/'
                     * @param string $file
                     *  The path to the Event file
                     */
                    Symphony::ExtensionManager()->notifyMembers('EventPostCreate', '/blueprints/events/', array('file' => $file));
                } else {
                    /**
                     * After editing the Event, the path to the Event file is provided
                     *
                     * @delegate EventPostEdit
                     * @since Symphony 2.2
                     * @param string $context
                     * '/blueprints/events/'
                     * @param string $file
                     *  The path to the Event file
                     * @param string $previous_file
                     *  The path of the previous Event file in the case where an Event may
                     *  have been renamed. To get the handle from this value, see
                     *  `EventManager::__getHandleFromFilename`
                     */
                    Symphony::ExtensionManager()->notifyMembers('EventPostEdit', '/blueprints/events/', array('file' => $file, 'previous_file' => $queueForDeletion ? $queueForDeletion : null));
                }
                redirect(SYMPHONY_URL . '/blueprints/events/edit/' . $classname . '/' . ($this->_context[0] == 'new' ? 'created' : 'saved') . '/');
            }
        }
    }
 /**
  * Returns Pages that match the given `$types`. If no `$types` is provided
  * the function returns the result of `PageManager::fetch`.
  *
  * @param array $types
  *  An array of some of the available Page Types.
  * @param boolean $negate (optional)
  *  If true, the logic gets inversed to return Pages that don't match the given `$types`.
  * @return array|null
  *  An associative array of Page information with the key being the column
  *  name from `tbl_pages` and the value being the data. If multiple Pages
  *  are found, an array of Pages will be returned. If no Pages are found
  *  null is returned.
  */
 public static function fetchPageByTypes(array $types = array(), $andOperation = false, $negate = false)
 {
     if (empty($types)) {
         return PageManager::fetch();
     }
     $types = array_map(array('MySQL', 'cleanValue'), $types);
     // Build SQL parts depending on query parameters. There are four possibilities.
     // 1. Without negation and with OR filter
     if (!$andOperation && !$negate) {
         $join = "LEFT JOIN `tbl_pages_types` AS `pt` ON (p.id = pt.page_id)";
         $where = sprintf("\n\t\t\t\t\t\tAND `pt`.type IN ('%s')\n\t\t\t\t\t", implode("', '", $types));
     } elseif ($andOperation && !$negate) {
         $join = "";
         $where = "";
         foreach ($types as $index => $type) {
             $join .= " LEFT JOIN `tbl_pages_types` AS `pt_{$index}` ON (p.id = pt_{$index}.page_id)";
             $where .= " AND pt_{$index}.type = '" . $type . "'";
         }
     } elseif (!$andOperation && $negate) {
         $join = sprintf("\n\t\t\t\t\t\tLEFT JOIN `tbl_pages_types` AS `pt` ON (p.id = pt.page_id AND pt.type IN ('%s'))\n\t\t\t\t\t", implode("', '", $types));
         $where = "AND `pt`.type IS NULL";
     } elseif ($andOperation && $negate) {
         $join = "";
         $where = "AND (";
         foreach ($types as $index => $type) {
             $join .= sprintf("\n\t\t\t\t\t\t\tLEFT JOIN `tbl_pages_types` AS `pt_%s` ON (p.id = pt_%s.page_id AND pt_%s.type IN ('%s'))\n\t\t\t\t\t\t", $index, $index, $index, $type);
             $where .= ($index === 0 ? "" : " OR ") . "pt_{$index}.type IS NULL";
         }
         $where .= ")";
     }
     $pages = Symphony::Database()->fetch(sprintf("\n\t\t\t\t\tSELECT\n\t\t\t\t\t\t`p`.*\n\t\t\t\t\tFROM\n\t\t\t\t\t\t`tbl_pages` AS `p`\n\t\t\t\t\t%s\n\t\t\t\t\tWHERE 1\n\t\t\t\t\t\t%s\n\t\t\t\t", $join, $where));
     return count($pages) == 1 ? array_pop($pages) : $pages;
 }
 /**
  * This function will return the number of child pages for a given
  * `$page_id`. This is a recursive function and will return the absolute
  * count.
  *
  * @param integer $page_id
  *  The ID of the Page.
  * @return integer
  *  The number of child pages for the given `$page_id`
  */
 public static function getChildPagesCount($page_id = null)
 {
     if (is_null($page_id)) {
         return null;
     }
     $children = PageManager::fetch(false, array('id'), array(sprintf('parent = %d', $page_id)));
     $count = count($children);
     if ($count > 0) {
         foreach ($children as $c) {
             $count += self::getChildPagesCount($c['id']);
         }
     }
     return $count;
 }
 public function __formAction()
 {
     $fields = $_POST['fields'];
     $this->_errors = array();
     $providers = Symphony::ExtensionManager()->getProvidersOf('data-sources');
     $providerClass = null;
     if (trim($fields['name']) == '') {
         $this->_errors['name'] = __('This is a required field');
     }
     if ($fields['source'] == 'static_xml') {
         if (trim($fields['static_xml']) == '') {
             $this->_errors['static_xml'] = __('This is a required field');
         } else {
             $xml_errors = NULL;
             include_once TOOLKIT . '/class.xsltprocess.php';
             General::validateXML($fields['static_xml'], $xml_errors, false, new XsltProcess());
             if (!empty($xml_errors)) {
                 $this->_errors['static_xml'] = __('XML is invalid');
             }
         }
     } elseif ($fields['source'] == 'dynamic_xml') {
         if (trim($fields['dynamic_xml']['url']) == '') {
             $this->_errors['dynamic_xml']['url'] = __('This is a required field');
         }
         // Use the TIMEOUT that was specified by the user for a real world indication
         $timeout = isset($fields['dynamic_xml']['timeout']) ? (int) $fields['dynamic_xml']['timeout'] : 6;
         // If there is a parameter in the URL, we can't validate the existence of the URL
         // as we don't have the environment details of where this datasource is going
         // to be executed.
         if (!preg_match('@{([^}]+)}@i', $fields['dynamic_xml']['url'])) {
             $valid_url = self::__isValidURL($fields['dynamic_xml']['url'], $timeout, $error);
             if ($valid_url) {
                 $data = $valid_url['data'];
             } else {
                 $this->_errors['dynamic_xml']['url'] = $error;
             }
         }
         if (trim($fields['dynamic_xml']['xpath']) == '') {
             $this->_errors['dynamic_xml']['xpath'] = __('This is a required field');
         }
         if (!is_numeric($fields['dynamic_xml']['cache'])) {
             $this->_errors['dynamic_xml']['cache'] = __('Must be a valid number');
         } elseif ($fields['dynamic_xml']['cache'] < 1) {
             $this->_errors['dynamic_xml']['cache'] = __('Must be greater than zero');
         }
     } elseif (is_numeric($fields['source'])) {
         if (strlen(trim($fields['max_records'])) == 0 || is_numeric($fields['max_records']) && $fields['max_records'] < 1) {
             if (isset($fields['paginate_results'])) {
                 $this->_errors['max_records'] = __('A result limit must be set');
             }
         } else {
             if (!self::__isValidPageString($fields['max_records'])) {
                 $this->_errors['max_records'] = __('Must be a valid number or parameter');
             }
         }
         if (strlen(trim($fields['page_number'])) == 0 || is_numeric($fields['page_number']) && $fields['page_number'] < 1) {
             if (isset($fields['paginate_results'])) {
                 $this->_errors['page_number'] = __('A page number must be set');
             }
         } else {
             if (!self::__isValidPageString($fields['page_number'])) {
                 $this->_errors['page_number'] = __('Must be a valid number or parameter');
             }
         }
     } elseif (!empty($providers)) {
         foreach ($providers as $providerClass => $provider) {
             if ($fields['source'] == call_user_func(array($providerClass, 'getSource'))) {
                 call_user_func(array($providerClass, 'validate'), &$fields, &$this->_errors);
                 break;
             }
             unset($providerClass);
         }
     }
     $classname = Lang::createHandle($fields['name'], 255, '_', false, true, array('@^[^a-z\\d]+@i' => '', '/[^\\w-\\.]/i' => ''));
     $rootelement = str_replace('_', '-', $classname);
     // Check to make sure the classname is not empty after handlisation.
     if (empty($classname) && !isset($this->_errors['name'])) {
         $this->_errors['name'] = __('Please ensure name contains at least one Latin-based character.', array($classname));
     }
     $file = DATASOURCES . '/data.' . $classname . '.php';
     $isDuplicate = false;
     $queueForDeletion = NULL;
     if ($this->_context[0] == 'new' && is_file($file)) {
         $isDuplicate = true;
     } elseif ($this->_context[0] == 'edit') {
         $existing_handle = $this->_context[1];
         if ($classname != $existing_handle && is_file($file)) {
             $isDuplicate = true;
         } elseif ($classname != $existing_handle) {
             $queueForDeletion = DATASOURCES . '/data.' . $existing_handle . '.php';
         }
     }
     // Duplicate
     if ($isDuplicate) {
         $this->_errors['name'] = __('A Data source with the name %s already exists', array('<code>' . $classname . '</code>'));
     }
     if (empty($this->_errors)) {
         $filters = array();
         $elements = NULL;
         $placeholder = '<!-- GRAB -->';
         $source = $fields['source'];
         $params = array('rootelement' => $rootelement);
         $about = array('name' => $fields['name'], 'version' => 'Symphony ' . Symphony::Configuration()->get('version', 'symphony'), 'release date' => DateTimeObj::getGMT('c'), 'author name' => Administration::instance()->Author->getFullName(), 'author website' => URL, 'author email' => Administration::instance()->Author->get('email'));
         // If there is a provider, get their template
         if ($providerClass) {
             $dsShell = file_get_contents(call_user_func(array($providerClass, 'getTemplate')));
         } else {
             $dsShell = file_get_contents($this->getTemplate('blueprints.datasource'));
         }
         // Author metadata
         self::injectAboutInformation($dsShell, $about);
         // Do dependencies, the template file must have <!-- CLASS NAME -->
         // and <!-- DS DEPENDENCY LIST --> tokens
         $dsShell = str_replace('<!-- CLASS NAME -->', $classname, $dsShell);
         // If there is a provider, let them do the prepartion work
         if ($providerClass) {
             $dsShell = call_user_func(array($providerClass, 'prepare'), $fields, $params, $dsShell);
         } else {
             switch ($source) {
                 case 'authors':
                     $extends = 'AuthorDatasource';
                     if (isset($fields['filter']['author'])) {
                         $filters = $fields['filter']['author'];
                     }
                     $elements = $fields['xml_elements'];
                     $params['order'] = $fields['order'];
                     $params['redirectonempty'] = isset($fields['redirect_on_empty']) ? 'yes' : 'no';
                     $params['requiredparam'] = trim($fields['required_url_param']);
                     $params['paramoutput'] = $fields['param'];
                     $params['sort'] = $fields['sort'];
                     break;
                 case 'navigation':
                     $extends = 'NavigationDatasource';
                     if (isset($fields['filter']['navigation'])) {
                         $filters = $fields['filter']['navigation'];
                     }
                     $params['order'] = $fields['order'];
                     $params['redirectonempty'] = isset($fields['redirect_on_empty']) ? 'yes' : 'no';
                     $params['requiredparam'] = trim($fields['required_url_param']);
                     break;
                 case 'dynamic_xml':
                     $extends = 'DynamicXMLDatasource';
                     // Automatically detect namespaces
                     if (isset($data)) {
                         preg_match_all('/xmlns:([a-z][a-z-0-9\\-]*)="([^\\"]+)"/i', $data, $matches);
                         if (!is_array($fields['dynamic_xml']['namespace'])) {
                             $fields['dynamic_xml']['namespace'] = array();
                         }
                         if (isset($matches[2][0])) {
                             $detected_namespaces = array();
                             foreach ($fields['dynamic_xml']['namespace'] as $name => $uri) {
                                 $detected_namespaces[] = $name;
                                 $detected_namespaces[] = $uri;
                             }
                             foreach ($matches[2] as $index => $uri) {
                                 $name = $matches[1][$index];
                                 if (in_array($name, $detected_namespaces) or in_array($uri, $detected_namespaces)) {
                                     continue;
                                 }
                                 $detected_namespaces[] = $name;
                                 $detected_namespaces[] = $uri;
                                 $fields['dynamic_xml']['namespace'][] = array('name' => $name, 'uri' => $uri);
                             }
                         }
                     }
                     $filters = array();
                     if (is_array($fields['dynamic_xml']['namespace'])) {
                         foreach ($fields['dynamic_xml']['namespace'] as $index => $data) {
                             $filters[$data['name']] = $data['uri'];
                         }
                     }
                     $params['url'] = $fields['dynamic_xml']['url'];
                     $params['xpath'] = $fields['dynamic_xml']['xpath'];
                     $params['cache'] = $fields['dynamic_xml']['cache'];
                     $params['format'] = $fields['dynamic_xml']['format'];
                     $params['timeout'] = isset($fields['dynamic_xml']['timeout']) ? (int) $fields['dynamic_xml']['timeout'] : '6';
                     break;
                 case 'static_xml':
                     $extends = 'StaticXMLDatasource';
                     $fields['static_xml'] = trim($fields['static_xml']);
                     if (preg_match('/^<\\?xml/i', $fields['static_xml']) == true) {
                         // Need to remove any XML declaration
                         $fields['static_xml'] = preg_replace('/^<\\?xml[^>]+>/i', NULL, $fields['static_xml']);
                     }
                     $params['static'] = sprintf('%s', addslashes(trim($fields['static_xml'])));
                     break;
                 default:
                     $extends = 'SectionDatasource';
                     $elements = $fields['xml_elements'];
                     if (is_array($fields['filter']) && !empty($fields['filter'])) {
                         $filters = array();
                         foreach ($fields['filter'] as $f) {
                             foreach ($f as $key => $val) {
                                 $filters[$key] = $val;
                             }
                         }
                     }
                     $params['order'] = $fields['order'];
                     $params['group'] = $fields['group'];
                     $params['paginateresults'] = isset($fields['paginate_results']) ? 'yes' : 'no';
                     $params['limit'] = $fields['max_records'];
                     $params['startpage'] = $fields['page_number'];
                     $params['redirectonempty'] = isset($fields['redirect_on_empty']) ? 'yes' : 'no';
                     $params['requiredparam'] = trim($fields['required_url_param']);
                     $params['paramoutput'] = $fields['param'];
                     $params['sort'] = $fields['sort'];
                     $params['htmlencode'] = $fields['html_encode'];
                     $params['associatedentrycounts'] = $fields['associated_entry_counts'];
                     if ($params['associatedentrycounts'] == NULL) {
                         $params['associatedentrycounts'] = 'no';
                     }
                     break;
             }
             $this->__injectVarList($dsShell, $params);
             $this->__injectIncludedElements($dsShell, $elements);
             self::injectFilters($dsShell, $filters);
             if (preg_match_all('@(\\$ds-[0-9a-z_\\.\\-]+)@i', $dsShell, $matches)) {
                 $dependencies = General::array_remove_duplicates($matches[1]);
                 $dsShell = str_replace('<!-- DS DEPENDENCY LIST -->', "'" . implode("', '", $dependencies) . "'", $dsShell);
             }
             $dsShell = str_replace('<!-- CLASS EXTENDS -->', $extends, $dsShell);
             $dsShell = str_replace('<!-- SOURCE -->', $source, $dsShell);
         }
         if ($this->_context[0] == 'new') {
             /**
              * Prior to creating the Datasource, the file path where it will be written to
              * is provided and well as the contents of that file.
              *
              * @delegate DatasourcePreCreate
              * @since Symphony 2.2
              * @param string $context
              * '/blueprints/datasources/'
              * @param string $file
              *  The path to the Datasource file
              * @param string $contents
              *  The contents for this Datasource as a string passed by reference
              * @param array $params
              *  An array of all the `$dsParam*` values
              * @param array $elements
              *  An array of all the elements included in this datasource
              * @param array $filters
              *  An associative array of all the filters for this datasource with the key
              *  being the `field_id` and the value the filter.
              * @param array $dependencies
              *  An array of dependencies that this datasource has
              */
             Symphony::ExtensionManager()->notifyMembers('DatasourcePreCreate', '/blueprints/datasources/', array('file' => $file, 'contents' => &$dsShell, 'params' => $params, 'elements' => $elements, 'filters' => $filters, 'dependencies' => $dependencies));
         } else {
             /**
              * Prior to editing a Datasource, the file path where it will be written to
              * is provided and well as the contents of that file.
              *
              * @delegate DatasourcePreEdit
              * @since Symphony 2.2
              * @param string $context
              * '/blueprints/datasources/'
              * @param string $file
              *  The path to the Datasource file
              * @param string $contents
              *  The contents for this Datasource as a string passed by reference
              * @param array $dependencies
              *  An array of dependencies that this datasource has
              * @param array $params
              *  An array of all the `$dsParam*` values
              * @param array $elements
              *  An array of all the elements included in this datasource
              * @param array $filters
              *  An associative array of all the filters for this datasource with the key
              *  being the `field_id` and the value the filter.
              */
             Symphony::ExtensionManager()->notifyMembers('DatasourcePreEdit', '/blueprints/datasources/', array('file' => $file, 'contents' => &$dsShell, 'dependencies' => $dependencies, 'params' => $params, 'elements' => $elements, 'filters' => $filters));
         }
         // Remove left over placeholders
         $dsShell = preg_replace(array('/<!--[\\w ]++-->/', '/(\\r\\n){2,}/', '/(\\t+[\\r\\n]){2,}/'), '', $dsShell);
         // Write the file
         if (!is_writable(dirname($file)) || !($write = General::writeFile($file, $dsShell, Symphony::Configuration()->get('write_mode', 'file')))) {
             $this->pageAlert(__('Failed to write Data source to disk.') . ' ' . __('Please check permissions on %s.', array('<code>/workspace/data-sources</code>')), Alert::ERROR);
         } else {
             if ($queueForDeletion) {
                 General::deleteFile($queueForDeletion);
                 // Update pages that use this DS
                 $pages = PageManager::fetch(false, array('data_sources', 'id'), array("\n\t\t\t\t\t\t\t`data_sources` REGEXP '[[:<:]]" . $existing_handle . "[[:>:]]'\n\t\t\t\t\t\t"));
                 if (is_array($pages) && !empty($pages)) {
                     foreach ($pages as $page) {
                         $page['data_sources'] = preg_replace('/\\b' . $existing_handle . '\\b/i', $classname, $page['data_sources']);
                         PageManager::edit($page['id'], $page);
                     }
                 }
             }
             if ($this->_context[0] == 'new') {
                 /**
                  * After creating the Datasource, the path to the Datasource file is provided
                  *
                  * @delegate DatasourcePostCreate
                  * @since Symphony 2.2
                  * @param string $context
                  * '/blueprints/datasources/'
                  * @param string $file
                  *  The path to the Datasource file
                  */
                 Symphony::ExtensionManager()->notifyMembers('DatasourcePostCreate', '/blueprints/datasources/', array('file' => $file));
             } else {
                 /**
                  * After editing the Datasource, the path to the Datasource file is provided
                  *
                  * @delegate DatasourcePostEdit
                  * @since Symphony 2.2
                  * @param string $context
                  * '/blueprints/datasources/'
                  * @param string $file
                  *  The path to the Datasource file
                  */
                 Symphony::ExtensionManager()->notifyMembers('DatasourcePostEdit', '/blueprints/datasources/', array('file' => $file));
             }
             redirect(SYMPHONY_URL . '/blueprints/datasources/edit/' . $classname . '/' . ($this->_context[0] == 'new' ? 'created' : 'saved') . '/');
         }
     }
 }
Esempio n. 17
0
 public function __viewEdit()
 {
     $isNew = true;
     $time = Widget::Time();
     // Verify role exists
     if ($this->_context[0] == 'edit') {
         $isNew = false;
         if (!($role_id = $this->_context[1])) {
             redirect(extension_Members::baseURL() . 'roles/');
         }
         if (!($existing = RoleManager::fetch($role_id))) {
             throw new SymphonyErrorPage(__('The role you requested to edit does not exist.'), __('Role not found'));
         }
     }
     // Add in custom assets
     Administration::instance()->Page->addStylesheetToHead(URL . '/extensions/members/assets/members.roles.css', 'screen', 101);
     Administration::instance()->Page->addScriptToHead(URL . '/extensions/members/assets/members.roles.js', 104);
     // Append any Page Alerts from the form's
     if (isset($this->_context[2])) {
         switch ($this->_context[2]) {
             case 'saved':
                 $this->pageAlert(__('Role updated at %s.', array($time->generate())) . ' <a href="' . extension_members::baseURL() . 'roles/new/" accesskey="c">' . __('Create another?') . '</a> <a href="' . extension_members::baseURL() . 'roles/" accesskey="a">' . __('View all Roles') . '</a>', Alert::SUCCESS);
                 break;
             case 'created':
                 $this->pageAlert(__('Role created at %s.', array($time->generate())) . ' <a href="' . extension_members::baseURL() . 'roles/new/" accesskey="c">' . __('Create another?') . '</a> <a href="' . extension_members::baseURL() . 'roles/" accesskey="a">' . __('View all Roles') . '</a>', Alert::SUCCESS);
                 break;
         }
     }
     // Has the form got any errors?
     $formHasErrors = is_array($this->_errors) && !empty($this->_errors);
     if ($formHasErrors) {
         $this->pageAlert(__('An error occurred while processing this form. <a href="#error">See below for details.</a>'), Alert::ERROR);
     }
     $this->setPageType('form');
     if ($isNew) {
         $this->setTitle(__('Symphony &ndash; Member Roles'));
         $this->appendSubheading(__('Untitled'));
         $fields = array('name' => null, 'permissions' => null, 'page_access' => null);
     } else {
         $this->setTitle(__('Symphony &ndash; Member Roles &ndash; ') . $existing->get('name'));
         $this->appendSubheading($existing->get('name'));
         if (isset($_POST['fields'])) {
             $fields = $_POST['fields'];
         } else {
             $fields = array('name' => $existing->get('name'), 'permissions' => $existing->get('event_permissions'), 'page_access' => $existing->get('forbidden_pages'));
         }
     }
     $this->insertBreadcrumbs(array(Widget::Anchor(__('Member Roles'), extension_members::baseURL() . 'roles/')));
     $fieldset = new XMLElement('fieldset');
     $fieldset->setAttribute('class', 'settings type-file');
     $fieldset->appendChild(new XMLElement('legend', __('Essentials')));
     $label = Widget::Label(__('Name'));
     $label->appendChild(Widget::Input('fields[name]', General::sanitize($fields['name'])));
     if (isset($this->_errors['name'])) {
         $fieldset->appendChild(Widget::Error($label, $this->_errors['name']));
     } else {
         $fieldset->appendChild($label);
     }
     $this->Form->appendChild($fieldset);
     $events = EventManager::listAll();
     $fieldset = new XMLElement('fieldset');
     $fieldset->setAttribute('class', 'settings type-file');
     $fieldset->appendChild(new XMLElement('legend', __('Event Level Permissions')));
     $aTableBody = array();
     if (is_array($events) && !empty($events)) {
         foreach ($events as $event_handle => $event) {
             $permissions = $fields['permissions'][$event_handle];
             $td_name = Widget::TableData($event['name'], 'name');
             $td_permission_create = Widget::TableData(sprintf('<label title="%s">%s <span>%s</span></label>', __('User can create new entries'), Widget::Input("fields[permissions][{$event_handle}][create]", (string) EventPermissions::CREATE, 'checkbox', $permissions['create'] == EventPermissions::CREATE ? array('checked' => 'checked') : NULL)->generate(), 'Create'), 'create');
             $td_permission_none = Widget::TableData(sprintf('<label title="%s">%s <span>%s</span></label>', __('User cannot edit existing entries'), Widget::Input("fields[permissions][{$event_handle}][edit]", (string) EventPermissions::NO_PERMISSIONS, 'radio', $permissions['edit'] == EventPermissions::NO_PERMISSIONS ? array('checked' => 'checked') : NULL)->generate(), 'None'));
             $td_permission_own = Widget::TableData(sprintf('<label title="%s">%s <span>%s</span></label>', __('User can edit their own entries only'), Widget::Input("fields[permissions][{$event_handle}][edit]", (string) EventPermissions::OWN_ENTRIES, 'radio', $permissions['edit'] == EventPermissions::OWN_ENTRIES ? array('checked' => 'checked') : NULL)->generate(), 'Own'));
             $td_permission_all = Widget::TableData(sprintf('<label title="%s">%s <span>%s</span></label>', __('User can edit all entries'), Widget::Input("fields[permissions][{$event_handle}][edit]", (string) EventPermissions::ALL_ENTRIES, 'radio', $permissions['edit'] == EventPermissions::ALL_ENTRIES ? array('checked' => 'checked') : NULL)->generate(), 'All'));
             // Create an Event instance
             $ev = EventManager::create($event_handle, array());
             $aTableBody[] = Widget::TableRow(array($td_name, $td_permission_create, $td_permission_none, $td_permission_own, $td_permission_all), method_exists($ev, 'ignoreRolePermissions') && $ev->ignoreRolePermissions() == true ? 'inactive' : '');
             unset($ev);
         }
     }
     $thead = Widget::TableHead(array(array(__('Event'), 'col', array('class' => 'name')), array(__('Create New'), 'col', array('class' => 'new', 'title' => __('Toggle all'))), array(__('No Edit'), 'col', array('class' => 'edit', 'title' => __('Toggle all'))), array(__('Edit Own'), 'col', array('class' => 'edit', 'title' => __('Toggle all'))), array(__('Edit All'), 'col', array('class' => 'edit', 'title' => __('Toggle all')))));
     $table = Widget::Table($thead, NULL, Widget::TableBody($aTableBody), 'role-permissions');
     $fieldset->appendChild($table);
     $this->Form->appendChild($fieldset);
     // Add Page Permissions [simple Deny/Allow]
     $fieldset = new XMLElement('fieldset');
     $fieldset->setAttribute('class', 'settings type-file');
     $fieldset->appendChild(new XMLElement('legend', __('Page Level Permissions')));
     $label = Widget::Label(__('Deny Access'));
     if (!is_array($fields['page_access'])) {
         $fields['page_access'] = array();
     }
     $options = array();
     $pages = PageManager::fetch(false, array('id'));
     if (!empty($pages)) {
         foreach ($pages as $page) {
             $options[] = array($page['id'], in_array($page['id'], $fields['page_access']), '/' . PageManager::resolvePagePath($page['id']));
         }
     }
     $label->appendChild(Widget::Select('fields[page_access][]', $options, array('multiple' => 'multiple')));
     $fieldset->appendChild($label);
     $this->Form->appendChild($fieldset);
     $div = new XMLElement('div');
     $div->setAttribute('class', 'actions');
     $div->appendChild(Widget::Input('action[save]', __('Save Changes'), 'submit', array('accesskey' => 's')));
     if (!$isNew && $existing->get('id') != Role::PUBLIC_ROLE) {
         $button = new XMLElement('button', __('Delete'));
         $button->setAttributeArray(array('name' => 'action[delete]', 'class' => 'button confirm delete', 'title' => __('Delete this Role'), 'type' => 'submit', 'accesskey' => 'd'));
         $div->appendChild($button);
     }
     $this->Form->appendChild($div);
 }
 /**
  * This function is called from the resources index when a user uses the
  * With Selected, or Apply, menu. The type of resource is given by
  * `$resource_type`. At this time the only two valid values,
  * `RESOURCE_TYPE_EVENT` or `RESOURCE_TYPE_DATASOURCE`.
  *
  * The function handles 'delete', 'attach', 'detach', 'attach all',
  * 'detach all' actions.
  *
  * @param integer $resource_type
  *  Either `RESOURCE_TYPE_EVENT` or `RESOURCE_TYPE_DATASOURCE`
  */
 public function __actionIndex($resource_type)
 {
     $manager = ResourceManager::getManagerFromType($resource_type);
     if (isset($_POST['action']) && is_array($_POST['action'])) {
         $checked = $_POST['items'] ? @array_keys($_POST['items']) : NULL;
         if (is_array($checked) && !empty($checked)) {
             if ($_POST['with-selected'] == 'delete') {
                 $canProceed = true;
                 foreach ($checked as $handle) {
                     $path = call_user_func(array($manager, '__getDriverPath'), $handle);
                     if (!General::deleteFile($path)) {
                         $folder = str_replace(DOCROOT, '', $path);
                         $folder = str_replace('/' . basename($path), '', $folder);
                         $this->pageAlert(__('Failed to delete %s.', array('<code>' . basename($path) . '</code>')) . ' ' . __('Please check permissions on %s', array('<code>' . $folder . '</code>')), Alert::ERROR);
                         $canProceed = false;
                     }
                 }
                 if ($canProceed) {
                     redirect(Administration::instance()->getCurrentPageURL());
                 }
             } else {
                 if (preg_match('/^(at|de)?tach-(to|from)-page-/', $_POST['with-selected'])) {
                     if (substr($_POST['with-selected'], 0, 6) == 'detach') {
                         $page = str_replace('detach-from-page-', '', $_POST['with-selected']);
                         foreach ($checked as $handle) {
                             ResourceManager::detach($resource_type, $handle, $page);
                         }
                     } else {
                         $page = str_replace('attach-to-page-', '', $_POST['with-selected']);
                         foreach ($checked as $handle) {
                             ResourceManager::attach($resource_type, $handle, $page);
                         }
                     }
                     if ($canProceed) {
                         redirect(Administration::instance()->getCurrentPageURL());
                     }
                 } else {
                     if (preg_match('/^(at|de)?tach-all-pages$/', $_POST['with-selected'])) {
                         $pages = PageManager::fetch(false, array('id'));
                         if (substr($_POST['with-selected'], 0, 6) == 'detach') {
                             foreach ($checked as $handle) {
                                 foreach ($pages as $page) {
                                     ResourceManager::detach($resource_type, $handle, $page['id']);
                                 }
                             }
                         } else {
                             foreach ($checked as $handle) {
                                 foreach ($pages as $page) {
                                     ResourceManager::attach($resource_type, $handle, $page['id']);
                                 }
                             }
                         }
                         redirect(Administration::instance()->getCurrentPageURL());
                     }
                 }
             }
         }
     }
 }
Esempio n. 19
0
 public function appendFormattedElement(XMLElement &$wrapper, $data, $encode = false, $mode = null, $entry_id = null)
 {
     if (!is_array($data) || empty($data)) {
         return;
     }
     $role_id = $this->getActivationRole($entry_id, $data['role_id']);
     $role = RoleManager::fetch($role_id);
     if (!$role instanceof Role) {
         return;
     }
     $element = new XMLElement($this->get('element_name'), null, array('id' => $role->get('id'), 'assumed-id' => $data["role_id"], 'mode' => $mode == "permissions" ? $mode : 'normal'));
     $element->appendChild(new XMLElement('name', General::sanitize($role->get('name')), array('handle' => $role->get('handle'))));
     if ($mode == "permissions") {
         // The more information that's provided here, the easier it will be for
         // a developer to write XSLT that is dynamic and can work when the Roles
         // are updated in the backend. For instance you could check if a page was
         // denied access before creating a link to it. This check would then work
         // for all roles, instead of writing logic for Role A, Role B. Consider it
         // feature detection, rather than user agent detection.
         $forbidden_pages = $role->get('forbidden_pages');
         if (is_array($forbidden_pages) & !empty($forbidden_pages)) {
             $page_data = PageManager::fetch(false, array('*'), array(sprintf('id IN (%s)', implode(',', $forbidden_pages))));
             if (is_array($page_data) && !empty($page_data)) {
                 $pages = new XMLElement('forbidden-pages');
                 foreach ($page_data as $key => $page) {
                     $attributes = array('id' => $page['id'], 'handle' => $page['handle']);
                     if (!is_null($page['path'])) {
                         $attributes['parent-path'] = General::sanitize($page['path']);
                     }
                     $pages->appendChild(new XMLElement('page', $page['title'], $attributes));
                 }
                 $element->appendChild($pages);
             }
         }
         $event_permissions = $role->get('event_permissions');
         if (is_array($event_permissions) & !empty($event_permissions)) {
             $events = new XMLElement('events');
             foreach ($event_permissions as $event => $event_data) {
                 $item = new XMLElement('event', null, array('handle' => $event));
                 foreach ($event_data as $action => $level) {
                     $item->appendChild(new XMLElement('action', EventPermissions::$permissionMap[$level], array('type' => $action, 'handle' => Lang::createHandle(EventPermissions::$permissionMap[$level]))));
                 }
                 $events->appendChild($item);
             }
             $element->appendChild($events);
         }
     }
     $wrapper->appendChild($element);
 }
Esempio n. 20
0
 /**
  * This function is called from the resources index when a user uses the
  * With Selected, or Apply, menu. The type of resource is given by
  * `$resource_type`. At this time the only two valid values,
  * `RESOURCE_TYPE_EVENT` or `RESOURCE_TYPE_DATASOURCE`.
  *
  * The function handles 'delete', 'attach', 'detach', 'attach all',
  * 'detach all' actions.
  *
  * @param integer $resource_type
  *  Either `RESOURCE_TYPE_EVENT` or `RESOURCE_TYPE_DATASOURCE`
  * @throws Exception
  */
 public function __actionIndex($resource_type)
 {
     $manager = ResourceManager::getManagerFromType($resource_type);
     $checked = is_array($_POST['items']) ? array_keys($_POST['items']) : null;
     $context = Administration::instance()->getPageCallback();
     if (isset($_POST['action']) && is_array($_POST['action'])) {
         /**
          * Extensions can listen for any custom actions that were added
          * through `AddCustomPreferenceFieldsets` or `AddCustomActions`
          * delegates.
          *
          * @delegate CustomActions
          * @since Symphony 2.3.2
          * @param string $context
          *  '/blueprints/datasources/' or '/blueprints/events/'
          * @param array $checked
          *  An array of the selected rows. The value is usually the ID of the
          *  the associated object.
          */
         Symphony::ExtensionManager()->notifyMembers('CustomActions', $context['pageroot'], array('checked' => $checked));
         if (is_array($checked) && !empty($checked)) {
             if ($_POST['with-selected'] == 'delete') {
                 $canProceed = true;
                 foreach ($checked as $handle) {
                     $path = call_user_func(array($manager, '__getDriverPath'), $handle);
                     // Don't allow Extension resources to be deleted. RE: #2027
                     if (stripos($path, EXTENSIONS) === 0) {
                         continue;
                     } elseif (!General::deleteFile($path)) {
                         $folder = str_replace(DOCROOT, '', $path);
                         $folder = str_replace('/' . basename($path), '', $folder);
                         $this->pageAlert(__('Failed to delete %s.', array('<code>' . basename($path) . '</code>')) . ' ' . __('Please check permissions on %s', array('<code>' . $folder . '</code>')), Alert::ERROR);
                         $canProceed = false;
                     } else {
                         $pages = ResourceManager::getAttachedPages($resource_type, $handle);
                         foreach ($pages as $page) {
                             ResourceManager::detach($resource_type, $handle, $page['id']);
                         }
                     }
                 }
                 if ($canProceed) {
                     redirect(Administration::instance()->getCurrentPageURL());
                 }
             } elseif (preg_match('/^(at|de)?tach-(to|from)-page-/', $_POST['with-selected'])) {
                 if (substr($_POST['with-selected'], 0, 6) == 'detach') {
                     $page = str_replace('detach-from-page-', '', $_POST['with-selected']);
                     foreach ($checked as $handle) {
                         ResourceManager::detach($resource_type, $handle, $page);
                     }
                 } else {
                     $page = str_replace('attach-to-page-', '', $_POST['with-selected']);
                     foreach ($checked as $handle) {
                         ResourceManager::attach($resource_type, $handle, $page);
                     }
                 }
                 if ($canProceed) {
                     redirect(Administration::instance()->getCurrentPageURL());
                 }
             } elseif (preg_match('/^(at|de)?tach-all-pages$/', $_POST['with-selected'])) {
                 $pages = PageManager::fetch(false, array('id'));
                 if (substr($_POST['with-selected'], 0, 6) == 'detach') {
                     foreach ($checked as $handle) {
                         foreach ($pages as $page) {
                             ResourceManager::detach($resource_type, $handle, $page['id']);
                         }
                     }
                 } else {
                     foreach ($checked as $handle) {
                         foreach ($pages as $page) {
                             ResourceManager::attach($resource_type, $handle, $page['id']);
                         }
                     }
                 }
                 redirect(Administration::instance()->getCurrentPageURL());
             }
         }
     }
 }
Esempio n. 21
0
 public function render_panel($context)
 {
     $config = $context['config'];
     switch ($context['type']) {
         case 'datasource_to_table':
             $ds = DatasourceManager::create($config['datasource'], NULL, false);
             if (!$ds) {
                 $context['panel']->appendChild(new XMLElement('div', __('The Data Source with the name <code>%s</code> could not be found.', array($config['datasource']))));
                 return;
             }
             $param_pool = array();
             $xml = $ds->grab($param_pool);
             if (!$xml) {
                 return;
             }
             $xml = $xml->generate();
             require_once TOOLKIT . '/class.xsltprocess.php';
             $proc = new XsltProcess();
             $data = $proc->process($xml, file_get_contents(EXTENSIONS . '/dashboard/lib/datasource-to-table.xsl'));
             $context['panel']->appendChild(new XMLElement('div', $data));
             break;
         case 'rss_reader':
             require_once TOOLKIT . '/class.gateway.php';
             require_once CORE . '/class.cacheable.php';
             $cache_id = md5('rss_reader_cache' . $config['url']);
             $cache = new Cacheable(Administration::instance()->Database());
             $data = $cache->check($cache_id);
             if (!$data) {
                 $ch = new Gateway();
                 $ch->init();
                 $ch->setopt('URL', $config['url']);
                 $ch->setopt('TIMEOUT', 6);
                 $new_data = $ch->exec();
                 $writeToCache = true;
                 if ((int) $config['cache'] > 0) {
                     $cache->write($cache_id, $new_data, $config['cache']);
                 }
                 $xml = $new_data;
                 if (empty($xml) && $data) {
                     $xml = $data['data'];
                 }
             } else {
                 $xml = $data['data'];
             }
             if (!$xml) {
                 $xml = '<error>' . __('Error: could not retrieve panel XML feed.') . '</error>';
             }
             require_once TOOLKIT . '/class.xsltprocess.php';
             $proc = new XsltProcess();
             $data = $proc->process($xml, file_get_contents(EXTENSIONS . '/dashboard/lib/rss-reader.xsl'), array('show' => $config['show']));
             $context['panel']->appendChild(new XMLElement('div', $data));
             break;
         case 'html_block':
             require_once TOOLKIT . '/class.gateway.php';
             require_once CORE . '/class.cacheable.php';
             $cache_id = md5('html_block_' . $config['url']);
             $cache = new Cacheable(Administration::instance()->Database());
             $data = $cache->check($cache_id);
             if (!$data) {
                 $ch = new Gateway();
                 $ch->init();
                 $ch->setopt('URL', $config['url']);
                 $ch->setopt('TIMEOUT', 6);
                 $new_data = $ch->exec();
                 $writeToCache = true;
                 if ((int) $config['cache'] > 0) {
                     $cache->write($cache_id, $new_data, $config['cache']);
                 }
                 $html = $new_data;
                 if (empty($html) && $data) {
                     $html = $data['data'];
                 }
             } else {
                 $html = $data['data'];
             }
             if (!$html) {
                 $html = '<p class="invalid">' . __('Error: could not retrieve panel HTML.') . '</p>';
             }
             $context['panel']->appendChild(new XMLElement('div', $html));
             break;
         case 'symphony_overview':
             $container = new XMLElement('div');
             $dl = new XMLElement('dl');
             $dl->appendChild(new XMLElement('dt', __('Website Name')));
             $dl->appendChild(new XMLElement('dd', Symphony::Configuration()->get('sitename', 'general')));
             $current_version = Symphony::Configuration()->get('version', 'symphony');
             require_once TOOLKIT . '/class.gateway.php';
             $ch = new Gateway();
             $ch->init();
             $ch->setopt('URL', 'https://api.github.com/repos/symphonycms/symphony-2/tags');
             $ch->setopt('TIMEOUT', $timeout);
             $repo_tags = $ch->exec();
             // tags request found
             if (is_array($repo_tags)) {
                 $repo_tags = json_decode($repo_tags);
                 $tags = array();
                 foreach ($repo_tags as $tag) {
                     // remove tags that contain strings
                     if (preg_match('/[a-zA]/i', $tag->name)) {
                         continue;
                     }
                     $tags[] = $tag->name;
                 }
                 natsort($tags);
                 rsort($tags);
                 $latest_version = reset($tags);
             } else {
                 $latest_version = $current_version;
             }
             $needs_update = version_compare($latest_version, $current_version, '>');
             $dl->appendChild(new XMLElement('dt', __('Version')));
             $dl->appendChild(new XMLElement('dd', $current_version . ($needs_update ? ' (<a href="http://getsymphony.com/download/releases/version/' . $latest_version . '/">' . __('Latest is %s', array($latest_version)) . "</a>)" : '')));
             $container->appendChild(new XMLElement('h4', __('Configuration')));
             $container->appendChild($dl);
             $entries = 0;
             foreach (SectionManager::fetch() as $section) {
                 $entries += EntryManager::fetchCount($section->get('id'));
             }
             $dl = new XMLElement('dl');
             $dl->appendChild(new XMLElement('dt', __('Sections')));
             $dl->appendChild(new XMLElement('dd', (string) count(SectionManager::fetch())));
             $dl->appendChild(new XMLElement('dt', __('Entries')));
             $dl->appendChild(new XMLElement('dd', (string) $entries));
             $dl->appendChild(new XMLElement('dt', __('Data Sources')));
             $dl->appendChild(new XMLElement('dd', (string) count(DatasourceManager::listAll())));
             $dl->appendChild(new XMLElement('dt', __('Events')));
             $dl->appendChild(new XMLElement('dd', (string) count(EventManager::listAll())));
             $dl->appendChild(new XMLElement('dt', __('Pages')));
             $dl->appendChild(new XMLElement('dd', (string) count(PageManager::fetch())));
             $container->appendChild(new XMLElement('h4', __('Statistics')));
             $container->appendChild($dl);
             $context['panel']->appendChild($container);
             break;
         case 'markdown_text':
             $formatter = TextformatterManager::create($config['formatter']);
             $html = $formatter->run($config['text']);
             $context['panel']->appendChild(new XMLElement('div', $html));
             break;
     }
 }
 public function __viewIndexDSPages($context)
 {
     $pages = PageManager::fetch(false, array(), array(), 'sortorder ASC');
     $options = array();
     foreach ($pages as $page) {
         $selected = $this->driver->isDSPageSelected($page['id']);
         $options[] = array($page['id'], $selected, '/' . PageManager::resolvePagePath($page['id']));
     }
     $section = Widget::Label(__('Excluded Pages'));
     $section->setAttribute('class', 'column');
     $section->appendChild(Widget::Select('settings[ds-pages][]', $options, array('multiple' => 'multiple')));
     $context->appendChild($section);
 }
Esempio n. 23
0
 function view()
 {
     // fetch all pages
     $pages = PageManager::fetch();
     // build container DIV
     $sitemap = new XMLElement('div', null, array('class' => 'sitemap'));
     // add headings
     $sitemap->appendChild(new XMLElement('h1', 'Sitemap <span>' . Symphony::Configuration()->get('sitename', 'general') . '</span>'));
     $sitemap->appendChild(new XMLElement('h2', 'Site Map, ' . date('d F Y', time())));
     // build container ULs
     $primary = new XMLElement('ul', null, array('id' => 'primaryNav'));
     $utilities = new XMLElement('ul', null, array('id' => 'utilityNav'));
     // get values from config: remove spaces, remove any trailing commas and split into an array
     $this->type_index = explode(',', trim(preg_replace('/ /', '', Symphony::Configuration()->get('index_type', 'sitemap')), ','));
     $this->type_primary = explode(',', trim(preg_replace('/ /', '', Symphony::Configuration()->get('primary_type', 'sitemap')), ','));
     $this->type_utility = explode(',', trim(preg_replace('/ /', '', Symphony::Configuration()->get('utilities_type', 'sitemap')), ','));
     $this->type_exclude = explode(',', trim(preg_replace('/ /', '', Symphony::Configuration()->get('exclude_type', 'sitemap')), ','));
     // supplement list of pages with additional meta data
     foreach ($pages as $page) {
         $page['url'] = '/' . implode('/', Administration::instance()->resolvePagePath($page['id']));
         $page['edit-url'] = Administration::instance()->getCurrentPageURL() . 'edit/' . $page['id'] . '/';
         if (count(array_intersect($page['type'], $this->type_exclude)) > 0) {
             continue;
         }
         $page['is_home'] = count(array_intersect($page['type'], $this->type_index)) ? true : false;
         $page['is_primary'] = count(array_intersect($page['type'], $this->type_primary)) > 0 ? true : false;
         $page['is_utility'] = count(array_intersect($page['type'], $this->type_utility)) > 0 ? true : false;
         $this->_pages[] = $page;
     }
     // append the Home page first
     foreach ($this->_pages as $page) {
         if ($page['is_home'] == true) {
             $this->appendPage($primary, $page, 1, true, false);
         }
     }
     // append top level pages
     $primary_pages = 0;
     foreach ($this->_pages as $page) {
         if ($page['is_primary'] == true) {
             $primary_pages++;
             $this->appendPage($primary, $page);
         }
     }
     // sitemap provides styles for up to 10 top level pages
     if ($primary_pages > 0 && $primary_pages < 11) {
         $primary->setAttribute('class', 'col' . $primary_pages);
     }
     // append utilities (global) pages
     foreach ($this->_pages as $page) {
         if ($page['is_utility'] == true) {
             $this->appendPage($utilities, $page, 1, false, false);
         }
     }
     if ($utilities->getNumberOfChildren() > 0) {
         $sitemap->appendChild($utilities);
     }
     $sitemap->appendChild($primary);
     // build a vanilla HTML document
     $html = new XMLElement('html');
     $html->setDTD('<!DOCTYPE html>');
     $head = new XMLElement('head');
     $head->appendChild(new XMLElement('meta', null, array('charset' => 'utf-8')));
     $head->appendChild(new XMLElement('title', 'Site Map — ' . Symphony::Configuration()->get('sitename', 'general')));
     $head->appendChild(new XMLElement('link', null, array('rel' => 'stylesheet', 'type' => 'text/css', 'media' => 'print, screen', 'href' => URL . '/extensions/sitemap/assets/sitemap.map.css')));
     $head->appendChild(new XMLElement('link', null, array('rel' => 'stylesheet', 'type' => 'text/css', 'media' => 'print, screen', 'href' => URL . '/extensions/sitemap/assets/slickmap/slickmap.css')));
     $html->appendChild($head);
     $body = new XMLElement('body');
     $body->appendChild($sitemap);
     $html->appendChild($body);
     header('content-type: text/html');
     echo $html->generate(true);
     die;
 }