public function start() { if (!is_object($this->getTemplate())) { $this->setStatus('error-template'); return; } if (!is_object($this->getSender())) { $this->setStatus('error-sender'); return; } if (empty($this->_recipientgroups)) { $this->setStatus('error-recipients'); return; } // Never start if the newsletter is sending or completed if ($this->getStatus() == 'sending' || $this->getStatus() == 'completed') { return; } $this->generatePAuth(); Symphony::Database()->query("CREATE TABLE IF NOT EXISTS `tbl_tmp_email_newsletters_sent_" . $this->getId() . "` (\n `id` int(10) unsigned NOT NULL AUTO_INCREMENT,\n `email` varchar(255),\n `result` varchar(255),\n PRIMARY KEY (`id`),\n KEY `email` (`email`)\n ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;"); Symphony::Database()->query('DELETE FROM `tbl_tmp_email_newsletters_sent_' . $this->getId() . '` WHERE `result` = \'idle\''); $this->setStatus('sending'); $author_id = 0; if (Symphony::Engine() instanceof Administration) { $author_id = Symphony::Author()->get('id'); } elseif (Symphony::Engine() instanceof Frontend && Symphony::ExtensionManager()->fetchStatus('members') == EXTENSION_ENABLED) { $Members = Symphony::ExtensionManager()->create('members'); $author_id = $Members->getMemberDriver()->getMemberID(); } Symphony::Database()->update(array('started_on' => date('Y-m-d H:i:s', time()), 'started_by' => $author_id), 'tbl_email_newsletters', 'id = ' . $this->getId()); EmailBackgroundProcess::spawnProcess($this->getId(), $this->getPAuth()); }
protected function __trigger() { // Cookies only show up on page refresh. // This flag helps in making sure the correct XML is being set $loggedin = false; if (isset($_REQUEST['action']['login'])) { $username = $_REQUEST['username']; $password = $_REQUEST['password']; $loggedin = Frontend::instance()->login($username, $password); } else { $loggedin = Frontend::instance()->isLoggedIn(); } if ($loggedin) { $result = new XMLElement('login-info'); $result->setAttribute('logged-in', 'true'); $author = null; if (is_callable(array('Symphony', 'Author'))) { $author = Symphony::Author(); } else { $author = Frontend::instance()->Author; } $result->setAttributeArray(array('id' => $author->get('id'), 'user-type' => $author->get('user_type'), 'primary-account' => $author->get('primary'))); $fields = array('name' => new XMLElement('name', $author->getFullName()), 'username' => new XMLElement('username', $author->get('username')), 'email' => new XMLElement('email', $author->get('email'))); if ($author->isTokenActive()) { $fields['author-token'] = new XMLElement('author-token', $author->createAuthToken()); } // Section if ($section = Symphony::Database()->fetchRow(0, "SELECT `id`, `handle`, `name` FROM `tbl_sections` WHERE `id` = '" . $author->get('default_area') . "' LIMIT 1")) { $default_area = new XMLElement('default-area', $section['name']); $default_area->setAttributeArray(array('id' => $section['id'], 'handle' => $section['handle'], 'type' => 'section')); $fields['default-area'] = $default_area; } else { $default_area = new XMLElement('default-area', $author->get('default_area')); $default_area->setAttribute('type', 'page'); $fields['default-area'] = $default_area; } foreach ($fields as $f) { $result->appendChild($f); } } else { $result = new XMLElement('user'); $result->setAttribute('logged-in', 'false'); } // param output Frontend::Page()->_param['login'] = $loggedin ? 'yes' : 'no'; Frontend::Page()->_param['login-filter'] = $loggedin ? 'yes,no' : 'yes'; return $result; }
public function stopRestartNewsletter(&$context) { if (substr($_POST['action']['save'], 0, 12) == 'enm-restart:') { $vars = explode(":", $_POST['action']['save']); $field_id = $vars[1]; $entry_id = $context['entry']->get('id'); $data = $this->_getEntryData($field_id, $entry_id); if (!empty($data)) { try { $newsletter = EmailNewsletterManager::create($data['newsletter_id']); $array = array('template' => is_object($newsletter->getTemplate()) ? $newsletter->getTemplate()->getHandle() : NULL, 'sender' => is_object($newsletter->getSender()) ? $newsletter->getSender()->getHandle() : NULL, 'recipients' => implode(', ', $newsletter->getRecipientGroups(false, true))); $news = EmailNewsletterManager::save($array); $context['entry']->setData($field_id, array('author_id' => Symphony::Author()->get('id'), 'entry_id' => $entry_id, 'newsletter_id' => $news->getId())); //$news->start(); } catch (Exception $e) { Administration::instance()->throwCustomError(__('Error restarting email newsletter'), __($e->getMessage())); } } } if (substr($_POST['action']['save'], 0, 9) == 'enm-stop:') { $vars = explode(":", $_POST['action']['save']); $field_id = $vars[1]; $entry_id = $context['entry']->get('id'); $data = $this->_getEntryData($field_id, $entry_id); if (!empty($data)) { try { $newsletter = EmailNewsletterManager::create($data['newsletter_id']); $newsletter->stop(); } catch (Exception $e) { Administration::instance()->throwCustomError(__('Error stopping email newsletter'), __($e->getMessage())); } } } if (substr($_POST['action']['save'], 0, 10) == 'enm-pause:') { $vars = explode(":", $_POST['action']['save']); $field_id = $vars[1]; $entry_id = $context['entry']->get('id'); $data = $this->_getEntryData($field_id, $entry_id); if (!empty($data)) { try { $newsletter = EmailNewsletterManager::create($data['newsletter_id']); $newsletter->pause(); } catch (Exception $e) { Administration::instance()->throwCustomError(__('Error pausing email newsletter'), __($e->getMessage())); } } } }
public function appendAlert($context) { if (!is_null($context['alert'])) { return; } // https://github.com/symphonycms/symphony-2/wiki/Migration-Guide-to-2.5-for-Developers#properties if (is_callable(array('Symphony', 'Author'))) { $author = Symphony::Author(); } else { $author = Administration::instance()->Author; } if ($this->__filesNewer() && ($author instanceof Author && $author->isDeveloper()) ? true : false) { $files = implode(__(" and "), array_map('__', array_map('ucfirst', $this->__filesNewer()))); if (count($this->__filesNewer()) == 1) { $message = __('The database file for your %s is newer than your last sync. ', array($files)); } else { $message = __('The database files for both your %s is newer than your last sync. ', array($files)); } $message .= __('It\'s recommended to <a href="%s">sync your database now.</a>', array(URL . '/symphony/system/preferences/#dump-actions')); Administration::instance()->Page->pageAlert($message); } }
public function getAuthorID() { return Symphony::Author()->get('id'); }
public function view() { if (isset($this->_context[0]) && in_array(strlen($this->_context[0]), array(6, 8, 16))) { if (!$this->__loginFromToken($this->_context[0])) { if (Administration::instance()->isLoggedIn()) { // Redirect to the Author's profile. RE: #1801 redirect(SYMPHONY_URL . '/system/authors/edit/' . Symphony::Author()->get('id') . '/reset-password/'); } } } $this->Form = Widget::Form(SYMPHONY_URL . '/login/', 'post'); $this->Form->setAttribute('class', 'frame'); $this->Form->appendChild(new XMLElement('h1', Symphony::Configuration()->get('sitename', 'general'))); $fieldset = new XMLElement('fieldset'); // Display retrieve password UI if (isset($this->_context[0]) && $this->_context[0] == 'retrieve-password') { $this->Form->setAttribute('action', SYMPHONY_URL . '/login/retrieve-password/'); // Successful reset if (isset($this->_email_sent) && $this->_email_sent) { $fieldset->appendChild(new XMLElement('p', __('An email containing a customised login link has been sent to %s. It will expire in 2 hours.', array('<code>' . $this->_email_sent_to . '</code>')))); $fieldset->appendChild(new XMLElement('p', Widget::Anchor(__('Login'), SYMPHONY_URL . '/login/', null))); $this->Form->appendChild($fieldset); // Default, get the email address for reset } else { $fieldset->appendChild(new XMLElement('p', __('Enter your email address or username to be sent further instructions for logging in.'))); $label = Widget::Label(__('Email Address or Username')); $label->appendChild(Widget::Input('email', General::sanitize($_POST['email']), 'text', array('autofocus' => 'autofocus'))); if (isset($this->_email_sent) && !$this->_email_sent) { $label = Widget::Error($label, __('Unfortunately no account was found using this information.')); } else { // Email exception if (isset($this->_email_error) && $this->_email_error) { $label = Widget::Error($label, __('This Symphony instance has not been set up for emailing, %s', array('<code>' . $this->_email_error . '</code>'))); } } $fieldset->appendChild($label); $this->Form->appendChild($fieldset); $div = new XMLElement('div', null, array('class' => 'actions')); $div->appendChild(new XMLElement('button', __('Send Email'), array('name' => 'action[reset]', 'type' => 'submit', 'accesskey' => 's'))); $div->appendChild(Widget::Anchor(__('Cancel'), SYMPHONY_URL . '/login/', null, 'action-link')); $this->Form->appendChild($div); } // Normal login } else { $fieldset->appendChild(new XMLElement('legend', __('Login'), array('role' => 'heading'))); // Display error message if ($this->failedLoginAttempt) { $p = new XMLElement('p'); $p = Widget::Error($p, __('The login details provided are incorrect.')); $fieldset->appendChild($p); } // Username $label = Widget::Label(__('Username')); $username = Widget::Input('username', isset($_POST['username']) ? General::sanitize($_POST['username']) : null); if (!$this->failedLoginAttempt) { $username->setAttribute('autofocus', 'autofocus'); } $label->appendChild($username); if (isset($_POST['action'], $_POST['action']['login']) && empty($_POST['username'])) { $username->setAttribute('autofocus', 'autofocus'); $label = Widget::Error($label, __('No username was entered.')); } $fieldset->appendChild($label); // Password $label = Widget::Label(__('Password')); $password = Widget::Input('password', null, 'password'); $label->appendChild($password); if (isset($_POST['action'], $_POST['action']['login']) && empty($_POST['password'])) { $password->setAttribute('autofocus', 'autofocus'); $label = Widget::Error($label, __('No password was entered.')); } elseif ($this->failedLoginAttempt) { $password->setAttribute('autofocus', 'autofocus'); } $fieldset->appendChild($label); $this->Form->appendChild($fieldset); // Actions $div = new XMLElement('div', null, array('class' => 'actions')); $div->appendChild(new XMLElement('button', __('Login'), array('name' => 'action[login]', 'type' => 'submit', 'accesskey' => 'l'))); $div->appendChild(Widget::Anchor(__('Retrieve password?'), SYMPHONY_URL . '/login/retrieve-password/', null, 'action-link')); $this->Form->appendChild($div); if (isset($this->_context['redirect'])) { $this->Form->appendChild(Widget::Input('redirect', SYMPHONY_URL . General::sanitize($this->_context['redirect']), 'hidden')); } } $this->Body->appendChild($this->Form); }
/** * This function determines whether an administrative alert can be * displayed on the current page. It ensures that the page exists, * and the user is logged in and a developer * * @since Symphony 2.2 * @return boolean */ private function __canAccessAlerts() { if ($this->Page instanceof AdministrationPage && $this->isLoggedIn() && Symphony::Author()->isDeveloper()) { return true; } return false; }
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 __viewEdit() { if (!($section_id = SectionManager::fetchIDFromHandle($this->_context['section_handle']))) { Administration::instance()->throwCustomError(__('The Section, %s, could not be found.', array('<code>' . $this->_context['section_handle'] . '</code>')), __('Unknown Section'), Page::HTTP_STATUS_NOT_FOUND); } $section = SectionManager::fetch($section_id); $entry_id = intval($this->_context['entry_id']); $base = '/publish/' . $this->_context['section_handle'] . '/'; $new_link = $base . 'new/'; $filter_link = $base; EntryManager::setFetchSorting('id', 'DESC'); if (!($existingEntry = EntryManager::fetch($entry_id))) { Administration::instance()->throwCustomError(__('Unknown Entry'), __('The Entry, %s, could not be found.', array($entry_id)), Page::HTTP_STATUS_NOT_FOUND); } $existingEntry = $existingEntry[0]; // If there is post data floating around, due to errors, create an entry object if (isset($_POST['fields'])) { $fields = $_POST['fields']; $entry = EntryManager::create(); $entry->set('id', $entry_id); $entry->set('author_id', $existingEntry->get('author_id')); $entry->set('section_id', $existingEntry->get('section_id')); $entry->set('creation_date', $existingEntry->get('creation_date')); $entry->set('modification_date', $existingEntry->get('modification_date')); $entry->setDataFromPost($fields, $errors, true); // Editing an entry, so need to create some various objects } else { $entry = $existingEntry; $fields = array(); if (!$section) { $section = SectionManager::fetch($entry->get('section_id')); } } /** * Just prior to rendering of an Entry edit form. * * @delegate EntryPreRender * @param string $context * '/publish/edit/' * @param Section $section * @param Entry $entry * @param array $fields */ Symphony::ExtensionManager()->notifyMembers('EntryPreRender', '/publish/edit/', array('section' => $section, 'entry' => &$entry, 'fields' => $fields)); // Iterate over the `prepopulate` parameters to build a URL // to remember this state for Create New, View all Entries and // Breadcrumb links. If `prepopulate` doesn't exist, this will // just use the standard pages (ie. no filtering) if (isset($_REQUEST['prepopulate'])) { $new_link .= $this->getPrepopulateString(); $filter_link .= $this->getFilterString(); } if (isset($this->_context['flag'])) { // These flags are only relevant if there are no errors if (empty($this->_errors)) { $time = Widget::Time(); switch ($this->_context['flag']) { case 'saved': $message = __('Entry updated at %s.', array($time->generate())); break; case 'created': $message = __('Entry created at %s.', array($time->generate())); } $this->pageAlert($message . ' <a href="' . SYMPHONY_URL . $new_link . '" accesskey="c">' . __('Create another?') . '</a> <a href="' . SYMPHONY_URL . $filter_link . '" accesskey="a">' . __('View all Entries') . '</a>', Alert::SUCCESS); } } // Determine the page title $field_id = Symphony::Database()->fetchVar('id', 0, sprintf("\n SELECT `id`\n FROM `tbl_fields`\n WHERE `parent_section` = %d\n ORDER BY `sortorder` LIMIT 1", $section->get('id'))); if (!is_null($field_id)) { $field = FieldManager::fetch($field_id); } if ($field) { $title = $field->prepareReadableValue($existingEntry->getData($field->get('id')), $entry_id, true); } else { $title = ''; } if (trim($title) == '') { $title = __('Untitled'); } // Check if there is a field to prepopulate if (isset($_REQUEST['prepopulate'])) { foreach ($_REQUEST['prepopulate'] as $field_id => $value) { $this->Form->prependChild(Widget::Input("prepopulate[{$field_id}]", rawurlencode($value), 'hidden')); } } $this->setPageType('form'); $this->Form->setAttribute('enctype', 'multipart/form-data'); $this->setTitle(__('%1$s – %2$s – %3$s', array($title, $section->get('name'), __('Symphony')))); $sidebar_fields = $section->fetchFields(null, 'sidebar'); $main_fields = $section->fetchFields(null, 'main'); if (!empty($sidebar_fields) && !empty($main_fields)) { $this->Form->setAttribute('class', 'two columns'); } else { $this->Form->setAttribute('class', 'columns'); } // Only show the Edit Section button if the Author is a developer. #938 ^BA if (Symphony::Author()->isDeveloper()) { $this->appendSubheading($title, Widget::Anchor(__('Edit Section'), SYMPHONY_URL . '/blueprints/sections/edit/' . $section_id . '/', __('Edit Section Configuration'), 'button')); } else { $this->appendSubheading($title); } $this->insertBreadcrumbs(array(Widget::Anchor($section->get('name'), SYMPHONY_URL . (isset($filter_link) ? $filter_link : $base)))); $this->Form->appendChild(Widget::Input('MAX_FILE_SIZE', Symphony::Configuration()->get('max_upload_size', 'admin'), 'hidden')); $primary = new XMLElement('fieldset'); $primary->setAttribute('class', 'primary column'); if ((!is_array($main_fields) || empty($main_fields)) && (!is_array($sidebar_fields) || empty($sidebar_fields))) { $message = __('Fields must be added to this section before an entry can be created.'); if (Symphony::Author()->isDeveloper()) { $message .= ' <a href="' . SYMPHONY_URL . '/blueprints/sections/edit/' . $section->get('id') . '/" accesskey="c">' . __('Add fields') . '</a>'; } $this->pageAlert($message, Alert::ERROR); } else { if (is_array($main_fields) && !empty($main_fields)) { foreach ($main_fields as $field) { $primary->appendChild($this->__wrapFieldWithDiv($field, $entry)); } $this->Form->appendChild($primary); } if (is_array($sidebar_fields) && !empty($sidebar_fields)) { $sidebar = new XMLElement('fieldset'); $sidebar->setAttribute('class', 'secondary column'); foreach ($sidebar_fields as $field) { $sidebar->appendChild($this->__wrapFieldWithDiv($field, $entry)); } $this->Form->appendChild($sidebar); } $div = new XMLElement('div'); $div->setAttribute('class', 'actions'); $div->appendChild(Widget::Input('action[save]', __('Save Changes'), 'submit', array('accesskey' => 's'))); $button = new XMLElement('button', __('Delete')); $button->setAttributeArray(array('name' => 'action[delete]', 'class' => 'button confirm delete', 'title' => __('Delete this entry'), 'type' => 'submit', 'accesskey' => 'd', 'data-message' => __('Are you sure you want to delete this entry?'))); $div->appendChild($button); $this->Form->appendChild($div); // Create a Drawer for Associated Sections $this->prepareAssociationsDrawer($section); } }
public function save() { $about = array(); if ($this->_context[0] && !is_object($this->formatter)) { $this->formatter = TextformatterManager::create($this->_context[0]); } if (is_object($this->formatter)) { $about = TextformatterManager::about($this->_context[0]); } $fields = $_POST['fields']; $driverAbout = ExtensionManager::about('templatedtextformatters'); $types = $this->_driver->listTypes(); if (strlen(trim($fields['name'])) < 1) { $this->_errors['name'] = __('You have to specify name for text formatter'); return; } if ($about['templatedtextformatters-type'] && $about['templatedtextformatters-type'] != $fields['type']) { $this->_errors['type'] = __('Changing type of already existing formatter is not allowed'); return; } if (!$fields['type'] || !is_array($types[$fields['type']]) || !isset($types[$fields['type']]['path'])) { $this->_errors['type'] = __('There is no <code>%s</code> type available', array($fields['type'])); return; } $tplfile = $types[$fields['type']]['path'] . '/formatter.' . $fields['type'] . '.tpl'; if (!@is_file($tplfile)) { $this->_errors['type'] = __('Wrong type of text formatter'); return; } $classname = 'ttf_' . Lang::createHandle(trim($fields['name']), NULL, '_', false, true, array('@^[^a-z]+@i' => '', '/[^\\w-\\.]/i' => '')); $file = TEXTFORMATTERS . '/formatter.' . $classname . '.php'; $isDuplicate = false; $queueForDeletion = NULL; if (!$about['handle'] && @is_file($file)) { $isDuplicate = true; } else { if ($about['handle']) { if ($classname != $about['handle'] && @is_file($file)) { $isDuplicate = true; } elseif ($classname != $about['handle']) { $queueForDeletion = TEXTFORMATTERS . '/formatter.' . $about['handle'] . '.php'; } } } // Duplicate if ($isDuplicate) { $this->_errors['name'] = __('Text formatter with the name <code>%s</code> already exists', array($classname)); } if (!empty($this->_errors)) { return; } $description = trim($fields['description']); if (empty($description)) { $description = __('N/A'); } // https://github.com/symphonycms/symphony-2/wiki/Migration-Guide-to-2.5-for-Developers#properties if (is_callable(array('Symphony', 'Author'))) { $author = Symphony::Author(); } else { $author = Administration::instance()->Author; } $tokens = array('___' . $fields['type'] . '/* CLASS NAME */' => $classname, '/* NAME */' => preg_replace('/[^\\w\\s\\.-_\\&\\;]/i', '', trim($fields['name'])), '/* AUTHOR NAME */' => self::cleanupString($author->getFullName()), '/* AUTHOR WEBSITE */' => self::cleanupString(URL), '/* AUTHOR EMAIL */' => self::cleanupString($author->get('email')), '/* RELEASE DATE */' => DateTimeObj::getGMT('c'), '/* DESCRIPTION */' => self::cleanupString($description), '/* TEMPLATEDTEXTFORMATTERS VERSION */' => $driverAbout['version'], '/* TEMPLATEDTEXTFORMATTERS TYPE */' => $fields['type']); if (!is_object($this->formatter)) { include_once $tplfile; $temp = 'formatter___' . $fields['type']; $temp = new $temp(); if (method_exists($temp, 'ttf_tokens')) { $tokens = array_merge($tokens, $temp->ttf_tokens()); } } else { if (method_exists($this->formatter, 'ttf_tokens')) { $tokens = array_merge($tokens, $this->formatter->ttf_tokens()); } } $ttfShell = file_get_contents($tplfile); $ttfShell = str_replace(array_keys($tokens), $tokens, $ttfShell); $ttfShell = str_replace('/* CLASS NAME */', $classname, $ttfShell); // Write the file if (!is_writable(dirname($file)) || !($write = General::writeFile($file, $ttfShell, Symphony::Configuration()->get('write_mode', 'file')))) { $this->pageAlert(__('Failed to write Text Formatter source to <code>%s</code>. Please check permissions.', array($file)), Alert::ERROR); } else { if ($queueForDeletion || !$about['name']) { if ($queueForDeletion) { General::deleteFile($queueForDeletion); } // TODO: Find a way to make formatted fields update their content $_SESSION['templatedtextformatters-alert'] = 'created'; redirect(URL . '/symphony/extension/templatedtextformatters/edit/' . $classname); } else { // Update current data $_SESSION['templatedtextformatters-alert'] = 'saved'; $_POST['fields']['name'] = $tokens['/* NAME */']; $_POST['fields']['description'] = $tokens['/* DESCRIPTION */']; } } }
/** * Append notice that the site is currently in maintenance mode offering a link * to switch to live mode if no other alert is set. * * @param array $context * delegate context */ public function __appendAlert($context) { $author = null; if (is_callable(array('Symphony', 'Author'))) { $author = Symphony::Author(); } else { $author = Administration::instance()->Author; } // Site in maintenance mode if (Symphony::Configuration()->get('enabled', 'maintenance_mode') == 'yes') { if ($author != null && $author->isDeveloper()) { Administration::instance()->Page->pageAlert(__('This site is currently in maintenance mode.') . ' <a href="' . SYMPHONY_URL . '/system/preferences/?action=toggle-maintenance-mode&redirect=' . getCurrentPage() . '">' . __('Restore?') . '</a>', Alert::NOTICE); } else { Administration::instance()->Page->pageAlert(__('This site is currently in maintenance mode.'), Alert::NOTICE); } } }
/** * Prepares field values for database. */ public function processRawFieldData($data, &$status, &$message = NULL, $simulate = false, $entry_id = NULL) { $status = self::__OK__; if (empty($data)) { return NULL; } $entry_data = array(); if ($entry_id) { // grab existing entry data $entry_data = Symphony::Database()->fetchRow(0, sprintf("SELECT *\n FROM `tbl_entries_data_%d`\n WHERE `entry_id` = %d\n LIMIT 1", $this->get('id'), $entry_id)); } if (!is_array($data['recipient_groups'])) { $data['recipient_groups'] = array(); } // Prevent DOM hacking: When saving newsletter data, we __must__ // check if properties are valid (i.e. configured in the section // editor); otherwise it would be super-simple to send with // unwanted or invalid properties; $template = NULL; if (in_array($data['template'], explode(',', $this->get('templates')))) { $template = $data['template']; } $sender = NULL; if (in_array($data['sender'], explode(',', $this->get('senders')))) { $sender = $data['sender']; } $recipient_groups = array(); foreach ($data['recipient_groups'] as $group) { if (in_array($group, explode(',', $this->get('recipient_groups')))) { $recipient_groups[] = $group; } } // save $author_id = 0; if (Symphony::Engine() instanceof Administration) { $author_id = Symphony::Author()->get('id'); } elseif (Symphony::Engine() instanceof Frontend && Symphony::ExtensionManager()->fetchStatus('members') == EXTENSION_ENABLED) { $Members = Symphony::ExtensionManager()->create('members'); $author_id = $Members->getMemberDriver()->getMemberID(); } $newsletter = EmailNewsletterManager::save(array('id' => $entry_data['newsletter_id'], 'template' => $template, 'recipients' => implode(', ', $recipient_groups), 'sender' => $sender, 'pseudo_root' => URL)); $result = array('author_id' => $author_id, 'newsletter_id' => $newsletter->getId()); return $result; }
/** * Creates the Symphony footer for an Administration page. By default * this includes the installed Symphony version and the currently logged * in Author. A delegate is provided to allow extensions to manipulate the * footer HTML, which is an XMLElement of a `<ul>` element. * Since Symphony 2.3, it no longer uses the `AddElementToFooter` delegate. */ public function appendUserLinks() { $ul = new XMLElement('ul', null, array('id' => 'session')); $li = new XMLElement('li'); $li->appendChild(Widget::Anchor(Symphony::Author()->getFullName(), SYMPHONY_URL . '/system/authors/edit/' . Symphony::Author()->get('id') . '/')); $ul->appendChild($li); $li = new XMLElement('li'); $li->appendChild(Widget::Anchor(__('Log out'), SYMPHONY_URL . '/logout/', null, null, null, array('accesskey' => 'l'))); $ul->appendChild($li); $this->Header->appendChild($ul); }
/** * This function determines whether an there is a currently logged in * Author for Symphony by using the `$Cookie`'s username * and password. If an Author is found, they will be logged in, otherwise * the `$Cookie` will be destroyed. * * @see core.Cookie#expire() */ public static function isLoggedIn() { // Ensures that we're in the real world.. Also reduces three queries from database // We must return true otherwise exceptions are not shown if (is_null(self::$_instance)) { return true; } if (self::$Author) { return true; } else { $username = self::Database()->cleanValue(self::$Cookie->get('username')); $password = self::Database()->cleanValue(self::$Cookie->get('pass')); if (strlen(trim($username)) > 0 && strlen(trim($password)) > 0) { $author = AuthorManager::fetch('id', 'ASC', 1, null, sprintf("`username` = '%s'", $username)); if (!empty($author) && Cryptography::compare($password, current($author)->get('password'), true)) { self::$Author = current($author); self::Database()->update(array('last_seen' => DateTimeObj::get('Y-m-d H:i:s')), 'tbl_authors', sprintf(" `id` = %d", self::$Author->get('id'))); // Only set custom author language in the backend if (class_exists('Administration')) { Lang::set(self::$Author->get('language')); } return true; } } return false; } }
public function __viewIndex() { $this->setPageType('form'); $this->setTitle(__('Symphony') . ' – ' . __('Dashboard')); $this->addScriptToHead(URL . '/extensions/dashboard/assets/jquery-ui-1.11.4.custom.min.js', 29421); $this->addStylesheetToHead(URL . '/extensions/dashboard/assets/dashboard.index.css', 'screen', 29422); $this->addScriptToHead(URL . '/extensions/dashboard/assets/dashboard.index.js', 29423); // https://github.com/symphonycms/symphony-2/wiki/Migration-Guide-to-2.5-for-Developers#properties $author = null; if (is_callable(array('Symphony', 'Author'))) { $author = Symphony::Author(); } else { $author = Administration::instance()->Author; } // Add welcome message $hour = date('H'); $welcome = __('Nice to meet you'); if ($author->get('last_see') != NULL) { if ($hour < 10) { $welcome = __('Good morning'); } elseif ($hour < 17) { $welcome = __('Welcome back'); } else { $welcome = __('Good evening'); } } $panel_types = array(); /** * Ask panel extensions to list their panel types. * * @delegate DashboardPanelTypes * @param string $context * '/backend/' * @param array $types */ Symphony::ExtensionManager()->notifyMembers('DashboardPanelTypes', '/backend/', array('types' => &$panel_types)); if ($author->isDeveloper()) { $panel_types_options = array(array('', FALSE, __('New Panel'))); natsort($panel_types); foreach ($panel_types as $handle => $name) { $panel_types_options[] = array($handle, false, $name); } $actions = array(); $actions[] = Widget::Select('panel-type', $panel_types_options); $actions[] = Widget::Anchor(__('Enable Editing'), '#', __('Disable Editing'), 'edit-mode button'); } $this->Form->setAttribute('class', 'two columns'); $this->appendSubheading($welcome . ', ' . $author->get('first_name'), $actions); $this->insertDrawer(Widget::Drawer('dashboard', 'Dashboard', new XMLElement('span', ''), 'closed', time()), 'horizontal', FALSE); $container = new XMLElement('div', NULL, array('id' => 'dashboard')); $primary = new XMLElement('div', NULL, array('class' => 'primary column sortable-container')); $secondary = new XMLElement('div', NULL, array('class' => 'secondary column sortable-container')); $panels = Extension_Dashboard::getPanels(); foreach ($panels as $p) { $html = Extension_Dashboard::buildPanelHTML($p); switch ($p['placement']) { case 'primary': $primary->appendChild($html); break; case 'secondary': $secondary->appendChild($html); break; } } $container->appendChild($primary); $container->appendChild($secondary); $this->Form->appendChild($container); }
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') . '/'); } } }
/** * Symphony allows Authors to login via the use of tokens instead of * a username and password. A token is derived from concatenating the * Author's username and password and applying the sha1 hash to * it, from this, a portion of the hash is used as the token. This is a useful * feature often used when setting up other Authors accounts or if an * Author forgets their password. * * @param string $token * The Author token, which is a portion of the hashed string concatenation * of the Author's username and password * @throws DatabaseException * @return boolean * True if the Author is logged in, false otherwise */ public static function loginFromToken($token) { $token = self::Database()->cleanValue($token); if (strlen(trim($token)) == 0) { return false; } if (strlen($token) == 6 || strlen($token) == 16) { $row = self::Database()->fetchRow(0, sprintf("SELECT `a`.`id`, `a`.`username`, `a`.`password`\n FROM `tbl_authors` AS `a`, `tbl_forgotpass` AS `f`\n WHERE `a`.`id` = `f`.`author_id`\n AND `f`.`expiry` > '%s'\n AND `f`.`token` = '%s'\n LIMIT 1", DateTimeObj::getGMT('c'), $token)); self::Database()->delete('tbl_forgotpass', sprintf(" `token` = '%s' ", $token)); } else { $row = self::Database()->fetchRow(0, sprintf("SELECT `id`, `username`, `password`\n FROM `tbl_authors`\n WHERE SUBSTR(%s(CONCAT(`username`, `password`)), 1, 8) = '%s'\n AND `auth_token_active` = 'yes'\n LIMIT 1", 'SHA1', $token)); } if ($row) { self::$Author = AuthorManager::fetchByID($row['id']); self::$Cookie->set('username', $row['username']); self::$Cookie->set('pass', $row['password']); self::Database()->update(array('last_seen' => DateTimeObj::getGMT('Y-m-d H:i:s')), 'tbl_authors', sprintf("\n `id` = %d", $row['id'])); return true; } return false; }
public function __actionEdit() { if (!($author_id = (int) $this->_context[1])) { redirect(SYMPHONY_URL . '/system/authors/'); } $isOwner = $author_id == Symphony::Author()->get('id'); if (@array_key_exists('save', $_POST['action']) || @array_key_exists('done', $_POST['action'])) { $fields = $_POST['fields']; $this->_Author = AuthorManager::fetchByID($author_id); $authenticated = false; if ($fields['email'] != $this->_Author->get('email')) { $changing_email = true; } // Check the old password was correct if (isset($fields['old-password']) && strlen(trim($fields['old-password'])) > 0 && Cryptography::compare(Symphony::Database()->cleanValue(trim($fields['old-password'])), $this->_Author->get('password'))) { $authenticated = true; // Developers don't need to specify the old password, unless it's their own account } elseif ($isOwner || Symphony::Author()->isManager() && $this->_Author->isAuthor() || Symphony::Author()->isPrimaryAccount() || Symphony::Author()->isDeveloper() && $this->_Author->isPrimaryAccount() === false) { $authenticated = true; } $this->_Author->set('id', $author_id); if ($this->_Author->isPrimaryAccount() || $isOwner && Symphony::Author()->isDeveloper()) { $this->_Author->set('user_type', 'developer'); // Primary accounts are always developer, Developers can't lower their level } elseif ((Symphony::Author()->isDeveloper() || Symphony::Author()->isManager()) && isset($fields['user_type'])) { $this->_Author->set('user_type', $fields['user_type']); // Only developer can change user type } $this->_Author->set('email', $fields['email']); $this->_Author->set('username', General::sanitize($fields['username'])); $this->_Author->set('first_name', General::sanitize($fields['first_name'])); $this->_Author->set('last_name', General::sanitize($fields['last_name'])); $this->_Author->set('language', isset($fields['language']) ? $fields['language'] : null); if (trim($fields['password']) != '') { $this->_Author->set('password', Cryptography::hash(Symphony::Database()->cleanValue($fields['password']))); $changing_password = true; } // Don't allow authors to set the Section Index as a default area // If they had it previously set, just save `null` which will redirect // the Author (when logging in) to their own Author record if ($this->_Author->get('user_type') == 'author' && $fields['default_area'] == '/blueprints/sections/') { $this->_Author->set('default_area', null); } else { $this->_Author->set('default_area', $fields['default_area']); } $this->_Author->set('auth_token_active', $fields['auth_token_active'] ? $fields['auth_token_active'] : 'no'); if ($this->_Author->validate($this->_errors)) { // Admin changing another profile if (!$isOwner) { $entered_password = Symphony::Database()->cleanValue($fields['confirm-change-password']); if (!isset($fields['confirm-change-password']) || empty($fields['confirm-change-password'])) { $this->_errors['confirm-change-password'] = __('Please provide your own password to make changes to this author.'); } elseif (Cryptography::compare($entered_password, Symphony::Author()->get('password')) !== true) { $this->_errors['confirm-change-password'] = __('Wrong password, please enter your own password to make changes to this author.'); } } // Author is changing their password if (!$authenticated && ($changing_password || $changing_email)) { if ($changing_password) { $this->_errors['old-password'] = __('Wrong password. Enter old password to change it.'); } elseif ($changing_email) { $this->_errors['old-password'] = __('Wrong password. Enter old one to change email address.'); } // Passwords provided, but doesn't match. } elseif (($fields['password'] != '' || $fields['password-confirmation'] != '') && $fields['password'] != $fields['password-confirmation']) { $this->_errors['password'] = $this->_errors['password-confirmation'] = __('Passwords did not match'); } // All good, let's save the Author if (is_array($this->_errors) && empty($this->_errors) && $this->_Author->commit()) { Symphony::Database()->delete('tbl_forgotpass', sprintf("\n `expiry` < '%s' OR `author_id` = %d", DateTimeObj::getGMT('c'), $author_id)); if ($isOwner) { Administration::instance()->login($this->_Author->get('username'), $this->_Author->get('password'), true); } /** * After editing an author, provided with the Author object * * @delegate AuthorPostEdit * @since Symphony 2.2 * @param string $context * '/system/authors/' * @param Author $author * An Author object */ Symphony::ExtensionManager()->notifyMembers('AuthorPostEdit', '/system/authors/', array('author' => $this->_Author)); redirect(SYMPHONY_URL . '/system/authors/edit/' . $author_id . '/saved/'); // Problems. } else { $this->pageAlert(__('Unknown errors occurred while attempting to save.') . '<a href="' . SYMPHONY_URL . '/system/log/">' . __('Check your activity log') . '</a>.', Alert::ERROR); } } // Author doesn't have valid data, throw back. if (is_array($this->_errors) && !empty($this->_errors)) { $this->pageAlert(__('There were some problems while attempting to save. Please check below for problem fields.'), Alert::ERROR); } } elseif (@array_key_exists('delete', $_POST['action'])) { /** * Prior to deleting an author, provided with the Author ID. * * @delegate AuthorPreDelete * @since Symphony 2.2 * @param string $context * '/system/authors/' * @param integer $author_id * The ID of Author ID that is about to be deleted */ Symphony::ExtensionManager()->notifyMembers('AuthorPreDelete', '/system/authors/', array('author_id' => $author_id)); if (!$isOwner) { AuthorManager::delete($author_id); redirect(SYMPHONY_URL . '/system/authors/'); } else { $this->pageAlert(__('You cannot remove yourself as you are the active Author.'), Alert::ERROR); } } }
public function displayPublishPanel(XMLElement &$wrapper, $data = null, $flagWithError = null, $fieldnamePrefix = null, $fieldnamePostfix = null, $entry_id = null) { $value = isset($data['author_id']) ? $data['author_id'] : null; if ($this->get('default_to_current_user') === 'yes' && empty($data) && empty($_POST)) { $value = array(Symphony::Author()->get('id')); } if (!is_array($value)) { $value = array($value); } $options = array(); if ($this->get('required') !== 'yes') { $options[] = array(null, false, null); } // Custom where to only show Authors based off the Author Types setting $types = $this->get('author_types'); if (!empty($types)) { $types = implode('","', $this->get('author_types')); $where = 'user_type IN ("' . $types . '")'; } $authors = AuthorManager::fetch('id', 'ASC', null, null, $where); $found = false; foreach ($authors as $a) { if (in_array($a->get('id'), $value)) { $found = true; } $options[] = array($a->get('id'), in_array($a->get('id'), $value), $a->getFullName()); } // Ensure the selected Author is included in the options (incase // the settings change after the original entry was created) if (!$found && !is_null($value)) { $authors = AuthorManager::fetchByID($value); foreach ($authors as $a) { $options[] = array($a->get('id'), in_array($a->get('id'), $value), $a->getFullName()); } } $fieldname = 'fields' . $fieldnamePrefix . '[' . $this->get('element_name') . ']' . $fieldnamePostfix; if ($this->get('allow_multiple_selection') === 'yes') { $fieldname .= '[]'; } $label = Widget::Label($this->get('label')); if ($this->get('required') !== 'yes') { $label->appendChild(new XMLElement('i', __('Optional'))); } $label->appendChild(Widget::Select($fieldname, $options, $this->get('allow_multiple_selection') === 'yes' ? array('multiple' => 'multiple') : null)); if ($flagWithError != null) { $wrapper->appendChild(Widget::Error($label, $flagWithError)); } else { $wrapper->appendChild($label); } }
/** * Insert action */ public function __actionInsert() { if (is_array($_POST['insert']) && isset($_POST['insert']['ip'])) { $ip = $_POST['insert']['ip']; // protection for not entering the users ip // since ip='' will become his ip if (ABF::instance()->isIPValid($ip)) { // temporary fix for getting the author $author = null; if (is_callable(array('Symphony', 'Author'))) { $author = Symphony::Author(); } else { $author = Administration::instance()->Author; } try { $author = $author->getFullName(); $ret = ABF::instance()->registerToList($this->_curColor, "Manual entry made by {$author}", $ip); if ($ret) { $this->pageAlert(__('IP added successfuly.'), Alert::SUCCESS); } else { throw new Exception(__('Could not save IP address.')); } } catch (Exception $e) { $this->pageAlert(__('Error') . ': ' . $e->getMessage(), Alert::ERROR); } } else { if (strlen($ip) > 0) { $this->pageAlert(__('Error: The given IP address, `%s`, is not valid', array($ip)), Alert::ERROR); } else { $this->pageAlert(__('Error: No IP address submitted'), Alert::ERROR); } } } }