public function appendTo(SymphonyDOMElement $wrapper) { $this->layout->setAttribute('class', $this->class); ### # Delegate: LayoutPreGenerate # Description: Allows developers to access the layout content # before it is appended to the page. Extension::notify('LayoutPreGenerate', '/administration/', $this->layout); if ($wrapper->tagName == 'form') { $this->layout->setAttribute('id', 'layout'); } $wrapper->appendChild($this->layout); }
public function render(Register $Parameters, XMLDocument &$Document = NULL, DocumentHeaders &$Headers = NULL) { $ParameterOutput = new Register(); if (!is_null($Headers)) { $Headers->append('Content-Type', $this->{'content-type'}); } else { header('Content-Type: ' . $this->{'content-type'}); } if (is_null($Document)) { $Document = new XMLDocument(); $Document->appendChild($Document->createElement('data')); } $root = $Document->documentElement; $datasources = $events = array(); $events_wrapper = $Document->createElement('events'); $root->appendChild($events_wrapper); if (is_array($this->about()->{'events'}) && !empty($this->about()->{'events'})) { $events = $this->about()->{'events'}; } if (is_array($this->about()->{'data-sources'}) && !empty($this->about()->{'data-sources'})) { $datasources = $this->about()->{'data-sources'}; } #### # Delegate: FrontendEventsAppend # Description: Append additional Events. # Global: Yes Extension::notify('FrontendEventsAppend', '/frontend/', array('events' => &$events)); if (!empty($events)) { $postdata = General::getPostData(); $events_ordered = array(); foreach ($events as $handle) { $events_ordered[] = Event::loadFromHandle($handle); } uasort($events_ordered, array($this, '__cbSortEventsByPriority')); foreach ($events_ordered as $e) { if (!$e->canTrigger($postdata)) { continue; } $fragment = $e->trigger($ParameterOutput, $postdata); if ($fragment instanceof DOMDocument && !is_null($fragment->documentElement)) { $node = $Document->importNode($fragment->documentElement, true); $events_wrapper->appendChild($node); } } } #### # Delegate: FrontendDataSourceAppend # Description: Append additional DataSources. # Global: Yes Extension::notify('FrontendDataSourcesAppend', '/frontend/', array('datasources' => &$datasources)); // Find dependancies and order accordingly $datasource_pool = array(); $dependency_list = array(); $datasources_ordered = array(); $all_dependencies = array(); foreach ($datasources as $handle) { $datasource_pool[$handle] = Datasource::loadFromHandle($handle); $dependency_list[$handle] = $datasource_pool[$handle]->parameters()->dependencies; } $datasources_ordered = $this->__sortByDependencies($dependency_list); if (!empty($datasources_ordered)) { foreach ($datasources_ordered as $handle) { $ds = $datasource_pool[$handle]; try { $fragment = $ds->render($ParameterOutput); } catch (FrontendPageNotFoundException $e) { FrontendPageNotFoundExceptionHandler::render($e); } if ($fragment instanceof DOMDocument && !is_null($fragment->documentElement)) { $node = $Document->importNode($fragment->documentElement, true); $root->appendChild($node); } } } if ($ParameterOutput->length() > 0) { foreach ($ParameterOutput as $p) { $Parameters->{$p->key} = $p->value; } } #### # Delegate: FrontendParamsPostResolve # Description: Access to the resolved param pool, including additional parameters provided by Data Source outputs # Global: Yes Extension::notify('FrontendParamsPostResolve', '/frontend/', array('params' => $Parameters)); $element = $Document->createElement('parameters'); $root->appendChild($element); foreach ($Parameters as $key => $parameter) { if (is_array($parameter->value) && count($parameter->value) > 1) { $p = $Document->createElement($key); $p->setAttribute('value', (string) $parameter); foreach ($parameter->value as $v) { $p->appendChild($Document->createElement('item', (string) $v)); } $element->appendChild($p); } else { $element->appendChild($Document->createElement($key, (string) $parameter)); } } $template = $this->template; #### # Delegate: FrontendTemplatePreRender # Description: Access to the template source, before it is rendered. # Global: Yes Extension::notify('FrontendTemplatePreRender', '/frontend/', array('document' => $Document, 'template' => &$template)); $this->template = $template; // When the XSLT executes, it uses the CWD as set here $cwd = getcwd(); chdir(WORKSPACE); $output = XSLProc::transform($Document, $this->template, XSLProc::XML, $Parameters->toArray(), array()); chdir($cwd); if (XSLProc::hasErrors()) { throw new XSLProcException('Transformation Failed'); } /* header('Content-Type: text/plain; charset=utf-8'); $Document->formatOutput = true; print $Document->saveXML(); die(); */ return $output; }
public function action() { if (isset($_POST['items'])) { $checked = array_keys($_POST['items']); } try { if (isset($_POST['action']['apply']) && isset($_POST['with-selected']) && is_array($checked) && !empty($checked)) { $action = $_POST['with-selected']; if (method_exists('Extension', $action)) { ### # Delegate: {name of the action} (enable|disable|uninstall) # Description: Notifies of enabling, disabling or uninstalling of an Extension. Array of selected extensions is provided. # This can be modified. Extension::notify($action, getCurrentPage(), array('extensions' => &$checked)); foreach ($checked as $handle) { call_user_func(array('Extension', $action), $handle); } } redirect(Administration::instance()->getCurrentPageURL()); } elseif (isset($_POST['action'])) { $action = end(array_keys($_POST['action'])); $handle = end(array_keys($_POST['action'][$action])); if (method_exists('Extension', $action)) { ### # Delegate: {name of the action} (enable|disable|uninstall) # Description: Notifies of enabling, disabling or uninstalling of an Extension. Extension handle is provided # This can be modified. Extension::notify($action, getCurrentPage(), array('extensions' => &$handle)); call_user_func(array('Extension', $action), $handle); redirect(Administration::instance()->getCurrentPageURL()); } } } catch (ExtensionException $e) { $extension = Extension::load($handle); $about = $extension->about(); switch ($action) { case 'enable': $message = "%s could not be enabled. <a class='more'>Show more information.</a>"; break; case 'disable': $message = "%s could not be disabled. <a class='more'>Show more information.</a>"; break; case 'uninstall': $message = "%s could not be uninstalled. <a class='more'>Show more information.</a>"; break; } $this->alerts()->append(__($message, array(isset($about) ? $about->{'name'} : $name)), AlertStack::ERROR, $e); return false; } }
protected function login(MessageStack $errors, Register $parameter_output, array $data) { $section = Section::loadFromHandle($this->parameters()->{'section'}); $wheres = array(); $joins = null; // Find fields: foreach ($section->fields as $field) { if ($field instanceof FieldMemberName) { $field_name = $field; $handle_name = $field->{'element-name'}; } else { if ($field instanceof FieldMemberEmail) { $field_email = $field; $handle_email = $field->{'element-name'}; } else { if ($field instanceof FieldMemberPassword) { $field_password = $field; $handle_password = $field->{'element-name'}; } } } } if (!isset($field_email) or !isset($field_password)) { throw new Exception(__('Section does not contain required fields.')); } // Simulate data from cookie: if (empty($data) and $this->readSession()) { $session = $this->readSession(); $fields = array($field_email->{'element-name'} => $session->email, $field_password->{'element-name'} => $session->login); } else { $this->deleteSession(); $fields = $data['fields']; } // Apply default values: foreach ($this->parameters()->{'defaults'} as $name => $value) { if (!isset($fields[$name])) { $fields[$name] = $value; } else { if (is_string($fields[$name]) and $fields[$name] == '') { $fields[$name] = $value; } else { if (is_array($fields[$name]) and empty($fields[$name])) { $fields[$name] = array($value); } } } } // Apply override values: foreach ($this->parameters()->{'overrides'} as $name => $value) { if (is_array($fields[$name])) { $fields[$name] = array($value); } else { $fields[$name] = $value; } } // Find values: if (isset($field_name)) { $value_name = (isset($fields[$handle_name]) and strlen($fields[$handle_name]) > 0) ? $fields[$handle_name] : null; } if (isset($field_email)) { $value_email = (isset($fields[$handle_email]) and strlen($fields[$handle_email]) > 0) ? $fields[$handle_email] : null; } if (isset($field_password)) { $value_password = (isset($fields[$handle_password]) and strlen($fields[$handle_password]) > 0) ? $fields[$handle_password] : null; } if (is_null($value_email) and is_null($value_name) or is_null($value_password)) { throw new Exception(__('Missing login credentials.')); } // Build query: $where_password = array(); $value_password = array('value' => $value_password, 'type' => 'is'); $field_password->buildFilterQuery($value_password, $joins, $where_password, $parameter_output); if (isset($field_email) and !is_null($value_email)) { $where_email = $where_password; $value_email = array('value' => $value_email, 'type' => 'is'); $field_email->buildFilterQuery($value_email, $joins, $where_email, $parameter_output); $wheres[] = '(' . implode("\nAND ", $where_email) . ')'; } if (isset($field_name) and !is_null($value_name)) { $where_name = $where_password; $value_name = array('value' => $value_name, 'type' => 'is'); $field_name->buildFilterQuery($value_name, $joins, $where_name, $parameter_output); $wheres[] = '(' . implode("\nAND ", $where_name) . ')'; } array_unshift($wheres, null); $wheres = implode("\nOR ", $wheres); $query = "\nSELECT DISTINCT\n\te.*\nFROM\n\t`tbl_entries` AS e{$joins}\nWHERE\n\tFALSE{$wheres}\n\t\t\t"; //echo '<pre>', htmlentities($query), '</pre>'; exit; // Find entry: $result = Symphony::Database()->query($query, array(), 'EntryResult'); if (!$result->valid()) { throw new Exception(__('Invalid login credentials.')); } $entry = $result->current(); $email = $entry->data()->{$handle_email}->value; $code = $entry->data()->{$handle_password}->code; $login = $this->driver->createToken($code, 'login'); if ($this->parameters()->{'create-cookie'} == true) { $this->writeCookie($login, $email); } $event_name = $this->parameters()->{'root-element'}; $parameter_output->{"event-{$event_name}.system.id"} = $entry->id; $parameter_output->{"event-{$event_name}.member.email"} = $email; $parameter_output->{"event-{$event_name}.member.login"} = $login; // Remove login fields: unset($fields[$handle_name], $fields[$handle_email], $fields[$handle_password]); // Set password as optional: $fields[$handle_password] = array('validate' => array('optional' => $this->driver->createToken($code, 'validate')), 'change' => array('optional' => $this->driver->createToken($code, 'change'))); // Update fields: $entry->setFieldDataFromFormArray($fields); ### # Delegate: EntryPreCreate # Description: Just prior to creation of an Entry. Entry object provided Extension::notify('EntryPreCreate', '/frontend/', array('entry' => &$entry)); $status = Entry::save($entry, $errors); if ($status != Entry::STATUS_OK) { throw new Exception(__('Entry encountered errors when saving.')); } ### # Delegate: EntryPostCreate # Description: Creation of an Entry. New Entry object is provided. Extension::notify('EntryPostCreate', '/frontend/', array('entry' => $entry)); }
public function __actionIndex() { if (!is_writable(CONF)) { return; } if (isset($_POST['action']['save'])) { $settings = $_POST['settings']; ### # Delegate: Save # Description: Saving of system preferences. Extension::notify('Save', '/system/settings/', array('settings' => &$settings, 'errors' => &$this->errors)); // Site name if (strlen(trim($settings['symphony']['sitename'])) == 0) { $this->errors->append('symphony::sitename', __("'%s' is a required field.", array('Site Name'))); } // Date format // TODO: Figure out a way to check date formats to ensure they are valid if (strlen(trim($settings['region']['date-format'])) == 0) { $this->errors->append('region::date-format', __("'%s' is a required field.", array('Date Format'))); } //elseif(!date_parse(DateTimeObj::get($settings['region']['date-format'] . 'H:m:s'))){ // $this->errors->append('region::date-format', __("Invalid date format specified.")); //} // Time format // TODO: Figure out a way to check time formats to ensure they are valid if (strlen(trim($settings['region']['time-format'])) == 0) { $this->errors->append('region::time-format', __("'%s' is a required field.", array('Time Format'))); } //elseif(!date_parse(DateTimeObj::get('Y-m-d' . $settings['region']['time-format']))){ // $this->errors->append('region::time-format', __("Invalid time format specified.")); //} if ($this->errors->length() <= 0) { if (is_array($settings) && !empty($settings)) { foreach ($settings as $set => $values) { foreach ($values as $key => $val) { Symphony::Configuration()->core()->{$set}->{$key} = $val; } } } Symphony::Configuration()->save(); redirect(ADMIN_URL . '/system/settings/:saved/'); } else { $this->alerts()->append(__('An error occurred while processing this form. <a href="#error">See below for details.</a>'), AlertStack::ERROR, $this->errors); } } }
private function __save(Role $role) { $fields = $_POST['fields']; $role->name = $fields['name']; $role->description = $fields['description']; $role->flushPermissions(); foreach ($fields['permissions'] as $key => $p) { foreach ($p as $type => $level) { $role->permissions()->{"{$key}.{$type}"} = (int) $level; } } ### # Delegate: AACRolePreCreate # Description: Just before creation of a new Role. Role object, fields array and error stack provided Extension::notify('AACRolePreCreate', '/extension/aac/roles/new/', array('fields' => $fields, 'role' => &$role, 'errors' => &$this->errors)); $this->role = $role; try { $result = Role::save($this->role, $this->errors); if (!isset($this->role->id)) { $this->role->id = $result; } ### # Delegate: AACRolePostCreate # Description: After creation of a new Role. Role object provided Extension::notify('AACRolePostCreate', '/extension/aac/roles/new/', array('role' => $this->role)); redirect(sprintf("%s/extension/aac/roles/edit/%d/:%s/", ADMIN_URL, $this->role->id, isset($role->id) ? 'saved' : 'created')); } catch (RoleException $e) { $this->alerts()->append(__('There were some problems while attempting to save. Please check below for problem fields.'), AlertStack::ERROR, $this->errors); } catch (Exception $e) { $this->alerts()->append(__('An unknown error has occurred. <a class="more">Show trace information.</a>'), AlertStack::ERROR, $e); } }
public function __actionDelete(array $sections, $redirect) { $success = true; $callback = Administration::instance()->getPageCallback(); $current_page = $callback['pageroot'] . (isset($callback['context'][0]) && $callback['context'][0] != 'index' ? $callback['context'][0] . '/' : NULL); foreach ($sections as $handle) { try { Section::delete(Section::loadFromHandle($handle)); ### # Delegate: SectionPostDelete Extension::notify('SectionPostDelete', $current_page, array('handle' => $handle)); } catch (SectionException $e) { $success = false; $this->alerts()->append($e->getMessage(), AlertStack::ERROR, $e); } catch (Exception $e) { $success = false; $this->alerts()->append(__('An unknown error has occurred. <a class="more">Show trace information.</a>'), AlertStack::ERROR, $e); } } if ($success) { redirect($redirect); } }
public function display($url = NULL) { self::$Parameters = new Register(); // Default headers. Can be overwritten later //self::$Headers->append('HTTP/1.0 200 OK'); self::$Headers->append('Content-Type', 'text/html;charset=utf-8'); self::$Headers->append('Expires', 'Mon, 12 Dec 1982 06:14:00 GMT'); self::$Headers->append('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT'); self::$Headers->append('Cache-Control', 'no-cache, must-revalidate, max-age=0'); self::$Headers->append('Pragma', 'no-cache'); #### # Delegate: FrontendPreInitialise # Description: TODO # Global: Yes Extension::notify('FrontendPreInitialise', '/frontend/', array('view' => &self::$view, 'url' => &$url)); if (!self::$view instanceof View) { $this->resolve($url); } #### # Delegate: FrontendPostInitialise Extension::notify('FrontendPostInitialise', '/frontend/', array('view' => &self::$view)); // SETTING UP PARAMETERS -------------------------- $root_page = array_shift(explode('/', self::$view->parent()->path)); $current_path = explode(dirname($_SERVER['SCRIPT_NAME']), $_SERVER['REQUEST_URI'], 2); $current_path = '/' . ltrim(end($current_path), '/'); self::$Parameters->register(array('today' => DateTimeObj::get('Y-m-d'), 'current-time' => DateTimeObj::get('H:i'), 'this-year' => DateTimeObj::get('Y'), 'this-month' => DateTimeObj::get('m'), 'this-day' => DateTimeObj::get('d'), 'timezone' => date_default_timezone_get(), 'website-name' => Symphony::Configuration()->core()->symphony->sitename, 'symphony-version' => Symphony::Configuration()->core()->symphony->version, 'upload-limit' => min(ini_size_to_bytes(ini_get('upload_max_filesize')), Symphony::Configuration()->core()->symphony->{'maximum-upload-size'}), 'root' => URL, 'workspace' => URL . '/workspace', 'page-title' => self::$view->title, 'root-page' => !is_null($root_page) ? $root_page : self::$view->handle, 'current-page' => self::$view->handle, 'current-path' => $current_path, 'parent-path' => '/' . self::$view->path, 'current-url' => URL . $current_path)); if (isset(self::$view->{'url-parameters'}) && is_array(self::$view->{'url-parameters'})) { foreach (self::$view->{'url-parameters'} as $p) { self::$Parameters->{$p} = NULL; } foreach (self::$view->parameters() as $p => $v) { self::$Parameters->{$p} = str_replace(' ', '+', $v); } } if (is_array($_GET) && !empty($_GET)) { foreach ($_GET as $key => $val) { if (in_array($key, array('symphony-page', 'debug', 'profile'))) { continue; } // self::$Parameters->{"url-{$key}"} = $val; "url" is not prepended by $_GET params self::$Parameters->{$key} = $val; } } if (is_array($_COOKIE[__SYM_COOKIE_PREFIX__]) && !empty($_COOKIE[__SYM_COOKIE_PREFIX__])) { foreach ($_COOKIE[__SYM_COOKIE_PREFIX__] as $key => $val) { self::$Parameters->{"cookie-{$key}"} = $val; } } // RENDER THE VIEW -------------------------- // Can ask the view to operate on an existing // Document. Useful if we pass it around beyond // the scope of View::render() #### # Delegate: FrontendPreRender # Description: TODO # Global: Yes Extension::notify('FrontendPreRender', '/frontend/', array('view' => &self::$view, 'parameters' => &self::$Parameters, 'document' => &self::$Document, 'headers' => &self::$Headers)); $output = self::$view->render(self::$Parameters, self::$Document, self::$Headers); #### # Delegate: FrontendPostRender # Description: TODO # Global: Yes Extension::notify('FrontendPostRender', '/frontend/', array('output' => &$output, 'headers' => &self::$Headers)); self::Headers()->render(); return $output; }
public function display($page) { // Default headers. Can be overwritten later //self::$Headers->append('HTTP/1.0 200 OK'); self::$Headers->append('Content-Type', 'text/html;charset=utf-8'); self::$Headers->append('Expires', 'Mon, 12 Dec 1982 06:14:00 GMT'); self::$Headers->append('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT'); self::$Headers->append('Cache-Control', 'no-cache, must-revalidate, max-age=0'); self::$Headers->append('Pragma', 'no-cache'); $this->isLoggedIn(); if (empty($page)) { if (!$this->isLoggedIn()) { $page = '/login'; } else { $section_handle = $this->User->default_section; // Make sure section exists: try { $section = Section::loadFromHandle($section_handle); redirect(ADMIN_URL . "/publish/{$section_handle}/"); } catch (Exception $e) { redirect(ADMIN_URL . '/blueprints/sections/'); } } } if (!($this->_callback = $this->getPageCallback($page))) { throw new AdministrationPageNotFoundException($page); } include_once (isset($this->_callback['driverlocation']) ? $this->_callback['driverlocation'] : CONTENT) . '/content.' . $this->_callback['driver'] . '.php'; $this->Page = new $this->_callback['classname'](); // Widget class needs a document in order to create elements Widget::init($this->Page); #### # Delegate: AdminPagePreBuild # Description: Immediately before building the admin page. Provided with the page and callback # Global: Yes Extension::notify('AdminPagePreBuild', '/administration/', array('page' => &$this->Page, 'callback' => &$this->_callback)); if (!$this->isLoggedIn() && $this->_callback['driver'] != 'login') { if (is_callable(array($this->Page, 'handleFailedAuthorisation'))) { $this->Page->handleFailedAuthorisation(); } else { include_once CONTENT . '/content.login.php'; $this->Page = new contentLogin(); $this->Page->build(); } } else { $this->Page->build($this->_callback['context']); } #### # Delegate: AdminPagePreGenerate # Description: Immediately before generating the admin page. Provided with the page object # Global: Yes Extension::notify('AdminPagePreGenerate', '/administration/', array('page' => &$this->Page)); $output = (string) $this->Page; #### # Delegate: AdminPagePostGenerate # Description: Immediately after generating the admin page. Provided with string containing page source # Global: Yes Extension::notify('AdminPagePostGenerate', '/administration/', array('output' => &$output)); self::Headers()->render(); return $output; }
public function trigger(Register $ParameterOutput, array $postdata) { $result = new XMLDocument(); $result->appendChild($result->createElement($this->parameters()->{'root-element'})); $root = $result->documentElement; // Apply default values: foreach ($this->parameters()->{'defaults'} as $name => $value) { if (!isset($postdata['fields'][$name])) { $postdata['fields'][$name] = $value; } else { if (is_string($postdata['fields'][$name]) and $postdata['fields'][$name] == '') { $postdata['fields'][$name] = $value; } else { if (is_array($postdata['fields'][$name]) and empty($postdata['fields'][$name])) { $postdata['fields'][$name] = array($value); } } } } // Apply override values: foreach ($this->parameters()->{'overrides'} as $name => $value) { if (is_array($postdata['fields'][$name])) { $postdata['fields'][$name] = array($value); } else { $postdata['fields'][$name] = $value; } } if (isset($postdata['id'])) { $entry = Entry::loadFromID($postdata['id']); $type = 'edit'; } else { $entry = new Entry(); $entry->section = $this->parameters()->{'section'}; if (isset(Frontend::instance()->User) && Frontend::instance()->User instanceof User) { $entry->user_id = Frontend::instance()->User->id; } else { $entry->user_id = (int) Symphony::Database()->query("SELECT `id` FROM `tbl_users` ORDER BY `id` ASC LIMIT 1")->current()->id; } $type = 'create'; } if (isset($postdata['fields']) && is_array($postdata['fields']) && !empty($postdata['fields'])) { $entry->setFieldDataFromFormArray($postdata['fields']); } $root->setAttribute('type', $type); ### # Delegate: EntryPreCreate # Description: Just prior to creation of an Entry. Entry object provided Extension::notify('EntryPreCreate', '/frontend/', array('entry' => &$entry)); $errors = new MessageStack(); $status = Entry::save($entry, $errors); if ($status == Entry::STATUS_OK) { ### # Delegate: EntryPostCreate # Description: Creation of an Entry. New Entry object is provided. Extension::notify('EntryPostCreate', '/frontend/', array('entry' => $entry)); if ($this->parameters()->{'output-id-on-save'} == true) { $ParameterOutput->{sprintf('event-%s-id', $this->parameters()->{'root-element'})} = $entry->id; } $root->setAttribute('result', 'success'); $root->setAttribute('id', $entry->id); $root->appendChild($result->createElement('message', __("Entry %s successfully.", array($type == 'edit' ? __('edited') : __('created'))))); } else { $root->setAttribute('result', 'error'); $root->appendChild($result->createElement('message', __('Entry encountered errors when saving.'))); if (!isset($postdata['fields']) || !is_array($postdata['fields'])) { $postdata['fields'] = array(); } $element = $result->createElement('errors'); $this->appendMessages($element, $errors); $root->appendChild($element); } $messages = new MessageStack(); ### # Delegate: EventPostSaveFilter # Description: After saving entry from the front-end. This delegate will not force the Events to terminate if it populates the error # array reference. Provided with the event, message stack, postdata and entry object. Extension::notify('EventPostSaveFilter', '/frontend/', array('event' => $this, 'messages' => $messages, 'fields' => $postdata, 'entry' => $entry)); if ($messages->valid()) { $filter = $result->createElement('filters'); $this->appendMessages($filter, $messages); $root->appendChild($filter); } $element = $result->createElement('values'); $this->appendValues($element, is_array($postdata['fields']) ? $postdata['fields'] : array()); $root->appendChild($element); return $result; }
protected function __buildNavigation() { $nav = array(); $xml = simplexml_load_file(ASSETS . '/navigation.xml'); foreach ($xml->xpath('/navigation/group') as $n) { $index = (string) $n->attributes()->index; $children = $n->xpath('children/item'); $content = $n->attributes(); if (isset($nav[$index])) { do { $index++; } while (isset($nav[$index])); } $nav[$index] = array('name' => __(strval($content->name)), 'index' => $index, 'children' => array()); if (strlen(trim((string) $content->limit)) > 0) { $nav[$index]['limit'] = (string) $content->limit; } if (count($children) > 0) { foreach ($children as $child) { $limit = (string) $child->attributes()->limit; $item = array('link' => (string) $child->attributes()->link, 'name' => __(strval($child->attributes()->name)), 'visible' => (string) $child->attributes()->visible == 'no' ? 'no' : 'yes'); if (strlen(trim($limit)) > 0) { $item['limit'] = $limit; } $nav[$index]['children'][] = $item; } } } foreach (new SectionIterator() as $s) { $group_index = self::__navigationFindGroupIndex($nav, $s->{'navigation-group'}); if ($group_index === false) { $group_index = General::array_find_available_index($nav, 0); $nav[$group_index] = array('name' => $s->{'navigation-group'}, 'index' => $group_index, 'children' => array(), 'limit' => NULL); } $nav[$group_index]['children'][] = array('link' => '/publish/' . $s->handle . '/', 'name' => $s->name, 'type' => 'section', 'section' => array('id' => $s->guid, 'handle' => $s->handle), 'visible' => $s->{'hidden-from-publish-menu'} == 'no' ? 'yes' : 'no'); } // $extensions = ExtensionManager::instance()->listInstalledHandles(); foreach (new ExtensionIterator(ExtensionIterator::FLAG_STATUS, Extension::STATUS_ENABLED) as $e) { if (!method_exists($e, 'fetchNavigation')) { continue; } $e_navigation = $e->fetchNavigation(); if (isset($e_navigation) && is_array($e_navigation) && !empty($e_navigation)) { foreach ($e_navigation as $item) { $type = isset($item['children']) ? Extension::NAVIGATION_GROUP : Extension::NAVIGATION_CHILD; switch ($type) { case Extension::NAVIGATION_GROUP: $index = General::array_find_available_index($nav, $item['location']); $nav[$index] = array('name' => $item['name'], 'index' => $index, 'children' => array(), 'limit' => !is_null($item['limit']) ? $item['limit'] : NULL); foreach ($item['children'] as $child) { if (!isset($child['relative']) || $child['relative'] == true) { $link = '/extension/' . Extension::getHandleFromPath(Extension::getPathFromClass(get_class($e))) . '/' . ltrim($child['link'], '/'); } else { $link = '/' . ltrim($child['link'], '/'); } $nav[$index]['children'][] = array('link' => $link, 'name' => $child['name'], 'visible' => $child['visible'] == 'no' ? 'no' : 'yes', 'limit' => !is_null($child['limit']) ? $child['limit'] : NULL); } break; case Extension::NAVIGATION_CHILD: if (!isset($item['relative']) || $item['relative'] == true) { $link = '/extension/' . Extension::getHandleFromPath(Extension::getPathFromClass(get_class($e))) . '/' . ltrim($item['link'], '/'); } else { $link = '/' . ltrim($item['link'], '/'); } if (!is_numeric($item['location'])) { // is a navigation group $group_name = $item['location']; $group_index = $this->__findLocationIndexFromName($nav, $item['location']); } else { // is a legacy numeric index $group_index = $item['location']; } $child = array('link' => $link, 'name' => $item['name'], 'visible' => $item['visible'] == 'no' ? 'no' : 'yes', 'limit' => !is_null($item['limit']) ? $item['limit'] : NULL); if ($group_index === false) { // add new navigation group $nav[] = array('name' => $group_name, 'index' => $group_index, 'children' => array($child), 'limit' => !is_null($item['limit']) ? $item['limit'] : NULL); } else { // add new location by index $nav[$group_index]['children'][] = $child; } break; } } } } #### # Delegate: ExtensionsAddToNavigation # Description: After building the Navigation properties array. This is specifically # for extentions to add their groups to the navigation or items to groups, # already in the navigation. Note: THIS IS FOR ADDING ONLY! If you need # to edit existing navigation elements, use the 'NavigationPreRender' delegate. # Global: Yes Extension::notify('ExtensionsAddToNavigation', '/administration/', array('navigation' => &$nav)); $pageCallback = Administration::instance()->getPageCallback(); $pageRoot = $pageCallback['pageroot'] . (isset($pageCallback['context'][0]) ? $pageCallback['context'][0] . '/' : ''); $found = $this->__findActiveNavigationGroup($nav, $pageRoot); ## Normal searches failed. Use a regular expression using the page root. This is less ## efficent and should never really get invoked unless something weird is going on if (!$found) { $this->__findActiveNavigationGroup($nav, '/^' . str_replace('/', '\\/', $pageCallback['pageroot']) . '/i', true); } ksort($nav); $this->_navigation = $nav; }
public function appendFormattedElement(SymphonyDOMElement $wrapper, $data, $encode = false, $mode = null, Entry $entry = null) { if (!$this->sanitizeDataArray($data)) { return null; } $document = $wrapper->ownerDocument; $meta = unserialize($data->meta); if (!is_array($meta)) { $meta = array(); } $meta['size'] = General::formatFilesize($data->size); $meta['type'] = $data->type; ksort($meta); $field = $document->createElement($this->{'element-name'}); $field->appendChild($document->createElement('file', $data->name, array('path' => trim($data->path, '/'), 'name' => $data->file))); $element = $document->createElement('meta'); foreach ($meta as $key => $value) { if ($key == 'creation' or $key == 'type') { $element->setAttribute($key, $value); } else { if ($key == 'size') { $bits = explode(' ', $value); if (count($bits) != 2) { continue; } $element->appendChild($document->createElement('size', $bits[0], array('unit' => $bits[1]))); } else { if (is_array($value)) { $element->appendChild($document->createElement($key, null, $value)); } else { $element->appendChild($document->createElement($key, (string) $value)); } } } } $field->appendChild($element); ### # Delegate: UploadField_AppendFormattedElement # Description: Allow other extensions to add media previews. Extension::notify('UploadField_AppendFormattedElement', '/publish/', array('data' => $data, 'entry' => $entry, 'field' => $this, 'wrapper' => $field)); $wrapper->appendChild($field); }
public function trigger(Register $ParameterOutput, array $postdata) { $result = new XMLDocument(); $result->appendChild($result->createElement($this->parameters()->{'root-element'})); $root = $result->documentElement; if (isset($postdata['id'])) { $entry = Entry::loadFromID($postdata['id']); $type = 'edit'; } else { $entry = new Entry(); $entry->section = $this->parameters()->{'section'}; if (isset(Frontend::instance()->User) && Frontend::instance()->User instanceof User) { $entry->user_id = Frontend::instance()->User->id; } else { $entry->user_id = (int) Symphony::Database()->query("SELECT `id` FROM `tbl_users` ORDER BY `id` ASC LIMIT 1")->current()->id; } $type = 'create'; } if (isset($postdata['fields']) && is_array($postdata['fields']) && !empty($postdata['fields'])) { $entry->setFieldDataFromFormArray($postdata['fields']); } $root->setAttribute('type', $type); ### # Delegate: EntryPreCreate # Description: Just prior to creation of an Entry. Entry object provided Extension::notify('EntryPreCreate', '/frontend/', array('entry' => &$entry)); $errors = new MessageStack(); $status = Entry::save($entry, $errors); if ($status == Entry::STATUS_OK) { ### # Delegate: EntryPostCreate # Description: Creation of an Entry. New Entry object is provided. Extension::notify('EntryPostCreate', '/frontend/', array('entry' => $entry)); if ($this->parameters()->{'output-id-on-save'} == true) { $ParameterOutput->{sprintf('event-%s-id', $this->parameters()->{'root-element'})} = $entry->id; } $root->setAttribute('result', 'success'); $root->appendChild($result->createElement('message', __("Entry %s successfully.", array($type == 'edit' ? __('edited') : __('created'))))); } else { $root->setAttribute('result', 'error'); $root->appendChild($result->createElement('message', __('Entry encountered errors when saving.'))); if (!isset($postdata['fields']) || !is_array($postdata['fields'])) { $postdata['fields'] = array(); } $element = $result->createElement('values'); $this->appendValues($element, $postdata['fields']); $root->appendChild($element); $element = $result->createElement('errors'); $this->appendMessages($element, $errors); $root->appendChild($element); } return $result; }
public function displayPublishPanel(SymphonyDOMElement $wrapper, MessageStack $errors, Entry $entry = NULL, $data = NULL) { $document = $wrapper->ownerDocument; $driver = Extension::load('field_textbox'); $driver->addPublishHeaders($document); $sortorder = $this->{'sortorder'}; $element_name = $this->{'element-name'}; $classes = array(); $label = Widget::Label(isset($this->{'publish-label'}) && strlen(trim($this->{'publish-label'})) > 0 ? $this->{'publish-label'} : $this->name); $optional = ''; if ($this->{'required'} != 'yes') { if ((int) $this->{'text-length'} > 0) { $optional = $document->createDocumentFragment(); $optional->appendChild($document->createTextNode(__('$1 of $2 remaining') . ' ')); $optional->appendChild($document->createEntityReference('ndash')); $optional->appendChild($document->createTextNode(' ' . __('Optional'))); } else { $optional = __('Optional'); } } else { if ((int) $this->{'text-length'} > 0) { $optional = __('$1 of $2 remaining'); } } if ($optional) { $label->appendChild($wrapper->ownerDocument->createElement('em', $optional)); } // Input box: if ($this->{'text-size'} == 'single') { $input = Widget::Input("fields[{$element_name}]", $data->value); ### # Delegate: ModifyTextBoxInlineFieldPublishWidget # Description: Allows developers modify the textbox before it is rendered in the publish forms $delegate = 'ModifyTextBoxInlineFieldPublishWidget'; } else { $input = Widget::Textarea("fields[{$element_name}]", $data->value, array('rows' => 20, 'cols' => 50)); ### # Delegate: ModifyTextBoxFullFieldPublishWidget # Description: Allows developers modify the textbox before it is rendered in the publish forms $delegate = 'ModifyTextBoxFullFieldPublishWidget'; } // Add classes: $classes[] = 'size-' . $this->{'text-size'}; if ($this->{'text-formatter'} != 'none') { $classes[] = $this->{'text-formatter'}; } $input->setAttribute('class', implode(' ', $classes)); $input->setAttribute('length', (int) $this->{'text-length'}); Extension::notify($delegate, '/administration/', array('field' => &$this, 'label' => &$label, 'input' => &$input)); if (is_null($label)) { return; } $label->appendChild($input); if ($errors->valid()) { $label = Widget::wrapFormElementWithError($label, $errors->current()->message); } $wrapper->appendChild($label); }
public function __actionEdit() { $callback = Administration::instance()->getPageCallback(); $entry_id = (int) $callback['context']['entry_id']; if (@array_key_exists('save', $_POST['action']) || @array_key_exists("done", $_POST['action'])) { $entry = Entry::loadFromID($entry_id); $post = General::getPostData(); $fields = array(); if (isset($post['fields']) and !empty($post['fields'])) { $fields = $post['fields']; } $entry->setFieldDataFromFormArray($fields); ### # Delegate: EntryPreEdit # Description: Just prior to editing of an Entry. Extension::notify('EntryPreEdit', '/publish/edit/', array('entry' => &$entry)); $this->errors->flush(); $status = Entry::save($entry, $this->errors); if ($status == Entry::STATUS_OK) { // Check if there is a field to prepopulate if (isset($_REQUEST['prepopulate']) && strlen(trim($_REQUEST['prepopulate'])) > 0) { $field_handle = key($_REQUEST['prepopulate']); $value = stripslashes(rawurldecode($_REQUEST['prepopulate'][$field_handle])); $prepopulate_filter = "?prepopulate[{$field_handle}]=" . rawurlencode($value); } else { $prepopulate_filter = null; } ### # Delegate: EntryPostEdit # Description: Editing an entry. Entry object is provided. Extension::notify('EntryPostEdit', '/publish/edit/', array('entry' => $entry)); ## WOOT redirect(sprintf('%s/symphony/publish/%s/edit/%d/:saved/%s', URL, $entry->section, $entry->id, $prepopulate_filter)); } // Oh dear $this->entry = $entry; $this->alerts()->append(__('An error occurred while processing this form. <a href="#error">See below for details.</a> <a class="more">Show a list of errors.</a>'), AlertStack::ERROR); return; } elseif (@array_key_exists('delete', $_POST['action']) && is_numeric($entry_id)) { $callback = Administration::instance()->getPageCallback(); ### # Delegate: Delete # Description: Prior to deleting an entry. Entry ID is provided, as an # array to remain compatible with other Delete delegate call Extension::notify('Delete', '/publish/', array('entry_id' => $entry_id)); Entry::delete($entry_id); redirect(ADMIN_URL . '/publish/' . $callback['context']['section_handle'] . '/'); } }
public function __actionEdit() { if (!($user_id = $this->_context[1])) { redirect(ADMIN_URL . '/system/users/'); } if (array_key_exists('save', $_POST['action']) || array_key_exists('done', $_POST['action'])) { $fields = $_POST['fields']; $this->user = User::load($user_id); $this->user->id = $user_id; $this->user->email = $fields['email']; $this->user->username = $fields['username']; $this->user->first_name = General::sanitize($fields['first_name']); $this->user->last_name = General::sanitize($fields['last_name']); if (trim($fields['password']) != '') { $this->user->password = md5($fields['password']); $changing_password = true; } $this->user->default_section = $fields['default_section']; $this->user->auth_token_active = $fields['auth_token_active'] ? $fields['auth_token_active'] : 'no'; $this->user->language = $fields['language']; ### # Delegate: UserPreSave # Description: Just before creation of a new User. User object, fields and error array provided Extension::notify('UserPreSave', '/system/users/edit/', array('fields' => $fields, 'user' => &$this->user, 'errors' => &$this->errors)); $this->user->validate($this->errors); if ($this->errors->length() == 0) { if (($fields['password'] != '' || $fields['password-confirmation'] != '') && $fields['password'] != $fields['password-confirmation']) { $this->errors->append('password', __('Passwords did not match')); $this->errors->append('password-confirmation', __('Passwords did not match')); } elseif (User::save($this->user)) { Symphony::Database()->delete('tbl_forgotpass', array(DateTimeObj::getGMT('c'), $user_id), " `expiry` < '%s' OR `user_id` = %d "); // This is the logged in user, so update their session if ($user_id == Administration::instance()->User->id) { Administration::instance()->login($this->user->username, $this->user->password, true); } ### # Delegate: PostSave # Description: Just after creation of a new User. The ID of the User is provided. Extension::notify('PostSave', '/system/users/edit/', array('user' => $this->user)); redirect(ADMIN_URL . "/system/users/edit/{$this->user->id}/:saved/"); } else { $this->alerts()->append(__('Unknown errors occurred while attempting to save. Please check your <a href="%s">activity log</a>.', array(ADMIN_URL . '/system/log/')), AlertStack::ERROR); } } else { $this->alerts()->append(__('There were some problems while attempting to save. Please check below for problem fields.'), AlertStack::ERROR, $this->errors); } } elseif (array_key_exists('delete', $_POST['action'])) { ## FIXME: Fix this delegate ### # Delegate: Delete # Description: Prior to deleting an User. ID is provided. //Extension::notify('Delete', getCurrentPage(), array('user_id' => $user_id)); User::delete($user_id); redirect(ADMIN_URL . '/system/users/'); } }
protected function appendSidebar(DOMElement $wrapper) { $container = $this->document->createElement('div'); $container->setAttribute('id', 'sidebar'); // Header: $header = $this->document->createElement('h1'); $header->appendChild(Widget::Anchor($this->view->title, (string) $this->url)); $container->appendChild($header); $list = $this->document->createElement('ul'); $list->setAttribute('class', 'menu'); $root = $this->document->createElement('navigation'); #### # Delegate: DevKiAppendtMenuItem # Description: Allow navigation XML to be manipulated before it is rendered. # Global: Yes #$this->_page->ExtensionManager->notifyMembers( Extension::notify('DevKiAppendtMenuItem', '/frontend/', array('wrapper' => $root)); if ($root->hasChildNodes()) { foreach ($root->childNodes as $node) { if ($node->getAttribute('active') == 'yes') { $item = $this->document->createElement('li', $node->getAttribute('name')); } else { $handle = $node->getAttribute('handle'); $url = clone $this->url; $url->parameters()->{$handle} = null; $item = $this->document->createElement('li'); $item->appendChild(Widget::Anchor($node->getAttribute('name'), '?' . (string) $url)); } $list->appendChild($item); } } $item = $this->document->createElement('li'); $item->appendChild(Widget::Anchor(__('Edit'), ADMIN_URL . '/blueprints/views/edit/' . $this->view->handle . '/')); $list->prependChild($item); $container->appendChild($list); // Main: $fieldset = Widget::Fieldset(__('Pages')); $container->appendChild($fieldset); $wrapper->appendChild($container); return $container; }
public function buildOutput() { $ParameterOutput = new Register(); $root = $this->document->documentElement; $this->buildContextXML($root); $datasources = $events = array(); $events_wrapper = $this->document->createElement('events'); $root->appendChild($events_wrapper); if (is_array($this->about()->{'events'}) && !empty($this->about()->{'events'})) { $events = $this->about()->{'events'}; } if (is_array($this->about()->{'data-sources'}) && !empty($this->about()->{'data-sources'})) { $datasources = $this->about()->{'data-sources'}; } #### # Delegate: FrontendEventsAppend # Description: Append additional Events. # Global: Yes Extension::notify('FrontendEventsAppend', '/frontend/', array('events' => &$events)); if (!empty($events)) { $postdata = General::getPostData(); $events_ordered = array(); foreach ($events as $handle) { $events_ordered[] = Event::loadFromHandle($handle); } uasort($events_ordered, array($this, '__cbSortEventsByPriority')); foreach ($events_ordered as $e) { if (!$e->canTrigger($postdata)) { continue; } $fragment = $e->trigger($ParameterOutput, $postdata); if ($fragment instanceof DOMDocument && !is_null($fragment->documentElement)) { $node = $this->document->importNode($fragment->documentElement, true); $events_wrapper->appendChild($node); } } } #### # Delegate: FrontendDataSourceAppend # Description: Append additional DataSources. # Global: Yes Extension::notify('FrontendDataSourcesAppend', '/frontend/', array('datasources' => &$datasources)); // Find dependancies and order accordingly $datasource_pool = array(); $dependency_list = array(); $datasources_ordered = array(); $all_dependencies = array(); foreach ($datasources as $handle) { $datasource_pool[$handle] = Datasource::loadFromHandle($handle); $dependency_list[$handle] = $datasource_pool[$handle]->parameters()->dependencies; } $datasources_ordered = General::dependenciesSort($dependency_list); $data = $this->document->createElement('data'); if (!empty($datasources_ordered)) { foreach ($datasources_ordered as $handle) { $ds = $datasource_pool[$handle]; try { $fragment = $ds->render($ParameterOutput); } catch (FrontendPageNotFoundException $e) { FrontendPageNotFoundExceptionHandler::render($e); } if ($fragment instanceof DOMDocument && !is_null($fragment->documentElement)) { $node = $this->document->importNode($fragment->documentElement, true); $data->appendChild($node); } } } $root->appendChild($data); /* if($ParameterOutput->length() > 0){ foreach($ParameterOutput as $p){ $Parameters->{$p->key} = $p->value; } } #### # Delegate: FrontendParamsPostResolve # Description: Access to the resolved param pool, including additional parameters provided by Data Source outputs # Global: Yes Extension::notify('FrontendParamsPostResolve', '/frontend/', array('params' => $Parameters)); #### # Delegate: FrontendTemplatePreRender # Description: Access to the template source, before it is rendered. # Global: Yes Extension::notify( 'FrontendTemplatePreRender', '/frontend/', array( 'document' => $Document, 'template' => &$template ) ); */ return $this->transform(); }