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()));
             }
         }
     }
 }
Example #4
0
 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);
     }
 }
Example #5
0
 public function getAuthorID()
 {
     return Symphony::Author()->get('id');
 }
Example #6
0
 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 &ndash; %2$s &ndash; %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 */'];
         }
     }
 }
Example #11
0
 /**
  * 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&amp;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);
 }
Example #14
0
 /**
  * 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;
     }
 }
Example #15
0
 public function __viewIndex()
 {
     $this->setPageType('form');
     $this->setTitle(__('Symphony') . ' &ndash; ' . __('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') . '/');
         }
     }
 }
Example #17
0
 /**
  * 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;
 }
Example #18
0
 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);
         }
     }
 }
Example #19
0
 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);
             }
         }
     }
 }