public function enable() { if (Symphony::ExtensionManager() instanceof ExtensionManager) { PLHDatasourceManager::editAllNavDssTo('PLH'); } return true; }
/** * 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; }
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'); }
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(); } }
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'); } }
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'); }
/** * 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(); }
/** * * 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'; } }
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'))); }
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; } } } }
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; }
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 – %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/'); } } }
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') . ' – ' . __('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); }
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; }
/** * 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()); } } } }
/** * 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/'); } } }