Пример #1
0
 public function enable()
 {
     if (Symphony::ExtensionManager() instanceof ExtensionManager) {
         PLHDatasourceManager::editAllNavDssTo('PLH');
     }
     return true;
 }
Пример #2
0
 /**
  * Given a Member ID, return Member
  *
  * @param integer $member_id
  * @return Entry
  */
 public function fetchMemberFromID($member_id)
 {
     if (!Identity::$driver instanceof Extension) {
         Identity::$driver = Symphony::ExtensionManager()->create('members');
     }
     return Identity::$driver->getMemberDriver()->initialiseMemberObject($member_id);
 }
 function displayPublishPanel(&$wrapper, $data = NULL, $flagWithError = NULL, $fieldnamePrefix = NULL, $fieldnamePostfix = NULL)
 {
     $label = Widget::Label($this->get('label'));
     if ($this->get('required') != 'yes') {
         $label->appendChild(new XMLElement('i', __('Optional')));
     }
     $textarea = Widget::Textarea('fields' . $fieldnamePrefix . '[' . $this->get('element_name') . ']' . $fieldnamePostfix, $this->get('size'), '50', strlen($data['value']) != 0 ? General::sanitize($data['value']) : NULL);
     if ($this->get('formatter') != 'none') {
         $textarea->setAttribute('class', $this->get('formatter'));
     }
     /**
      * Allows developers modify the textarea before it is rendered in the publish forms
      * 
      * @delegate ModifyTextareaFieldPublishWidget
      * @param string $context
      * '/backend/'
      * @param Field $field
      * @param Widget $label
      * @param Widget $textarea
      */
     Symphony::ExtensionManager()->notifyMembers('ModifyTextareaFieldPublishWidget', '/backend/', array('field' => &$this, 'label' => &$label, 'textarea' => &$textarea));
     $label->appendChild($textarea);
     if ($flagWithError != NULL) {
         $wrapper->appendChild(Widget::wrapFormElementWithError($label, $flagWithError));
     } else {
         $wrapper->appendChild($label);
     }
 }
 public function view()
 {
     $name = General::sanitize($_REQUEST['name']);
     $section = General::sanitize($_REQUEST['section']);
     $filters = self::processFilters($_REQUEST['filters']);
     $rootelement = Lang::createHandle($name);
     $doc_parts = array();
     // Add Documentation (Success/Failure)
     $this->addEntrySuccessDoc($doc_parts, $rootelement, $filters);
     $this->addEntryFailureDoc($doc_parts, $rootelement, $filters);
     // Filters
     $this->addDefaultFiltersDoc($doc_parts, $rootelement, $filters);
     // Frontend Markup
     $this->addFrontendMarkupDoc($doc_parts, $rootelement, $section, $filters);
     $this->addSendMailFilterDoc($doc_parts, $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
      * @param string $rootelment
      *  The name of this event, as a handle.
      */
     Symphony::ExtensionManager()->notifyMembers('AppendEventFilterDocumentation', '/blueprints/events/', array('selected' => $filters, 'documentation' => &$doc_parts, 'rootelement' => $rootelement));
     $documentation = join(PHP_EOL, array_map(create_function('$x', 'return rtrim($x->generate(true, 4));'), $doc_parts));
     $documentation = str_replace('\'', '\\\'', $documentation);
     $documentation = '<fieldset id="event-documentation" class="settings"><legend>' . __('Documentation') . '</legend>' . $documentation . '</fieldset>';
     $this->_Result = $documentation;
 }
Пример #5
0
 public function __construct()
 {
     parent::__construct();
     $this->_name = 'S3 Upload';
     $this->_driver = Symphony::ExtensionManager()->create('s3upload_field');
     $this->S3 = new S3($this->_driver->getAmazonS3AccessKeyId(), $this->_driver->getAmazonS3SecretAccessKey());
 }
 public function listTypes()
 {
     static $result;
     if (is_array($result)) {
         return $result;
     }
     $extensions = Symphony::ExtensionManager()->listInstalledHandles();
     if (!is_array($extensions) || empty($extensions)) {
         return array();
     }
     $result = array();
     foreach ($extensions as $e) {
         $path = EXTENSIONS . "/{$e}/template";
         if (!is_dir($path)) {
             continue;
         }
         $structure = General::listStructure($path, '/^formatter.[\\w-]+.tpl$/', false, 'ASC', $path);
         if (is_array($structure['filelist']) && !empty($structure['filelist'])) {
             foreach ($structure['filelist'] as $t) {
                 $type = preg_replace(array('/^formatter./i', '/.tpl$/i'), '', $t);
                 $result[$type] = array('path' => $path);
             }
         }
     }
     return $result;
 }
 public function initialize($context)
 {
     $conf = Symphony::Configuration();
     $result = MobileDetector::detect();
     $cookie = $conf->get(self::CONF_COOKIE, self::CONF);
     $url = $conf->get(self::CONF_URL, self::CONF);
     $devices = $conf->get(self::CONF_DEVICES, self::CONF);
     if ($devices) {
         $devices = explode(', ', $devices);
     } else {
         $devices = array();
     }
     /**
      * Allows other extensions to override when and where a mobile device is redirected.
      *
      * @delegate MobileRedirection
      * @param string $context /frontend/
      * @param string $url
      * @param array $devices
      * @param MobileDetectorResults $result
      */
     Symphony::ExtensionManager()->notifyMembers('MobileRedirection', '/frontend/', array('url' => &$url, 'devices' => &$devices, 'result' => $result));
     // User is requesting mobile redirection be enabled:
     if (isset($_GET['is-mobile']) && isset($_SESSION[$cookie])) {
         unset($_SESSION[$cookie]);
     }
     // User is requesting mobile redirection be disabled:
     if (isset($_GET['not-mobile']) || isset($_SESSION[$cookie])) {
         // Not a mobile, this request only:
         if ($_GET['not-mobile'] == 'once') {
             return;
         }
         // Not a mobile permenantly:
         $_SESSION[$cookie] = 'yes';
         return;
     }
     $can_redirect = $url && $result->passed();
     // Device was not detected, stop.
     if ($devices) {
         $can_redirect = false;
         foreach ($devices as $name) {
             if (!isset($result->devices()->{$name})) {
                 continue;
             }
             if (!$result->devices()->{$name}->detected) {
                 continue;
             }
             $can_redirect = true;
             break;
         }
     }
     if ($can_redirect) {
         $current = $this->sanitizeUrl(getCurrentPage());
         $redirect = $this->sanitizeUrl($url);
         if ($redirect !== $current && strpos($current, $redirect) !== 0) {
             redirect($redirect);
         }
     }
 }
function renderer_json($mode)
{
    if (strtolower($mode) == 'administration') {
        throw new Lib\Exceptions\InvalidModeException('JSON Renderer launcher is only available on the frontend');
    }
    $renderer = Frontend::instance();
    // Check if we should enable exception debug information
    $exceptionDebugEnabled = Symphony::isLoggedIn();
    // Use the JSON exception and error handlers instead of the Symphony one.
    Lib\ExceptionHandler::initialise($exceptionDebugEnabled);
    Lib\ErrorHandler::initialise($exceptionDebugEnabled);
    // #1808
    if (isset($_SERVER['HTTP_MOD_REWRITE'])) {
        throw new Exception("mod_rewrite is required, however is not enabled.");
    }
    $output = $renderer->display(getCurrentPage());
    cleanup_session_cookies();
    if (in_array('JSON', Frontend::Page()->pageData()['type'])) {
        // Load the output into a SimpleXML Container and convert to JSON
        try {
            $xml = new SimpleXMLElement($output, LIBXML_NOCDATA);
            // Convert the XML to a plain array. This step is necessary as we cannot
            // use JSON_PRETTY_PRINT directly on a SimpleXMLElement object
            $outputArray = json_decode(json_encode($xml), true);
            // Get the transforer object ready. Other extensions will
            // add their transormations to this.
            $transformer = new Lib\Transformer();
            /**
             * Allow other extensions to add their own transformers
             */
            Symphony::ExtensionManager()->notifyMembers('APIFrameworkJSONRendererAppendTransformations', '/frontend/', ['transformer' => &$transformer]);
            // Apply transformations
            $outputArray = $transformer->run($outputArray);
            // Now put the array through a json_encode
            $output = json_encode($outputArray, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
        } catch (\Exception $e) {
            // This happened because the input was not valid XML. This could
            // occur for a few reasons, but there are two scenarios
            // we are interested in.
            // 1) This is a devkit page (profile, debug etc). We want the data
            //    to be passed through and displayed rather than converted into
            //    JSON. There is no easy way in Symphony to tell if a devkit has
            //    control over the page, so instead lets inspect the output for
            //    any signs a devkit is rendering the page.
            // 2) It is actually bad XML. In that case we need to let the error
            //    bubble through.
            // Currently the easiest method is to check for the devkit.min.css
            // in the output. This may fail in the furture if this file is
            // renamed or moved.
            if (!preg_match("@\\/symphony\\/assets\\/css\\/devkit.min.css@", $output)) {
                throw $e;
            }
        }
    }
    echo $output;
    return $renderer;
}
 public function __construct()
 {
     parent::__construct();
     $this->_name = __('Geocoding');
     $this->_driver = Symphony::ExtensionManager()->create('geocodingfield');
     // Set defaults:
     $this->set('show_column', 'yes');
     $this->set('hide', 'no');
 }
Пример #10
0
 public function __construct()
 {
     parent::__construct();
     // Validate request passes XSRF checks if extension is enabled.
     $status = Symphony::ExtensionManager()->fetchStatus(array("handle" => "xsrf_protection"));
     if (in_array(EXTENSION_ENABLED, $status) || in_array(EXTENSION_REQUIRES_UPDATE, $status)) {
         XSRF::validateRequest();
     }
 }
Пример #11
0
 public function __construct(&$parent)
 {
     parent::__construct($parent);
     $this->_required = true;
     $this->set('required', 'yes');
     if (!self::$driver instanceof Extension) {
         self::$driver = Symphony::ExtensionManager()->create('members');
     }
 }
Пример #12
0
 public function __construct(&$parent)
 {
     parent::__construct($parent);
     $this->_name = 'Bi-Link';
     $this->_required = true;
     $this->_driver = Symphony::ExtensionManager()->create('bilinkfield');
     // Set defaults:
     $this->set('show_column', 'yes');
 }
Пример #13
0
 /**
  * The constructor for Frontend calls the parent Symphony constructor.
  *
  * @see core.Symphony#__construct()
  * @deprecated The constructor creates backwards compatible references
  *  to `$this->Database`, `$this->ExtensionManager` and `$this->Configuration`
  *  that act as alias for `Symphony::Database()`, `Symphony::ExtensionManager()`
  *  and `Symphony::Configuration()`. These will be removed in the
  *  next Symphony release
  */
 protected function __construct()
 {
     parent::__construct();
     $this->_env = array();
     // Need this part for backwards compatiblity
     $this->Database = Symphony::Database();
     $this->Configuration = Symphony::Configuration();
     $this->ExtensionManager = Symphony::ExtensionManager();
 }
Пример #14
0
 /**
  *
  * Class constructor
  * @param object $parent
  * @param array $env
  * @param boolean $process_params
  */
 public function __construct(array $env = null, $process_params = true)
 {
     parent::__construct($env, $process_params);
     // detect if multilangual field AND language redirect is enabled
     $this->isMultiLangual = Symphony::ExtensionManager()->fetchStatus('page_lhandles') == EXTENSION_ENABLED && Symphony::ExtensionManager()->fetchStatus('language_redirect') == EXTENSION_ENABLED;
     // add a ref to the Language redirect
     if ($this->isMultiLangual) {
         require_once EXTENSIONS . '/language_redirect/lib/class.languageredirect.php';
     }
 }
Пример #15
0
    static function upgrade()
    {
        // [#702] Update to include Admin Path configuration
        if (version_compare(self::$existing_version, '2.4beta2', '<=')) {
            // Add missing config value for index view string length
            Symphony::Configuration()->set('cell_truncation_length', '75', 'symphony');
            // Add admin-path to configuration
            Symphony::Configuration()->set('admin-path', 'symphony', 'symphony');
        }
        // [#1626] Update all tables to be UTF-8 encoding/collation
        // @link https://gist.github.com/michael-e/5789168
        $tables = Symphony::Database()->fetch("SHOW TABLES");
        if (is_array($tables) && !empty($tables)) {
            foreach ($tables as $table) {
                $table = current($table);
                // If it's not a Symphony table, ignore it
                if (!preg_match('/^' . Symphony::Database()->getPrefix() . '/', $table)) {
                    continue;
                }
                Symphony::Database()->query(sprintf("ALTER TABLE `%s` CHARACTER SET utf8 COLLATE utf8_unicode_ci", $table));
                Symphony::Database()->query(sprintf("ALTER TABLE `%s` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci", $table));
            }
        }
        // [#1420] Change date field to be a varchar instead of an ENUM to support prepopulation
        try {
            Symphony::Database()->query('
					ALTER TABLE `tbl_fields_date`
					CHANGE `pre_populate` `pre_populate` varchar(80) COLLATE utf8_unicode_ci DEFAULT NULL;
				');
        } catch (Exception $ex) {
        }
        // [#1997] Add filtering column to the Sections table
        if (!Symphony::Database()->tableContainsField('tbl_sections', 'filter')) {
            Symphony::Database()->query("\n\t\t\t\t\tALTER TABLE `tbl_sections`\n\t\t\t\t\tADD `filter` enum('yes','no') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'yes';\n\t\t\t\t");
        }
        $installed_extensions = Symphony::ExtensionManager()->listInstalledHandles();
        if (in_array('publishfiltering', $installed_extensions)) {
            Symphony::ExtensionManager()->uninstall('publishfiltering');
            self::$publish_filtering_disabled = true;
        }
        // [#1874] XSRF/CRSF options
        if (version_compare(self::$existing_version, '2.4beta3', '<=')) {
            // How long should a XSRF token be valid
            Symphony::Configuration()->set('token_lifetime', '15 minutes', 'symphony');
            // Should the token be removed as soon as it has been used?
            Symphony::Configuration()->set('invalidate_tokens_on_request', false, 'symphony');
        }
        // [#1874] XSRF/CRSF options
        if (version_compare(self::$existing_version, '2.4RC1', '<=')) {
            // On update, disable XSRF for compatibility purposes
            Symphony::Configuration()->set('enable_xsrf', 'no', 'symphony');
        }
        // Update the version information
        return parent::upgrade();
    }
 public function view()
 {
     $sectionManager = new SectionManager(Administration::instance());
     $fieldManager = new FieldManager(Administration::instance());
     // Fetch sections & populate a dropdown with the available upload fields
     $section = $sectionManager->fetch($_GET['section']);
     foreach ($section->fetchFields() as $field) {
         if (!preg_match(Extension_BulkImporter::$supported_fields['upload'], $field->get('type'))) {
             continue;
         }
         $element = new XMLElement("field", General::sanitize($field->get('label')), array('id' => $field->get('id'), 'type' => $field->get('type')));
         $this->_Result->appendChild($element);
     }
     // Check to see if any Sections link to this using the Section Associations table
     $associations = Symphony::Database()->fetch(sprintf("\n\t\t\t\t\tSELECT\n\t\t\t\t\t\t`child_section_field_id`\n\t\t\t\t\tFROM\n\t\t\t\t\t\t`tbl_sections_association`\n\t\t\t\t\tWHERE\n\t\t\t\t\t\t`parent_section_id` = %d\n\t\t\t\t", Symphony::Database()->cleanValue($_GET['section'])));
     if (is_array($associations) && !empty($associations)) {
         foreach ($associations as $related_field) {
             $field = $fieldManager->fetch($related_field['child_section_field_id']);
             if (!preg_match(Extension_BulkImporter::$supported_fields['section'], $field->get('type'))) {
                 continue;
             }
             $element = new XMLElement("section", General::sanitize($field->get('label')), array('id' => $field->get('id'), 'type' => $field->get('type'), 'section' => $sectionManager->fetch($field->get('parent_section'))->get('name')));
             $this->_Result->appendChild($element);
         }
     }
     // Check for Subsection Manager
     if (Symphony::ExtensionManager()->fetchStatus('subsectionmanager') == EXTENSION_ENABLED) {
         $associations = Symphony::Database()->fetch(sprintf("\n\t\t\t\t\t\tSELECT\n\t\t\t\t\t\t\t`field_id`\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\t`tbl_fields_subsectionmanager`\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t`subsection_id` = %d\n\t\t\t\t\t", Symphony::Database()->cleanValue($_GET['section'])));
         if (is_array($associations) && !empty($associations)) {
             foreach ($associations as $related_field) {
                 $field = $fieldManager->fetch($related_field['field_id']);
                 if (!preg_match(Extension_BulkImporter::$supported_fields['section'], $field->get('type'))) {
                     continue;
                 }
                 $element = new XMLElement("section", General::sanitize($field->get('label')), array('id' => $field->get('id'), 'type' => $field->get('type'), 'section' => $sectionManager->fetch($field->get('parent_section'))->get('name')));
                 $this->_Result->appendChild($element);
             }
         }
     }
     // Check for BiLink
     if (Symphony::ExtensionManager()->fetchStatus('bilinkfield') == EXTENSION_ENABLED) {
         $associations = Symphony::Database()->fetch(sprintf("\n\t\t\t\t\t\tSELECT\n\t\t\t\t\t\t\t`field_id`\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\t`tbl_fields_bilink`\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t`linked_section_id` = %d\n\t\t\t\t\t", Symphony::Database()->cleanValue($_GET['section'])));
         if (is_array($associations) && !empty($associations)) {
             foreach ($associations as $related_field) {
                 $field = $fieldManager->fetch($related_field['field_id']);
                 if (!preg_match(Extension_BulkImporter::$supported_fields['section'], $field->get('type'))) {
                     continue;
                 }
                 $element = new XMLElement("section", General::sanitize($field->get('label')), array('id' => $field->get('id'), 'type' => $field->get('type'), 'section' => $sectionManager->fetch($field->get('parent_section'))->get('name')));
                 $this->_Result->appendChild($element);
             }
         }
     }
 }
 public function __construct(&$parent)
 {
     parent::__construct($parent);
     $this->_name = 'Brightcove Status';
     $this->_driver = Symphony::ExtensionManager()->create('brightcove');
     // Set defaults:
     $this->set('show_column', 'yes');
     $this->set('size', 'medium');
     $this->set('required', 'yes');
     $this->_sizes = array(array('single', false, __('Single Line')), array('small', false, __('Small Box')), array('medium', false, __('Medium Box')), array('large', false, __('Large Box')), array('huge', false, __('Huge Box')));
 }
Пример #18
0
 public function appendDocs($context)
 {
     $current_page_url = str_replace(SYMPHONY_URL, '', Administration::instance()->getCurrentPageURL());
     if (preg_match('/edit/', $current_page_url)) {
         $pos = strripos($current_page_url, '/edit/');
         $current_page_url = substr($current_page_url, 0, $pos + 6);
     }
     $pages = Symphony::Database()->fetch("\n\t\t\t\tSELECT\n\t\t\t\t\td.pages, d.id\n\t\t\t\tFROM\n\t\t\t\t\t`tbl_documentation` AS d\n\t\t\t\tORDER BY\n\t\t\t\t\td.pages ASC\n\t\t\t");
     foreach ($pages as $key => $value) {
         if (strstr($value['pages'], ',')) {
             $list = explode(',', $value['pages']);
             foreach ($list as $item) {
                 $pages[] = array('id' => $value['id'], 'page' => $item);
             }
             unset($pages[$key]);
         }
     }
     ###
     # Delegate: appendDocsPre
     # Description: Allow other extensions to add their own documentation page
     Symphony::ExtensionManager()->notifyMembers('appendDocsPre', '/backend/', array('pages' => &$pages));
     // Fetch documentation items
     $items = array();
     foreach ($pages as $page) {
         if (in_array($current_page_url, $page)) {
             if (isset($page['id'])) {
                 $items[] = Symphony::Database()->fetchRow(0, "\n\t\t\t\t\t\t\tSELECT\n\t\t\t\t\t\t\t\td.title, d.content_formatted\n\t\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\t\t`tbl_documentation` AS d\n  \t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t d.id = '{$page['id']}'\n\t\t\t\t\t\t\tLIMIT 1\n\t\t\t\t\t\t ");
             } else {
                 ###
                 # Delegate: appendDocsPost
                 # Description: Allows other extensions to insert documentation for the $current_page_url
                 Administration::instance()->ExtensionManager->notifyMembers('appendDocsPost', '/backend/', array('doc_item' => &$doc_items));
             }
         }
     }
     // Allows a page to have more then one documentation source
     if (!empty($items)) {
         // Generate documentation panel
         $docs = new XMLElement('div', NULL, array('id' => 'documenter-drawer'));
         foreach ($items as $item) {
             // Add title
             if (isset($item['title'])) {
                 $docs->appendChild(new XMLElement('h2', $item['title']));
             }
             // Add formatted help text
             $docs->appendChild(new XMLElement('div', $item['content_formatted'], array('class' => 'documenter-content')));
         }
         $button = Symphony::Configuration()->get('button-text', 'Documentation');
         $drawer = Widget::Drawer('documenter', $button != '' ? $button : __('Documentation'), $docs, 'closed');
         Administration::instance()->Page->insertDrawer($drawer, 'vertical-right');
     }
 }
 public function __construct()
 {
     $this->paths = array(WORKSPACE . '/xml-importers', EXTENSIONS . '/xmlimporter/xml-importers');
     $extensions = Symphony::ExtensionManager()->listInstalledHandles();
     if (is_array($extensions) and !empty($extensions)) {
         foreach ($extensions as $handle) {
             $path = EXTENSIONS . "/{$e}/xml-importers";
             if (is_dir($path)) {
                 $this->paths[] = $path;
             }
         }
     }
 }
Пример #20
0
 public function load()
 {
     $request = Request::createFromGlobals();
     // This ensures the composer autoloader for the framework is included
     Symphony::ExtensionManager()->create('api_framework');
     // Event controllor only responds to certain methods. GET is handled by the data sources
     if ($request->getMethod() == 'GET') {
         return;
     }
     if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
         $data = json_decode($request->getContent(), true, 512, JSON_BIGINT_AS_STRING);
         $request->request->replace(is_array($data) ? $data : []);
     }
     // #5 - Use the full page path to generate the controller class name
     // #7 - Use a PSR-4 folder structure and build the namespace accordingly
     $currentPagePath = trim(Frontend::instance()->Page()->Params()["current-path"], '/');
     $parts = array_map("ucfirst", preg_split("@\\/@", $currentPagePath));
     $controllerName = "Controller" . array_pop($parts);
     $controllerPath = implode($parts, "\\") . "\\";
     $controllerPath = sprintf("Symphony\\ApiFramework\\Controllers\\%s%s", ltrim($controllerPath, '\\'), $controllerName);
     // #6 - Check if the controller exists before trying to include it.
     // Throw an exception if it cannot be located.
     if (!class_exists($controllerPath)) {
         throw new Lib\Exceptions\ControllerNotFoundException($controllerPath);
     }
     $controller = new $controllerPath();
     // Make sure the controller extends the AbstractController class
     if (!$controller instanceof Lib\AbstractController) {
         throw new Lib\Exceptions\ControllerNotValidException("'{$controllerPath}' is not a valid controller. Check implementation conforms to Lib\\AbstractController.");
     }
     $method = strtolower($request->getMethod());
     if (!method_exists($controller, $method)) {
         throw new Lib\Exceptions\MethodNotAllowedException($request->getMethod());
     }
     $controller->execute();
     // Prepare the response.
     $response = new JsonResponse();
     $response->headers->set('Content-Type', 'application/json');
     $response = $controller->{$method}($request, $response);
     $response->send();
     exit;
 }
Пример #21
0
 function grab(&$param_pool = NULL)
 {
     $result = new XMLElement($this->dsParamROOTELEMENT);
     $current = $this->dsParamFILTERS['current'];
     if (!(bool) $current) {
         return $result;
     }
     $driver = Symphony::ExtensionManager()->getInstance('nestedcats');
     if (!is_numeric($current)) {
         $current = Symphony::Database()->fetchVar('id', 0, sprintf("SELECT `id` FROM `tbl_%s` WHERE `handle` = '%s' LIMIT 1", $driver->extension_handle, Mysql::cleanValue($current)));
     }
     $data = $driver->getPath($current);
     if (!is_array($data) || empty($data)) {
         return $result->appendChild(new XMLElement('error', __('None found')));
     }
     $path = new XMLElement('path');
     foreach ($data as $c) {
         $path->appendChild(new XMLElement('item', $c['title'], array('id' => $c['id'], 'handle' => $c['handle'], 'parent-id' => $c['parent'], 'level' => $c['level'])));
     }
     $result->appendChild($path);
     return $result;
 }
 public function view()
 {
     $this->setPageType('table');
     $this->setTitle(__('%1$s &ndash; %2$s', array(__('Templated Text Formatters'), __('Symphony'))));
     $this->appendSubheading(__('Templated Text Formatters'), Widget::Anchor(__('Create New'), URL . '/symphony/extension/templatedtextformatters/edit/', __('Create a new formatter'), 'create button', NULL, array('accesskey' => 'c')));
     $aTableHead = array(array(__('Name'), 'col'), array(__('Type'), 'col'), array(__('Description'), 'col'));
     $aTableBody = array();
     $formatters = $this->_driver->listAll();
     if (!is_array($formatters) || empty($formatters)) {
         $aTableBody = array(Widget::TableRow(array(Widget::TableData(__('None found.'), 'inactive', NULL, count($aTableHead))), 'odd'));
     } else {
         foreach ($formatters as $id => $data) {
             $formatter = TextformatterManager::create($id);
             $about = $formatter->about();
             $td1 = Widget::TableData(Widget::Anchor($about['name'], URL . "/symphony/extension/templatedtextformatters/edit/{$id}/", $about['name']));
             $td2 = Widget::TableData($about['templatedtextformatters-type']);
             $td3 = Widget::TableData(General::sanitize($about['description']));
             $td1->appendChild(Widget::Label(__('Select Text Formatter %s', array($about['name'])), null, 'accessible', null, array('for' => 'ttf-' . $id)));
             $td1->appendChild(Widget::Input('items[' . $id . ']', 'on', 'checkbox', array('id' => 'ttf-' . $id)));
             // Add a row to the body array, assigning each cell to the row
             $aTableBody[] = Widget::TableRow(array($td1, $td2, $td3));
         }
     }
     $table = Widget::Table(Widget::TableHead($aTableHead), NULL, Widget::TableBody($aTableBody), 'selectable', null, array('role' => 'directory', 'aria-labelledby' => 'symphony-subheading', 'data-interactive' => 'data-interactive'));
     $this->Form->appendChild($table);
     $version = new XMLElement('p', 'Symphony ' . Symphony::Configuration()->get('version', 'symphony'), array('id' => 'version'));
     $this->Form->appendChild($version);
     $div = new XMLElement('div');
     $div->setAttribute('class', 'actions');
     $options = array(array(NULL, false, __('With Selected...')), array('delete', false, __('Delete'), 'confirm', null, array('data-message' => __('Are you sure you want to delete the selected text formatters?'))));
     Symphony::ExtensionManager()->notifyMembers('AddCustomActions', '/templatedtextformatters/', array('options' => &$options));
     if (!empty($options)) {
         $div->appendChild(Widget::Apply($options));
         $this->Form->appendChild($div);
     }
 }
 public function action()
 {
     // Do not proceed if the config file is read only
     if (!is_writable(CONFIG)) {
         redirect(SYMPHONY_URL . '/system/preferences/');
     }
     /**
      * This is where Extensions can hook on to custom actions they may need to provide
      * as a result of adding some custom actions through the `AddCustomPreferenceFieldsets`
      * delegate
      *
      * @delegate CustomActions
      * @param string $context
      * '/system/preferences/'
      */
     Symphony::ExtensionManager()->notifyMembers('CustomActions', '/system/preferences/');
     if (isset($_POST['action']['save'])) {
         $settings = $_POST['settings'];
         /**
          * Just prior to saving the preferences and writing them to the `CONFIG`
          * Allows extensions to preform custom validation logic on the settings.
          *
          * @delegate Save
          * @param string $context
          * '/system/preferences/'
          * @param array $settings
          *  An array of the preferences to be saved, passed by reference
          * @param array $errors
          *  An array of errors passed by reference
          */
         Symphony::ExtensionManager()->notifyMembers('Save', '/system/preferences/', array('settings' => &$settings, 'errors' => &$this->_errors));
         if (!is_array($this->_errors) || empty($this->_errors)) {
             if (is_array($settings) && !empty($settings)) {
                 foreach ($settings as $set => $values) {
                     foreach ($values as $key => $val) {
                         Symphony::Configuration()->set($key, $val, $set);
                     }
                 }
             }
             Symphony::Configuration()->write();
             redirect(SYMPHONY_URL . '/system/preferences/success/');
         }
     }
 }
Пример #24
0
 public function displayPublishPanel(XMLElement &$wrapper, $data = null, $flagWithError = null, $fieldnamePrefix = null, $fieldnamePostfix = null, $entry_id = null)
 {
     Extension_TextBoxField::appendHeaders(Extension_TextBoxField::PUBLISH_HEADERS);
     $sortorder = $this->get('sortorder');
     $element_name = $this->get('element_name');
     $classes = array();
     $label = Widget::Label($this->get('label'));
     $optional = '';
     if ($this->get('required') != 'yes') {
         if ((int) $this->get('text_length') > 0) {
             $optional = __('$1 of $2 remaining') . ' &#8211; ' . __('Optional');
         } else {
             $optional = __('Optional');
         }
     } else {
         if ((int) $this->get('text_length') > 0) {
             $optional = __('$1 of $2 remaining');
         }
     }
     if ($optional) {
         $label->appendChild(new XMLElement('i', $optional));
     }
     // Input box:
     if ($this->get('text_size') == 'single') {
         $input = Widget::Input("fields{$fieldnamePrefix}[{$element_name}]{$fieldnamePostfix}", General::sanitize($data['value']));
         ###
         # Delegate: ModifyTextBoxInlineFieldPublishWidget
         # Description: Allows developers modify the textbox before it is rendered in the publish forms
         $delegate = 'ModifyTextBoxInlineFieldPublishWidget';
     } else {
         $input = Widget::Textarea("fields{$fieldnamePrefix}[{$element_name}]{$fieldnamePostfix}", 20, 50, General::sanitize($data['value']));
         ###
         # Delegate: ModifyTextBoxFullFieldPublishWidget
         # Description: Allows developers modify the textbox before it is rendered in the publish forms
         $delegate = 'ModifyTextBoxFullFieldPublishWidget';
     }
     // Add classes:
     $classes[] = 'size-' . $this->get('text_size');
     if ($this->get('text_formatter') != 'none') {
         $classes[] = $this->get('text_formatter');
     }
     $input->setAttribute('class', implode(' ', $classes));
     $input->setAttribute('length', (int) $this->get('text_length'));
     Symphony::ExtensionManager()->notifyMembers($delegate, '/backend/', array('field' => $this, 'label' => $label, 'input' => $input, 'textarea' => $input));
     if (is_null($label)) {
         return;
     }
     $label->appendChild($input);
     if ($flagWithError != null) {
         $label = Widget::Error($label, $flagWithError);
     }
     $wrapper->appendChild($label);
 }
Пример #25
0
 public function __doit($fields, &$result, $position = null, $entry_id = null)
 {
     $post_values = new XMLElement('post-values');
     $filter_results = array();
     if (!is_array($this->eParamFILTERS)) {
         $this->eParamFILTERS = array();
     }
     // Create the post data cookie element
     if (is_array($fields) && !empty($fields)) {
         General::array_to_xml($post_values, $fields, true);
     }
     /**
      * Prior to saving entry from the front-end. This delegate will
      * force the Event to terminate if it populates the `$filter_results`
      * array. All parameters are passed by reference.
      *
      * @delegate EventPreSaveFilter
      * @param string $context
      * '/frontend/'
      * @param array $fields
      * @param Event $this
      * @param array $messages
      *  An associative array of array's which contain 4 values,
      *  the name of the filter (string), the status (boolean),
      *  the message (string) an optionally an associative array
      *  of additional attributes to add to the filter element.
      * @param XMLElement $post_values
      * @param integer $entry_id
      *  If editing an entry, this parameter will be an integer,
      *  otherwise null.
      */
     Symphony::ExtensionManager()->notifyMembers('EventPreSaveFilter', '/frontend/', array('fields' => &$fields, 'event' => &$this, 'messages' => &$filter_results, 'post_values' => &$post_values, 'entry_id' => &$entry_id));
     if (is_array($filter_results) && !empty($filter_results)) {
         $can_proceed = true;
         foreach ($filter_results as $fr) {
             list($name, $status, $message, $attributes) = $fr;
             $result->appendChild($this->buildFilterElement($name, $status ? 'passed' : 'failed', $message, $attributes));
             if ($status === false) {
                 $can_proceed = false;
             }
         }
         if ($can_proceed !== true) {
             $result->appendChild($post_values);
             $result->setAttribute('result', 'error');
             $result->appendChild(new XMLElement('message', __('Entry encountered errors when saving.')));
             return false;
         }
     }
     include_once TOOLKIT . '/class.sectionmanager.php';
     include_once TOOLKIT . '/class.entrymanager.php';
     if (!($section = SectionManager::fetch($this->getSource()))) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('The Section, %s, could not be found.', array($this->getSource()))));
         return false;
     }
     if (isset($entry_id)) {
         $entry =& EntryManager::fetch($entry_id);
         $entry = $entry[0];
         if (!is_object($entry)) {
             $result->setAttribute('result', 'error');
             $result->appendChild(new XMLElement('message', __('The Entry, %s, could not be found.', array($entry_id))));
             return false;
         }
     } else {
         $entry =& EntryManager::create();
         $entry->set('section_id', $this->getSource());
     }
     if (__ENTRY_FIELD_ERROR__ == $entry->checkPostData($fields, $errors, $entry->get('id') ? true : false)) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('Entry encountered errors when saving.')));
         foreach ($errors as $field_id => $message) {
             $field = FieldManager::fetch($field_id);
             if (is_array($fields[$field->get('element_name')])) {
                 $type = array_reduce($fields[$field->get('element_name')], array('SectionEvent', '__reduceType'));
             } else {
                 $type = $fields[$field->get('element_name')] == '' ? 'missing' : 'invalid';
             }
             $result->appendChild(new XMLElement($field->get('element_name'), null, array('label' => General::sanitize($field->get('label')), 'type' => $type, 'message' => General::sanitize($message))));
         }
         if (isset($post_values) && is_object($post_values)) {
             $result->appendChild($post_values);
         }
         return false;
     } elseif (__ENTRY_OK__ != $entry->setDataFromPost($fields, $errors, false, $entry->get('id') ? true : false)) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('Entry encountered errors when saving.')));
         foreach ($errors as $field_id => $message) {
             $field = FieldManager::fetch($field_id);
             $result->appendChild(new XMLElement($field->get('element_name'), null, array('label' => General::sanitize($field->get('label')), 'type' => 'invalid', 'message' => General::sanitize($message))));
         }
         if (isset($post_values) && is_object($post_values)) {
             $result->appendChild($post_values);
         }
         return false;
     } else {
         if (!$entry->commit()) {
             $result->setAttribute('result', 'error');
             $result->appendChild(new XMLElement('message', __('Unknown errors where encountered when saving.')));
             if (isset($post_values) && is_object($post_values)) {
                 $result->appendChild($post_values);
             }
             return false;
         }
         $result->setAttribute('id', $entry->get('id'));
     }
     // PASSIVE FILTERS ONLY AT THIS STAGE. ENTRY HAS ALREADY BEEN CREATED.
     if (in_array('send-email', $this->eParamFILTERS) && !in_array('expect-multiple', $this->eParamFILTERS)) {
         if (!function_exists('__sendEmailFindFormValue')) {
             function __sendEmailFindFormValue($needle, $haystack, $discard_field_name = true, $default = null, $collapse = true)
             {
                 if (preg_match('/^(fields\\[[^\\]]+\\],?)+$/i', $needle)) {
                     $parts = preg_split('/\\,/i', $needle, -1, PREG_SPLIT_NO_EMPTY);
                     $parts = array_map('trim', $parts);
                     $stack = array();
                     foreach ($parts as $p) {
                         $field = str_replace(array('fields[', ']'), '', $p);
                         $discard_field_name ? $stack[] = $haystack[$field] : ($stack[$field] = $haystack[$field]);
                     }
                     if (is_array($stack) && !empty($stack)) {
                         return $collapse ? implode(' ', $stack) : $stack;
                     } else {
                         $needle = null;
                     }
                 }
                 $needle = trim($needle);
                 if (empty($needle)) {
                     return $default;
                 }
                 return $needle;
             }
         }
         $fields = $_POST['send-email'];
         $db = Symphony::Database();
         $fields['recipient'] = __sendEmailFindFormValue($fields['recipient'], $_POST['fields'], true);
         $fields['recipient'] = preg_split('/\\,/i', $fields['recipient'], -1, PREG_SPLIT_NO_EMPTY);
         $fields['recipient'] = array_map('trim', $fields['recipient']);
         $fields['subject'] = __sendEmailFindFormValue($fields['subject'], $_POST['fields'], true, __('[Symphony] A new entry was created on %s', array(Symphony::Configuration()->get('sitename', 'general'))));
         $fields['body'] = __sendEmailFindFormValue($fields['body'], $_POST['fields'], false, null, false);
         $fields['sender-email'] = __sendEmailFindFormValue($fields['sender-email'], $_POST['fields'], true, null);
         $fields['sender-name'] = __sendEmailFindFormValue($fields['sender-name'], $_POST['fields'], true, null);
         $fields['reply-to-name'] = __sendEmailFindFormValue($fields['reply-to-name'], $_POST['fields'], true, null);
         $fields['reply-to-email'] = __sendEmailFindFormValue($fields['reply-to-email'], $_POST['fields'], true, null);
         $edit_link = SYMPHONY_URL . '/publish/' . $section->get('handle') . '/edit/' . $entry->get('id') . '/';
         $language = Symphony::Configuration()->get('lang', 'symphony');
         $template_path = Event::getNotificationTemplate($language);
         $body = sprintf(file_get_contents($template_path), $section->get('name'), $edit_link);
         if (is_array($fields['body'])) {
             foreach ($fields['body'] as $field_handle => $value) {
                 $body .= "// {$field_handle}" . PHP_EOL . $value . PHP_EOL . PHP_EOL;
             }
         } else {
             $body .= $fields['body'];
         }
         // Loop over all the recipients and attempt to send them an email
         // Errors will be appended to the Event XML
         $errors = array();
         foreach ($fields['recipient'] as $recipient) {
             $author = AuthorManager::fetchByUsername($recipient);
             if (empty($author)) {
                 $errors['recipient'][$recipient] = __('Recipient not found');
                 continue;
             }
             $email = Email::create();
             // Huib: Exceptions are also thrown in the settings functions, not only in the send function.
             // Those Exceptions should be caught too.
             try {
                 $email->recipients = array($author->get('first_name') => $author->get('email'));
                 if ($fields['sender-name'] != null) {
                     $email->sender_name = $fields['sender-name'];
                 }
                 if ($fields['sender-email'] != null) {
                     $email->sender_email_address = $fields['sender-email'];
                 }
                 if ($fields['reply-to-name'] != null) {
                     $email->reply_to_name = $fields['reply-to-name'];
                 }
                 if ($fields['reply-to-email'] != null) {
                     $email->reply_to_email_address = $fields['reply-to-email'];
                 }
                 $email->text_plain = str_replace('<!-- RECIPIENT NAME -->', $author->get('first_name'), $body);
                 $email->subject = $fields['subject'];
                 $email->send();
             } catch (EmailValidationException $e) {
                 $errors['address'][$author->get('email')] = $e->getMessage();
             } catch (EmailGatewayException $e) {
                 // The current error array does not permit custom tags.
                 // Therefore, it is impossible to set a "proper" error message.
                 // Will return the failed email address instead.
                 $errors['gateway'][$author->get('email')] = $e->getMessage();
             } catch (EmailException $e) {
                 // Because we don't want symphony to break because it can not send emails,
                 // all exceptions are logged silently.
                 // Any custom event can change this behaviour.
                 $errors['email'][$author->get('email')] = $e->getMessage();
             }
         }
         // If there were errors, output them to the event
         if (!empty($errors)) {
             $xml = $this->buildFilterElement('send-email', 'failed');
             foreach ($errors as $type => $messages) {
                 $xType = new XMLElement('error');
                 $xType->setAttribute('error-type', $type);
                 foreach ($messages as $recipient => $message) {
                     $xType->appendChild(new XMLElement('message', $message, array('recipient' => $recipient)));
                 }
                 $xml->appendChild($xType);
             }
             $result->appendChild($xml);
         } else {
             $result->appendChild($this->buildFilterElement('send-email', 'passed'));
         }
     }
     $filter_results = array();
     /**
      * After saving entry from the front-end. This delegate will not force
      * the Events to terminate if it populates the `$filter_results` array.
      * Provided with references to this object, the `$_POST` data and also
      * the error array
      *
      * @delegate EventPostSaveFilter
      * @param string $context
      * '/frontend/'
      * @param integer $entry_id
      * @param array $fields
      * @param Entry $entry
      * @param Event $this
      * @param array $messages
      *  An associative array of array's which contain 4 values,
      *  the name of the filter (string), the status (boolean),
      *  the message (string) an optionally an associative array
      *  of additional attributes to add to the filter element.
      */
     Symphony::ExtensionManager()->notifyMembers('EventPostSaveFilter', '/frontend/', array('entry_id' => $entry->get('id'), 'fields' => $fields, 'entry' => $entry, 'event' => &$this, 'messages' => &$filter_results));
     if (is_array($filter_results) && !empty($filter_results)) {
         foreach ($filter_results as $fr) {
             list($name, $status, $message, $attributes) = $fr;
             $result->appendChild($this->buildFilterElement($name, $status ? 'passed' : 'failed', $message, $attributes));
         }
     }
     $filter_errors = array();
     /**
      * This delegate that lets extensions know the final status of the
      * current Event. It is triggered when everything has processed correctly.
      * The `$messages` array contains the results of the previous filters that
      * have executed, and the `$errors` array contains any errors that have
      * occurred as a result of this delegate. These errors cannot stop the
      * processing of the Event, as that has already been done.
      *
      *
      * @delegate EventFinalSaveFilter
      * @param string $context
      * '/frontend/'
      * @param array $fields
      * @param Event $this
      * @param array $messages
      *  An associative array of array's which contain 4 values,
      *  the name of the filter (string), the status (boolean),
      *  the message (string) an optionally an associative array
      *  of additional attributes to add to the filter element.
      * @param array $errors
      *  An associative array of array's which contain 4 values,
      *  the name of the filter (string), the status (boolean),
      *  the message (string) an optionally an associative array
      *  of additional attributes to add to the filter element.
      * @param Entry $entry
      */
     Symphony::ExtensionManager()->notifyMembers('EventFinalSaveFilter', '/frontend/', array('fields' => $fields, 'event' => $this, 'messages' => $filter_results, 'errors' => &$filter_errors, 'entry' => $entry));
     if (is_array($filter_errors) && !empty($filter_errors)) {
         foreach ($filter_errors as $fr) {
             list($name, $status, $message, $attributes) = $fr;
             $result->appendChild($this->buildFilterElement($name, $status ? 'passed' : 'failed', $message, $attributes));
         }
     }
     $result->setAttributeArray(array('result' => 'success', 'type' => isset($entry_id) ? 'edited' : 'created'));
     $result->appendChild(new XMLElement('message', isset($entry_id) ? __('Entry edited successfully.') : __('Entry created successfully.')));
     if (isset($post_values) && is_object($post_values)) {
         $result->appendChild($post_values);
     }
     return true;
 }
Пример #26
0
 /**
  * This function is called from the resources index when a user uses the
  * With Selected, or Apply, menu. The type of resource is given by
  * `$resource_type`. At this time the only two valid values,
  * `RESOURCE_TYPE_EVENT` or `RESOURCE_TYPE_DATASOURCE`.
  *
  * The function handles 'delete', 'attach', 'detach', 'attach all',
  * 'detach all' actions.
  *
  * @param integer $resource_type
  *  Either `RESOURCE_TYPE_EVENT` or `RESOURCE_TYPE_DATASOURCE`
  * @throws Exception
  */
 public function __actionIndex($resource_type)
 {
     $manager = ResourceManager::getManagerFromType($resource_type);
     $checked = is_array($_POST['items']) ? array_keys($_POST['items']) : null;
     $context = Administration::instance()->getPageCallback();
     if (isset($_POST['action']) && is_array($_POST['action'])) {
         /**
          * Extensions can listen for any custom actions that were added
          * through `AddCustomPreferenceFieldsets` or `AddCustomActions`
          * delegates.
          *
          * @delegate CustomActions
          * @since Symphony 2.3.2
          * @param string $context
          *  '/blueprints/datasources/' or '/blueprints/events/'
          * @param array $checked
          *  An array of the selected rows. The value is usually the ID of the
          *  the associated object.
          */
         Symphony::ExtensionManager()->notifyMembers('CustomActions', $context['pageroot'], array('checked' => $checked));
         if (is_array($checked) && !empty($checked)) {
             if ($_POST['with-selected'] == 'delete') {
                 $canProceed = true;
                 foreach ($checked as $handle) {
                     $path = call_user_func(array($manager, '__getDriverPath'), $handle);
                     // Don't allow Extension resources to be deleted. RE: #2027
                     if (stripos($path, EXTENSIONS) === 0) {
                         continue;
                     } elseif (!General::deleteFile($path)) {
                         $folder = str_replace(DOCROOT, '', $path);
                         $folder = str_replace('/' . basename($path), '', $folder);
                         $this->pageAlert(__('Failed to delete %s.', array('<code>' . basename($path) . '</code>')) . ' ' . __('Please check permissions on %s', array('<code>' . $folder . '</code>')), Alert::ERROR);
                         $canProceed = false;
                     } else {
                         $pages = ResourceManager::getAttachedPages($resource_type, $handle);
                         foreach ($pages as $page) {
                             ResourceManager::detach($resource_type, $handle, $page['id']);
                         }
                     }
                 }
                 if ($canProceed) {
                     redirect(Administration::instance()->getCurrentPageURL());
                 }
             } elseif (preg_match('/^(at|de)?tach-(to|from)-page-/', $_POST['with-selected'])) {
                 if (substr($_POST['with-selected'], 0, 6) == 'detach') {
                     $page = str_replace('detach-from-page-', '', $_POST['with-selected']);
                     foreach ($checked as $handle) {
                         ResourceManager::detach($resource_type, $handle, $page);
                     }
                 } else {
                     $page = str_replace('attach-to-page-', '', $_POST['with-selected']);
                     foreach ($checked as $handle) {
                         ResourceManager::attach($resource_type, $handle, $page);
                     }
                 }
                 if ($canProceed) {
                     redirect(Administration::instance()->getCurrentPageURL());
                 }
             } elseif (preg_match('/^(at|de)?tach-all-pages$/', $_POST['with-selected'])) {
                 $pages = PageManager::fetch(false, array('id'));
                 if (substr($_POST['with-selected'], 0, 6) == 'detach') {
                     foreach ($checked as $handle) {
                         foreach ($pages as $page) {
                             ResourceManager::detach($resource_type, $handle, $page['id']);
                         }
                     }
                 } else {
                     foreach ($checked as $handle) {
                         foreach ($pages as $page) {
                             ResourceManager::attach($resource_type, $handle, $page['id']);
                         }
                     }
                 }
                 redirect(Administration::instance()->getCurrentPageURL());
             }
         }
     }
 }
Пример #27
0
 /**
  * Setter for `$ExtensionManager` using the current
  * Symphony instance as the parent. If for some reason this fails,
  * a Symphony Error page will be thrown
  */
 public function initialiseExtensionManager()
 {
     if (self::$ExtensionManager instanceof ExtensionManager) {
         return true;
     }
     self::$ExtensionManager = new ExtensionManager();
     if (!self::$ExtensionManager instanceof ExtensionManager) {
         throw new SymphonyErrorPage('Error creating Symphony extension manager.');
     }
 }
 public function sendBatch($pauth)
 {
     if ($this->getPAuth() != $pauth) {
         $this->setStatus('error');
         throw new EmailNewsletterException('Incorrect Process Auth used. This usually means there is more than one process running. Aborting.');
     }
     $this->_completed = explode(', ', $this->getCompletedRecipientGroups());
     $recipients = $this->_getRecipients($this->limit);
     if (count($recipients) > 0) {
         try {
             $template = $this->getTemplate();
             $sender = $this->getSender();
             $about = $sender->about();
             $additional_headers = $sender->additional_headers;
             if (is_array($about['smtp'])) {
                 $email = Email::create('smtp');
                 $email->setSenderName($about['smtp']['from_name']);
                 $email->setSenderEmailAddress($about['smtp']['from_address']);
                 $email->setHost($about['smtp']['host']);
                 $email->setPort($about['smtp']['port']);
                 $email->setSecure($about['smtp']['secure']);
                 if ($about['smtp']['auth'] == 1) {
                     $email->setAuth(true);
                     $email->setUser($about['smtp']['username']);
                     $email->setPass($about['smtp']['password']);
                 }
             } elseif (is_array($about['amazon_ses'])) {
                 $email = Email::create('amazon_ses');
                 $email->setSenderName($about['amazon_ses']['from_name']);
                 $email->setSenderEmailAddress($about['amazon_ses']['from_address']);
                 $email->setAwsKey($about['amazon_ses']['aws_key']);
                 $email->setAwsSecretKey($about['amazon_ses']['aws_secret_key']);
                 $email->setFallback($about['amazon_ses']['fallback']);
                 $email->setReturnPath($about['amazon_ses']['return_path']);
             } elseif (is_array($about['sendmail'])) {
                 $email = Email::create('sendmail');
                 $email->setSenderName($about['sendmail']['from_name']);
                 $email->setSenderEmailAddress($about['sendmail']['from_address']);
             } else {
                 throw new EmailNewsletterException('Currently only sendmail and SMTP are supported. This will be fixed when the API supports it.');
             }
         } catch (Exception $e) {
             file_put_contents(DOCROOT . '/manifest/newsletter-log.txt', '[' . DateTimeObj::get('Y/m/d H:i:s') . '] newsletter-id: ' . $this->getId() . ' - ' . $e->getMessage() . "\r\n", FILE_APPEND);
             return false;
         }
         $email->openConnection();
         foreach ($recipients as $recipient) {
             try {
                 /**
                  * @delegate PreEmailGenerate
                  */
                 Symphony::ExtensionManager()->notifyMembers('PreEmailGenerate', '/extension/email_newsletter_manager/', array('newsletter' => &$this, 'email' => &$email, 'template' => &$template, 'recipient' => &$recipient));
                 $email->setRecipients(array($recipient['name'] => $recipient['email']));
                 $template->recipients = '"' . $recipient['name'] . '" <' . $recipient['email'] . '>';
                 $template->addParams(array('etm-recipient' => $recipient['email']));
                 $email->setReplyToName($about['reply-to-name']);
                 $template->reply_to_name = $about['reply-to-name'];
                 $template->addParams(array('etm-reply-to-name' => $about['reply-to-name']));
                 $email->setReplyToEmailAddress($about['reply-to-email']);
                 $template->reply_to_email_address = $about['reply-to-email'];
                 $template->addParams(array('etm-reply-to-email-address' => $about['reply-to-email']));
                 if (!empty($additional_headers)) {
                     foreach ($additional_headers as $name => $body) {
                         $email->appendHeaderField($name, $body);
                     }
                 }
                 $template->addParams(array('enm-newsletter-id' => $this->getId()));
                 // add root and workspace parameters
                 $pseudo_root = $this->getPseudoRoot();
                 $template->addParams(array('root' => !empty($pseudo_root) ? $pseudo_root : NULL, 'workspace' => !empty($pseudo_root) ? $pseudo_root . '/workspace' : NULL));
                 $xml = $template->processDatasources();
                 $template->setXML($xml->generate());
                 $content = $template->render();
                 if (empty($content)) {
                     throw new EmailNewsletterException("ETM template could not be rendered");
                 }
                 if (!empty($content['subject'])) {
                     $email->subject = $content['subject'];
                 } else {
                     throw new EmailNewsletterException("Can not send emails without a subject");
                 }
                 if (isset($content['plain'])) {
                     $email->text_plain = $content['plain'];
                 }
                 if (isset($content['html'])) {
                     $email->text_html = $content['html'];
                 }
                 /**
                  * @delegate PreEmailSend
                  */
                 Symphony::ExtensionManager()->notifyMembers('PreEmailSend', '/extension/email_newsletter_manager/', array('newsletter' => &$this, 'email' => &$email, 'template' => &$template, 'recipient' => $recipient));
                 $email->send();
                 /**
                  * @delegate PostEmailSend
                  */
                 Symphony::ExtensionManager()->notifyMembers('PostEmailSend', '/extension/email_newsletter_manager/', array('newsletter' => &$this, 'email' => &$email, 'template' => &$template, 'recipient' => $recipient));
                 $this->_markRecipient($recipient['email'], 'sent');
             } catch (Exception $e) {
                 file_put_contents(DOCROOT . '/manifest/newsletter-log.txt', '[' . DateTimeObj::get('Y/m/d H:i:s') . '] newsletter-id: ' . $this->getId() . ' - ' . $e->getMessage() . "\r\n", FILE_APPEND);
                 $this->_markRecipient($recipient['email'], 'failed');
                 continue;
             }
         }
         $email->closeConnection();
     }
     //To prevent timing problems, the completed recipient groups should only be marked as complete when the emails are actually sent.
     Symphony::Database()->update(array('completed_recipients' => implode(', ', $this->_completed)), 'tbl_email_newsletters', 'id = ' . $this->getId());
     if (count($recipients) == 0) {
         Symphony::Database()->query('DROP TABLE IF EXISTS `tbl_tmp_email_newsletters_sent_' . $this->getId() . '`');
         $this->setStatus('completed');
         Symphony::Database()->update(array('completed_on' => date('Y-m-d H:i:s', time())), 'tbl_email_newsletters', 'id = ' . $this->getId());
         return 'completed';
     }
     return 'sent';
 }
 /**
  * This function creates the initial `.xsl` template for the page, whether
  * that be from the `TEMPLATES/blueprints.page.xsl` file, or from an existing
  * template with the same name. This function will handle the renaming of a page
  * by creating the new files using the old files as the templates then removing
  * the old template. If a template already exists for a Page, it will not
  * be overridden and the function will return true.
  *
  * @see toolkit.PageManager#resolvePageFileLocation()
  * @see toolkit.PageManager#createHandle()
  * @param string $new_path
  *  The path of the Page, which is the handles of the Page parents. If the
  *  page has multiple parents, they will be separated by a forward slash.
  *  eg. article/read. If a page has no parents, this parameter should be null.
  * @param string $new_handle
  *  The new Page handle, generated using `PageManager::createHandle`.
  * @param string $old_path (optional)
  *  This parameter is only required when renaming a Page. It should be the 'old
  *  path' before the Page was renamed.
  * @param string $old_handle (optional)
  *  This parameter is only required when renaming a Page. It should be the 'old
  *  handle' before the Page was renamed.
  * @return boolean
  *  True when the page files have been created successfully, false otherwise.
  */
 public static function createPageFiles($new_path, $new_handle, $old_path = null, $old_handle = null)
 {
     $new = PageManager::resolvePageFileLocation($new_path, $new_handle);
     $old = PageManager::resolvePageFileLocation($old_path, $old_handle);
     $data = null;
     // Nothing to do:
     if (file_exists($new) && $new == $old) {
         return true;
     }
     // Old file doesn't exist, use template:
     if (!file_exists($old)) {
         $data = file_get_contents(self::getTemplate('blueprints.page'));
     } else {
         $data = file_get_contents($old);
     }
     /**
      * Just before a Page Template is about to be created & written to disk
      *
      * @delegate PageTemplatePreCreate
      * @since Symphony 2.2.2
      * @param string $context
      * '/blueprints/pages/'
      * @param string $file
      *  The path to the Page Template file
      * @param string $contents
      *  The contents of the `$data`, passed by reference
      */
     Symphony::ExtensionManager()->notifyMembers('PageTemplatePreCreate', '/blueprints/pages/', array('file' => $new, 'contents' => &$data));
     if (PageManager::writePageFiles($new, $data)) {
         // Remove the old file, in the case of a rename
         if (file_exists($old)) {
             General::deleteFile($old);
         }
         /**
          * Just after a Page Template is saved after been created.
          *
          * @delegate PageTemplatePostCreate
          * @since Symphony 2.2.2
          * @param string $context
          * '/blueprints/pages/'
          * @param string $file
          *  The path to the Page Template file
          */
         Symphony::ExtensionManager()->notifyMembers('PageTemplatePostCreate', '/blueprints/pages/', array('file' => $new));
         return true;
     }
     return false;
 }
 public function action()
 {
     // Do not proceed if the config file is read only
     if (!is_writable(CONFIG)) {
         redirect(SYMPHONY_URL . '/system/preferences/');
     }
     /**
      * Extensions can listen for any custom actions that were added
      * through `AddCustomPreferenceFieldsets` or `AddCustomActions`
      * delegates.
      *
      * @delegate CustomActions
      * @param string $context
      * '/system/preferences/'
      */
     Symphony::ExtensionManager()->notifyMembers('CustomActions', '/system/preferences/');
     if (isset($_POST['action']['save'])) {
         $settings = $_POST['settings'];
         /**
          * Just prior to saving the preferences and writing them to the `CONFIG`
          * Allows extensions to preform custom validation logic on the settings.
          *
          * @delegate Save
          * @param string $context
          * '/system/preferences/'
          * @param array $settings
          *  An array of the preferences to be saved, passed by reference
          * @param array $errors
          *  An array of errors passed by reference
          */
         Symphony::ExtensionManager()->notifyMembers('Save', '/system/preferences/', array('settings' => &$settings, 'errors' => &$this->_errors));
         if (!is_array($this->_errors) || empty($this->_errors)) {
             if (is_array($settings) && !empty($settings)) {
                 Symphony::Configuration()->setArray($settings, false);
             }
             Symphony::Configuration()->write();
             if (function_exists('opcache_invalidate')) {
                 opcache_invalidate(CONFIG, true);
             }
             redirect(SYMPHONY_URL . '/system/preferences/success/');
         }
     }
 }