public function delete($id) { $file = TEXTFORMATTERS . '/formatter.' . $id . '.php'; if (!General::deleteFile($file)) { $this->pageAlert(__('Failed to delete <code>%s</code>. Please check permissions.', array($file)), Alert::ERROR); } }
/** * Clear cache. * * @see http://symphony-cms.com/learn/api/2.3/delegates/#DatasourcePreDelete */ public function __clearSubsectionCache() { if (file_exists(CACHE . '/subsectionmanager-storage')) { General::deleteFile(CACHE . '/subsectionmanager-storage'); } self::$updateCache = true; }
function action() { $checked = @array_keys($_POST['items']); if (!isset($_POST['action']['apply']) || empty($checked)) { return; } $FileManager =& $this->_Parent->ExtensionManager->create('filemanager'); switch ($_POST['with-selected']) { case 'delete': $path = DOCROOT . $FileManager->getStartLocation(); foreach ($checked as $rel_file) { $abs_file = $path . '/' . ltrim($rel_file, '/'); if (!is_dir($abs_file) && file_exists($abs_file)) { General::deleteFile($abs_file); } elseif (is_dir($abs_file)) { if (!@rmdir($abs_file)) { $this->pageAlert(__('%s could not be deleted as is still contains files.', array('<code>' . $rel_file . '</code>')), AdministrationPage::PAGE_ALERT_ERROR); } } } break; case 'archive': $path = is_array($this->_context) && !empty($this->_context) ? '/' . implode('/', $this->_context) . '/' : NULL; $filename = $FileManager->createArchive($checked, $path); break; } }
function __actionIndex() { $checked = @array_keys($_POST['items']); if (is_array($checked) && !empty($checked)) { switch ($_POST['with-selected']) { case 'delete': $pages = $checked; ## TODO: Fix Me ### # Delegate: Delete # Description: Prior to deletion. Provided with an array of pages for deletion that can be modified. //$ExtensionManager->notifyMembers('Delete', getCurrentPage(), array('pages' => &$pages)); $pagesList = join(', ', array_map('intval', $pages)); // 1. Fetch page details $query = 'SELECT `id`, `sortorder`, `handle`, `path`, `title` FROM tbl_pages_templates WHERE `id` IN (' . $pagesList . ')'; $details = $this->_Parent->Database->fetch($query); $this->_Parent->Database->delete('tbl_pages_templates', " `id` IN('" . implode("','", $checked) . "')"); $this->_Parent->Database->delete('tbl_pages_types', " `page_id` IN('" . implode("','", $checked) . "')"); foreach ($details as $r) { $filename = Lang::createHandle($r['title']); // echo PAGES . "/templates/" . $filename . ".xsl"; $this->_Parent->Database->query("UPDATE tbl_pages_templates SET `sortorder` = (`sortorder` + 1) WHERE `sortorder` < '" . $r['sortorder'] . "'"); General::deleteFile(PAGES . "/templates/" . $filename . ".xsl"); } redirect($this->_Parent->getCurrentPageURL()); break; } } }
public function cbSectionPreDelete($context) { $section_ids = implode(',', $context['section_ids']); $sections = Symphony::Database()->fetchCol('handle', "SELECT * FROM `tbl_sections` WHERE id IN ({$section_ids})"); foreach ($sections as $section) { General::deleteFile(WORKSPACE . "/sections/{$section}.xml"); } }
public function entryDataCleanup($entry_id, $data) { foreach (FLang::instance()->ld()->languageCodes() as $language_code) { $file_location = WORKSPACE . '/' . ltrim($data['file-' . $language_code], '/'); if (is_file($file_location)) { General::deleteFile($file_location); } } parent::entryDataCleanup($entry_id); return true; }
public function uninstall() { $this->_Parent->Database->query('DROP TABLE IF EXISTS tbl_markitup_fields'); $this->_Parent->Database->query('DROP TABLE IF EXISTS tbl_markitup_cache'); $files = General::listStructure(CACHE, array('css', 'js'), false, 'asc'); if (empty($files['filelist'])) { return true; } foreach ($files['filelist'] as $file) { if (strpos(CACHE . "/{$file}", 'markitup_') !== false) { General::deleteFile(CACHE . "/{$file}"); } } $this->_Parent->Configuration->remove('markitup'); return $this->_Parent->saveConfig(); }
function action() { $FileManager =& $this->_Parent->ExtensionManager->create('filemanager'); $file = new File(DOCROOT . $FileManager->getStartLocation() . $_GET['file']); if (isset($_POST['action']['save'])) { $fields = $_POST['fields']; $file->setName($fields['name']); if (isset($fields['contents'])) { $file->setContents($fields['contents']); } $file->setPermissions($fields['permissions']); $relpath = str_replace(DOCROOT . $FileManager->getStartLocation(), NULL, dirname($_GET['file'])); if ($file->isWritable()) { redirect($FileManager->baseURL() . 'properties/?file=' . rtrim(dirname($_GET['file']), '/') . '/' . $file->name() . '&result=saved'); } else { redirect($FileManager->baseURL() . 'browse/' . $relpath); } } elseif (isset($_POST['action']['delete'])) { General::deleteFile($file->path() . '/' . $file->name()); $relpath = str_replace(DOCROOT . $FileManager->getStartLocation(), NULL, dirname($_GET['file'])); redirect($FileManager->baseURL() . 'browse/' . $relpath); } }
public function __actionIndex() { $sections_post = @$_POST['sections']; if (empty($this->_driver)) { $this->_driver = $this->_Parent->ExtensionManager->create('section_schemas'); } if (@isset($_POST['action']['save'])) { $blueprint = new contentBlueprintsDatasources(); $sm = new SectionManager($this->_Parent); $sections = $sm->fetch(); foreach ($sections as $section) { $file = DATASOURCES . '/data.section_schema_' . str_replace('-', '_', $section->_data['handle']) . '.php'; General::deleteFile($file); if (in_array($section->_data['handle'], $sections_post)) { $dsShell = file_get_contents(TEMPLATE . '/datasource.tpl'); $dsShell = str_replace("require_once(TOOLKIT . '/class.datasource.php');", "require_once(TOOLKIT . '/class.datasource.php');\n\trequire_once(TOOLKIT . '/class.sectionmanager.php');\n\trequire_once(TOOLKIT . '/class.fieldmanager.php');\n\trequire_once(TOOLKIT . '/class.entrymanager.php');", $dsShell); $dsShell = str_replace('<!-- CLASS NAME -->', 'section_schema_' . str_replace('-', '_', $section->_data['handle']), $dsShell); $dsShell = str_replace('<!-- FILTERS -->', '', $dsShell); $dsShell = str_replace('<!-- INCLUDED ELEMENTS -->', '', $dsShell); $dsShell = str_replace('<!-- DS DEPENDANCY LIST -->', '""', $dsShell); $params['rootelement'] = 'section-schema'; $blueprint->__injectVarList($dsShell, $params); $about = array('name' => 'Section Schema: ' . $section->_data['name'], 'version' => '1.0', 'release date' => DateTimeObj::getGMT('c'), 'author name' => $this->_Parent->Author->getFullName(), 'author website' => URL, 'author email' => $this->_Parent->Author->get('email')); $blueprint->__injectAboutInformation($dsShell, $about); $dsShell = str_replace('<!-- SOURCE -->', $section->_data['id'], $dsShell); $dsShell = str_replace('return true;', 'return false;', $dsShell); $dsShell = str_replace('<!-- GRAB -->', "\$extension = \$this->_Parent->ExtensionManager->create('section_schemas');" . self::CRLF . "\t\t\t\t\$extension->getSectionSchema(\$result, \$this->getSource());", $dsShell); $dsShell = str_replace('<!-- EXTRAS -->', '', $dsShell); if (!is_writable(dirname($file)) || !($write = General::writeFile($file, $dsShell, $this->_Parent->Configuration->get('write_mode', 'file')))) { $this->pageAlert(__('Failed to write data sources to <code>%s</code>. Please check permissions.', array(DATASOURCES)), Alert::ERROR); } else { $this->pageAlert('Section Schema data sources saved.', Alert::SUCCESS); } } } } }
function action() { $this->_existing_file = isset($this->_context[1]) ? $this->_context[1] . '.xsl' : NULL; if (array_key_exists('save', $_POST['action']) || array_key_exists('done', $_POST['action'])) { $fields = $_POST['fields']; $this->_errors = array(); if (!isset($fields['name']) || trim($fields['name']) == '') { $this->_errors['name'] = __('Name is a required field.'); } if (!isset($fields['body']) || trim($fields['body']) == '') { $this->_errors['body'] = __('Body is a required field.'); } elseif (!General::validateXML($fields['body'], $errors, false, new XSLTProcess())) { $this->_errors['body'] = __('This document is not well formed. The following error was returned: <code>%s</code>', array($errors[0]['message'])); } if (empty($this->_errors)) { $fields['name'] = Lang::createFilename($fields['name']); if (General::right($fields['name'], 4) != '.xsl') { $fields['name'] .= '.xsl'; } $file = UTILITIES . '/' . $fields['name']; ##Duplicate if ($this->_context[0] == 'edit' && ($this->_existing_file != $fields['name'] && is_file($file))) { $this->_errors['name'] = __('A Utility with that name already exists. Please choose another.'); } elseif ($this->_context[0] == 'new' && is_file($file)) { $this->_errors['name'] = __('A Utility with that name already exists. Please choose another.'); } elseif (!($write = General::writeFile($file, $fields['body'], $this->_Parent->Configuration->get('write_mode', 'file')))) { $this->pageAlert(__('Utility could not be written to disk. Please check permissions on <code>/workspace/utilities</code>.'), Alert::ERROR); } else { ## Remove any existing file if the filename has changed if ($this->_existing_file && $file != UTILITIES . '/' . $this->_existing_file) { General::deleteFile(UTILITIES . '/' . $this->_existing_file); } ## TODO: Fix me ### # Delegate: Edit # Description: After saving the asset, the file path is provided. //$ExtensionManager->notifyMembers('Edit', getCurrentPage(), array('file' => $file)); redirect(URL . '/symphony/blueprints/utilities/edit/' . str_replace('.xsl', '', $fields['name']) . '/' . ($this->_context[0] == 'new' ? 'created' : 'saved') . '/'); } } } elseif ($this->_context[0] == 'edit' && @array_key_exists('delete', $_POST['action'])) { ## TODO: Fix me ### # Delegate: Delete # Description: Prior to deleting the asset file. Target file path is provided. //$ExtensionManager->notifyMembers('Delete', getCurrentPage(), array('file' => WORKSPACE . '/' . $this->_existing_file_rel)); General::deleteFile(UTILITIES . '/' . $this->_existing_file); redirect(URL . '/symphony/blueprints/components/'); } }
public function __formAction() { $fields = $_POST['fields']; $this->_errors = array(); if (trim($fields['name']) == '') { $this->_errors['name'] = __('This is a required field'); } if (trim($fields['source']) == '') { $this->_errors['source'] = __('This is a required field'); } $filters = is_array($fields['filters']) ? $fields['filters'] : array(); $classname = Lang::createHandle($fields['name'], NULL, '_', false, true, array('@^[^a-z]+@i' => '', '/[^\\w-\\.]/i' => '')); $rootelement = str_replace('_', '-', $classname); $file = EVENTS . '/event.' . $classname . '.php'; $isDuplicate = false; $queueForDeletion = NULL; if ($this->_context[0] == 'new' && is_file($file)) { $isDuplicate = true; } elseif ($this->_context[0] == 'edit') { $existing_handle = $this->_context[1]; if ($classname != $existing_handle && is_file($file)) { $isDuplicate = true; } elseif ($classname != $existing_handle) { $queueForDeletion = EVENTS . '/event.' . $existing_handle . '.php'; } } ##Duplicate if ($isDuplicate) { $this->_errors['name'] = __('An Event with the name <code>%s</code> name already exists', array($classname)); } if (empty($this->_errors)) { $multiple = in_array('expect-multiple', $filters); $eventShell = file_get_contents(TEMPLATE . '/event.tpl'); $about = array('name' => $fields['name'], 'version' => '1.0', 'release date' => DateTimeObj::getGMT('c'), 'author name' => Administration::instance()->Author->getFullName(), 'author website' => URL, 'author email' => Administration::instance()->Author->get('email'), 'trigger condition' => $rootelement); $source = $fields['source']; $filter = NULL; $elements = NULL; $this->__injectAboutInformation($eventShell, $about); $this->__injectFilters($eventShell, $filters); $documentation = NULL; $documentation_parts = array(); $documentation_parts[] = new XMLElement('h3', __('Success and Failure XML Examples')); $documentation_parts[] = new XMLElement('p', __('When saved successfully, the following XML will be returned:')); if ($multiple) { $code = new XMLElement($rootelement); $entry = new XMLElement('entry', NULL, array('index' => '0', 'result' => 'success', 'type' => 'create | edit')); $entry->appendChild(new XMLElement('message', __('Entry [created | edited] successfully.'))); $code->appendChild($entry); } else { $code = new XMLElement($rootelement, NULL, array('result' => 'success', 'type' => 'create | edit')); $code->appendChild(new XMLElement('message', __('Entry [created | edited] successfully.'))); } $documentation_parts[] = self::processDocumentationCode($code); ### $documentation_parts[] = new XMLElement('p', __('When an error occurs during saving, due to either missing or invalid fields, the following XML will be returned') . ($multiple ? __(' (<b>Notice that it is possible to get mixtures of success and failure messages when using the "Allow Multiple" option</b>)') : NULL) . ':'); if ($multiple) { $code = new XMLElement($rootelement); $entry = new XMLElement('entry', NULL, array('index' => '0', 'result' => 'error')); $entry->appendChild(new XMLElement('message', __('Entry encountered errors when saving.'))); $entry->appendChild(new XMLElement('field-name', NULL, array('type' => 'invalid | missing'))); $code->appendChild($entry); $entry = new XMLElement('entry', NULL, array('index' => '1', 'result' => 'success', 'type' => 'create | edit')); $entry->appendChild(new XMLElement('message', __('Entry [created | edited] successfully.'))); $code->appendChild($entry); } else { $code = new XMLElement($rootelement, NULL, array('result' => 'error')); $code->appendChild(new XMLElement('message', __('Entry encountered errors when saving.'))); $code->appendChild(new XMLElement('field-name', NULL, array('type' => 'invalid | missing'))); } $code->setValue('...', false); $documentation_parts[] = self::processDocumentationCode($code); ### if (is_array($filters) && !empty($filters)) { $documentation_parts[] = new XMLElement('p', __('The following is an example of what is returned if any options return an error:')); $code = new XMLElement($rootelement, NULL, array('result' => 'error')); $code->appendChild(new XMLElement('message', __('Entry encountered errors when saving.'))); $code->appendChild(new XMLElement('filter', NULL, array('name' => 'admin-only', 'status' => 'failed'))); $code->appendChild(new XMLElement('filter', __('Recipient not found'), array('name' => 'send-email', 'status' => 'failed'))); $code->setValue('...', false); $documentation_parts[] = self::processDocumentationCode($code); } ### $documentation_parts[] = new XMLElement('h3', __('Example Front-end Form Markup')); $documentation_parts[] = new XMLElement('p', __('This is an example of the form markup you can use on your frontend:')); $container = new XMLElement('form', NULL, array('method' => 'post', 'action' => '', 'enctype' => 'multipart/form-data')); $container->appendChild(Widget::Input('MAX_FILE_SIZE', Symphony::Configuration()->get('max_upload_size', 'admin'), 'hidden')); $sectionManager = new SectionManager($this->_Parent); $section = $sectionManager->fetch($fields['source']); $section_fields = $section->fetchFields(); if (is_array($section_fields) && !empty($section_fields)) { foreach ($section_fields as $f) { if ($f->getExampleFormMarkup() instanceof XMLElement) { $container->appendChild($f->getExampleFormMarkup()); } } } $container->appendChild(Widget::Input('action[' . $rootelement . ']', __('Submit'), 'submit')); $code = $container->generate(true); $documentation_parts[] = self::processDocumentationCode($multiple ? str_replace('fields[', 'fields[0][', $code) : $code); $documentation_parts[] = new XMLElement('p', __('To edit an existing entry, include the entry ID value of the entry in the form. This is best as a hidden field like so:')); $documentation_parts[] = self::processDocumentationCode(Widget::Input('id' . ($multiple ? '[0]' : NULL), 23, 'hidden')); $documentation_parts[] = new XMLElement('p', __('To redirect to a different location upon a successful save, include the redirect location in the form. This is best as a hidden field like so, where the value is the URL to redirect to:')); $documentation_parts[] = self::processDocumentationCode(Widget::Input('redirect', URL . '/success/', 'hidden')); if (in_array('send-email', $filters)) { $documentation_parts[] = new XMLElement('h3', __('Send Notification Email')); $documentation_parts[] = new XMLElement('p', __('Upon the event successfully saving the entry, this option takes input from the form and send an email to the desired recipient. <b>It currently does not work with "Allow Multiple".</b> The following are the recognised fields:')); $documentation_parts[] = self::processDocumentationCode('send-email[sender-email] // ' . __('Optional') . self::CRLF . 'send-email[sender-name] // ' . __('Optional') . self::CRLF . 'send-email[reply-to-email] // ' . __('Optional') . self::CRLF . 'send-email[reply-to-name] // ' . __('Optional') . self::CRLF . 'send-email[subject]' . self::CRLF . 'send-email[body]' . self::CRLF . 'send-email[recipient] // ' . __('list of comma-separated author usernames.')); $documentation_parts[] = new XMLElement('p', __('All of these fields can be set dynamically using the exact field name of another field in the form as shown below in the example form:')); $documentation_parts[] = self::processDocumentationCode('<form action="" method="post"> <fieldset> <label>' . __('Name') . ' <input type="text" name="fields[author]" value="" /></label> <label>' . __('Email') . ' <input type="text" name="fields[email]" value="" /></label> <label>' . __('Message') . ' <textarea name="fields[message]" rows="5" cols="21"></textarea></label> <input name="send-email[sender-email]" value="fields[email]" type="hidden" /> <input name="send-email[sender-name]" value="fields[author]" type="hidden" /> <input name="send-email[reply-to-email]" value="fields[email]" type="hidden" /> <input name="send-email[reply-to-name]" value="fields[author]" type="hidden" /> <input name="send-email[subject]" value="You are being contacted" type="hidden" /> <input name="send-email[body]" value="fields[message]" type="hidden" /> <input name="send-email[recipient]" value="fred" type="hidden" /> <input id="submit" type="submit" name="action[save-contact-form]" value="Send" /> </fieldset> </form>'); } /** * Allows adding documentation for new filters. A reference to the $documentation * array is provided, along with selected filters * @delegate AppendEventFilterDocumentation * @param string $context * '/blueprints/events/(edit|new|info)/' * @param array $selected * An array of all the selected filters for this Event * @param array $documentation * An array of all the documentation XMLElements, passed by reference */ Symphony::ExtensionManager()->notifyMembers('AppendEventFilterDocumentation', '/blueprints/events/' . $this->_context[0] . '/', array('selected' => $filters, 'documentation' => &$documentation_parts)); $documentation = join(self::CRLF, array_map(create_function('$x', 'return rtrim($x->generate(true, 4));'), $documentation_parts)); $documentation = str_replace('\'', '\\\'', $documentation); $eventShell = str_replace('<!-- CLASS NAME -->', $classname, $eventShell); $eventShell = str_replace('<!-- SOURCE -->', $source, $eventShell); $eventShell = str_replace('<!-- DOCUMENTATION -->', General::tabsToSpaces($documentation, 2), $eventShell); $eventShell = str_replace('<!-- ROOT ELEMENT -->', $rootelement, $eventShell); ## Remove left over placeholders $eventShell = preg_replace(array('/<!--[\\w ]++-->/'), '', $eventShell); if ($this->_context[0] == 'new') { /** * Prior to creating an Event, the file path where it will be written to * is provided and well as the contents of that file. * * @delegate EventsPreCreate * @since Symphony 2.2 * @param string $context * '/blueprints/events/' * @param string $file * The path to the Event file * @param string $contents * The contents for this Event as a string passed by reference * @param array $filters * An array of the filters attached to this event */ Symphony::ExtensionManager()->notifyMembers('EventPreCreate', '/blueprints/events/', array('file' => $file, 'contents' => &$eventShell, 'filters' => $filters)); } else { /** * Prior to editing an Event, the file path where it will be written to * is provided and well as the contents of that file. * * @delegate EventPreEdit * @since Symphony 2.2 * @param string $context * '/blueprints/events/' * @param string $file * The path to the Event file * @param string $contents * The contents for this Event as a string passed by reference * @param array $filters * An array of the filters attached to this event */ Symphony::ExtensionManager()->notifyMembers('EventPreEdit', '/blueprints/events/', array('file' => $file, 'contents' => &$eventShell, 'filters' => $filters)); } // Write the file if (!is_writable(dirname($file)) || !($write = General::writeFile($file, $eventShell, Symphony::Configuration()->get('write_mode', 'file')))) { $this->pageAlert(__('Failed to write Event to <code>%s</code>. Please check permissions.', array(EVENTS)), Alert::ERROR); } else { if ($queueForDeletion) { General::deleteFile($queueForDeletion); $sql = "SELECT * FROM `tbl_pages` WHERE `events` REGEXP '[[:<:]]" . $existing_handle . "[[:>:]]' "; $pages = Symphony::Database()->fetch($sql); if (is_array($pages) && !empty($pages)) { foreach ($pages as $page) { $page['events'] = preg_replace('/\\b' . $existing_handle . '\\b/i', $classname, $page['events']); Symphony::Database()->update($page, 'tbl_pages', "`id` = '" . $page['id'] . "'"); } } } if ($this->_context[0] == 'new') { /** * After creating the Event, the path to the Event file is provided * * @delegate EventPostCreate * @since Symphony 2.2 * @param string $context * '/blueprints/events/' * @param string $file * The path to the Event file */ Symphony::ExtensionManager()->notifyMembers('EventPostCreate', '/blueprints/events/', array('file' => $file)); } else { /** * After editing the Event, the path to the Event file is provided * * @delegate EventPostEdit * @since Symphony 2.2 * @param string $context * '/blueprints/events/' * @param string $file * The path to the Event file */ Symphony::ExtensionManager()->notifyMembers('EventPostEdit', '/blueprints/events/', array('file' => $file)); } redirect(SYMPHONY_URL . '/blueprints/events/edit/' . $classname . '/' . ($this->_context[0] == 'new' ? 'created' : 'saved') . '/'); } } }
public function action() { $this->_existing_file = isset($this->_context[1]) ? $this->_context[1] . '.xsl' : NULL; if (array_key_exists('save', $_POST['action']) || array_key_exists('done', $_POST['action'])) { $fields = $_POST['fields']; $this->_errors = array(); if (!isset($fields['name']) || trim($fields['name']) == '') { $this->_errors['name'] = __('Name is a required field.'); } if (!isset($fields['body']) || trim($fields['body']) == '') { $this->_errors['body'] = __('Body is a required field.'); } elseif (!General::validateXML($fields['body'], $errors, false, new XSLTProcess())) { $this->_errors['body'] = __('This document is not well formed. The following error was returned: <code>%s</code>', array($errors[0]['message'])); } $fields['name'] = Lang::createFilename($fields['name']); if (General::right($fields['name'], 4) != '.xsl') { $fields['name'] .= '.xsl'; } $file = UTILITIES . '/' . $fields['name']; ##Duplicate if ($this->_context[0] == 'edit' && ($this->_existing_file != $fields['name'] && is_file($file))) { $this->_errors['name'] = __('A Utility with that name already exists. Please choose another.'); } elseif ($this->_context[0] == 'new' && is_file($file)) { $this->_errors['name'] = __('A Utility with that name already exists. Please choose another.'); } if (empty($this->_errors)) { if ($this->_context[0] == 'new') { /** * Just before the Utility has been created * * @delegate UtilityPreCreate * @since Symphony 2.2 * @param string $context * '/blueprints/utilities/' * @param string $file * The path to the Utility file * @param string $contents * The contents of the `$fields['body']`, passed by reference */ Symphony::ExtensionManager()->notifyMembers('UtilityPreCreate', '/blueprints/utilities/', array('file' => $file, 'contents' => &$fields['body'])); } else { /** * Just before the Utility has been updated * * @delegate UtilityPreEdit * @since Symphony 2.2 * @param string $context * '/blueprints/utilities/' * @param string $file * The path to the Utility file * @param string $contents * The contents of the `$fields['body']`, passed by reference */ Symphony::ExtensionManager()->notifyMembers('UtilityPreEdit', '/blueprints/utilities/', array('file' => $file, 'contents' => &$fields['body'])); } ##Write the file if (!($write = General::writeFile($file, $fields['body'], Symphony::Configuration()->get('write_mode', 'file')))) { $this->pageAlert(__('Utility could not be written to disk. Please check permissions on <code>/workspace/utilities</code>.'), Alert::ERROR); } else { ## Remove any existing file if the filename has changed if ($this->_existing_file && $file != UTILITIES . '/' . $this->_existing_file) { General::deleteFile(UTILITIES . '/' . $this->_existing_file); } if ($this->_context[0] == 'new') { /** * Just after the Utility has been written to disk * * @delegate UtilityPostCreate * @since Symphony 2.2 * @param string $context * '/blueprints/utilities/' * @param string $file * The path to the Utility file */ Symphony::ExtensionManager()->notifyMembers('UtilityPostCreate', '/blueprints/utilities/', array('file' => $file)); } else { /** * Just after a Utility has been edited and written to disk * * @delegate UtilityPostEdit * @since Symphony 2.2 * @param string $context * '/blueprints/utilities/' * @param string $file * The path to the Utility file */ Symphony::ExtensionManager()->notifyMembers('UtilityPostEdit', '/blueprints/utilities/', array('file' => $file)); } redirect(SYMPHONY_URL . '/blueprints/utilities/edit/' . str_replace('.xsl', '', $fields['name']) . '/' . ($this->_context[0] == 'new' ? 'created' : 'saved') . '/'); } } } elseif ($this->_context[0] == 'edit' && @array_key_exists('delete', $_POST['action'])) { /** * Prior to deleting the Utility * * @delegate UtilityPreDelete * @since Symphony 2.2 * @param string $context * '/blueprints/utilities/' * @param string $file * The path to the Utility file */ Symphony::ExtensionManager()->notifyMembers('UtilityPreDelete', '/blueprints/utilities/', array('file' => $this->_existing_file)); General::deleteFile(UTILITIES . '/' . $this->_existing_file); redirect(SYMPHONY_URL . '/blueprints/components/'); } }
public function delete($datasource) { /* TODO: Upon deletion of the event, views need to be updated to remove it's associated with the event */ if (!$datasource instanceof DataSource) { $datasource = Datasource::loadFromHandle($datasource); } $handle = $datasource->handle; if (!$datasource->allowEditorToParse()) { throw new DataSourceException(__('Datasource cannot be deleted, the Editor does not have permission.')); } return General::deleteFile(DATASOURCES . "/{$handle}.php"); }
/** * Given a Page's `$path` and `$handle`, this function will remove * it's templates from the `PAGES` directory returning boolean on * completion * * @param string $page_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 $handle * A Page handle, generated using `PageManager::createHandle`. * @return boolean */ public static function deletePageFiles($page_path, $handle) { $file = PageManager::resolvePageFileLocation($page_path, $handle); // Nothing to do: if (!file_exists($file)) { return true; } // Delete it: if (General::deleteFile($file)) { return true; } return false; }
/** * Uploads the zip file to a target directory using the current date. The function * then extracts the content of the zip to the same folder, removes the zip file * after extraction and calls the openExtracted function to append the files to the * $files array. * * @return boolean * True if the $files array is not empty, false otherwise */ public function beginProcess() { if (empty($_FILES['fields']['name']['file'])) { return false; } $target = $this->getTarget() . DateTimeObj::get('d-m-Y'); foreach ($_FILES['fields']['error'] as $key => $error) { if ($error == UPLOAD_ERR_OK) { $tmp = $_FILES['fields']['tmp_name'][$key]; // Upload files to /workspace/uploads/bulkimporter/11-11-2010 $file = $_FILES['fields']['name'][$key]; if (!file_exists($target)) { General::realiseDirectory($target); } if (!General::uploadFile($target, $file, $tmp)) { return false; } $uploadedZipPath = $target . "/" . $file; } } $zipManager = new ZipArchive(); $zip = $zipManager->open($uploadedZipPath); // The directory where the extracted zip contents should go to. $this->extracted_directory = $target; $path = ''; if ($this->archive_is_parent) { $path = '/' . preg_replace('/\\.[^\\.]+$/', '', basename($uploadedZipPath)); $this->extracted_archive = basename($path); if (!file_exists($this->extracted_directory . $path)) { General::realiseDirectory($this->extracted_directory . $path); } } $zipManager->extractTo($this->extracted_directory . $path); $zipManager->close(); // Delete the zip file General::deleteFile($uploadedZipPath); // Add the extracted files to the $files array $this->openExtracted($this->extracted_directory); return count($this->files) != 0; }
protected function __actionDelete($utils, $redirect) { $success = true; if (!is_array($utils)) { $utils = array($utils); } foreach ($utils as $util) { General::deleteFile(UTILITIES . '/' . $util); } if ($success) { redirect($redirect); } }
/** * 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()); } } } }
public function __formAction() { $fields = $_POST['fields']; $this->_errors = array(); $providers = Symphony::ExtensionManager()->getProvidersOf(iProvider::EVENT); $providerClass = null; if (trim($fields['name']) == '') { $this->_errors['name'] = __('This is a required field'); } if (trim($fields['source']) == '') { $this->_errors['source'] = __('This is a required field'); } $filters = isset($fields['filters']) ? $fields['filters'] : array(); // See if a Provided Datasource is saved if (!empty($providers)) { foreach ($providers as $providerClass => $provider) { if ($fields['source'] == call_user_func(array($providerClass, 'getSource'))) { call_user_func_array(array($providerClass, 'validate'), array(&$fields, &$this->_errors)); break; } unset($providerClass); } } $classname = Lang::createHandle($fields['name'], 255, '_', false, true, array('@^[^a-z\\d]+@i' => '', '/[^\\w-\\.]/i' => '')); $rootelement = str_replace('_', '-', $classname); $extends = 'SectionEvent'; // Check to make sure the classname is not empty after handlisation. if (empty($classname) && !isset($this->_errors['name'])) { $this->_errors['name'] = __('Please ensure name contains at least one Latin-based character.', array($classname)); } $file = EVENTS . '/event.' . $classname . '.php'; $isDuplicate = false; $queueForDeletion = NULL; if ($this->_context[0] == 'new' && is_file($file)) { $isDuplicate = true; } else { if ($this->_context[0] == 'edit') { $existing_handle = $this->_context[1]; if ($classname != $existing_handle && is_file($file)) { $isDuplicate = true; } else { if ($classname != $existing_handle) { $queueForDeletion = EVENTS . '/event.' . $existing_handle . '.php'; } } } } // Duplicate if ($isDuplicate) { $this->_errors['name'] = __('An Event with the name %s already exists', array('<code>' . $classname . '</code>')); } if (empty($this->_errors)) { $multiple = in_array('expect-multiple', $filters); $elements = NULL; $placeholder = '<!-- GRAB -->'; $source = $fields['source']; $params = array('rootelement' => $rootelement); $about = array('name' => $fields['name'], 'version' => 'Symphony ' . Symphony::Configuration()->get('version', 'symphony'), 'release date' => DateTimeObj::getGMT('c'), 'author name' => Administration::instance()->Author->getFullName(), 'author website' => URL, 'author email' => Administration::instance()->Author->get('email')); // If there is a provider, get their template if ($providerClass) { $eventShell = file_get_contents(call_user_func(array($providerClass, 'getTemplate'))); } else { $eventShell = file_get_contents($this->getTemplate('blueprints.event')); $about['trigger condition'] = $rootelement; } $this->__injectAboutInformation($eventShell, $about); // Replace the name $eventShell = str_replace('<!-- CLASS NAME -->', $classname, $eventShell); // Build the templates if ($providerClass) { $eventShell = call_user_func(array($providerClass, 'prepare'), $fields, $params, $eventShell); } else { $this->__injectFilters($eventShell, $filters); // Add Documentation $documentation = NULL; $documentation_parts = array(); $documentation_parts[] = new XMLElement('h3', __('Success and Failure XML Examples')); $documentation_parts[] = new XMLElement('p', __('When saved successfully, the following XML will be returned:')); if ($multiple) { $code = new XMLElement($rootelement); $entry = new XMLElement('entry', NULL, array('index' => '0', 'result' => 'success', 'type' => 'create | edit')); $entry->appendChild(new XMLElement('message', __('Entry [created | edited] successfully.'))); $code->appendChild($entry); } else { $code = new XMLElement($rootelement, NULL, array('result' => 'success', 'type' => 'create | edit')); $code->appendChild(new XMLElement('message', __('Entry [created | edited] successfully.'))); } $documentation_parts[] = self::processDocumentationCode($code); $documentation_parts[] = new XMLElement('p', __('When an error occurs during saving, due to either missing or invalid fields, the following XML will be returned') . ($multiple ? ' (<strong> ' . __('Notice that it is possible to get mixtures of success and failure messages when using the ‘Allow Multiple’ option') . '</strong>)' : NULL) . ':'); if ($multiple) { $code = new XMLElement($rootelement); $entry = new XMLElement('entry', NULL, array('index' => '0', 'result' => 'error')); $entry->appendChild(new XMLElement('message', __('Entry encountered errors when saving.'))); $entry->appendChild(new XMLElement('field-name', NULL, array('type' => 'invalid | missing'))); $code->appendChild($entry); $entry = new XMLElement('entry', NULL, array('index' => '1', 'result' => 'success', 'type' => 'create | edit')); $entry->appendChild(new XMLElement('message', __('Entry [created | edited] successfully.'))); $code->appendChild($entry); } else { $code = new XMLElement($rootelement, NULL, array('result' => 'error')); $code->appendChild(new XMLElement('message', __('Entry encountered errors when saving.'))); $code->appendChild(new XMLElement('field-name', NULL, array('type' => 'invalid | missing'))); } $code->setValue('...', false); $documentation_parts[] = self::processDocumentationCode($code); if (is_array($filters) && !empty($filters)) { $documentation_parts[] = new XMLElement('p', __('The following is an example of what is returned if any options return an error:')); $code = new XMLElement($rootelement, NULL, array('result' => 'error')); $code->appendChild(new XMLElement('message', __('Entry encountered errors when saving.'))); $code->appendChild(new XMLElement('filter', NULL, array('name' => 'admin-only', 'status' => 'failed'))); $code->appendChild(new XMLElement('filter', __('Recipient not found'), array('name' => 'send-email', 'status' => 'failed'))); $code->setValue('...', false); $documentation_parts[] = self::processDocumentationCode($code); } $documentation_parts[] = new XMLElement('h3', __('Example Front-end Form Markup')); $documentation_parts[] = new XMLElement('p', __('This is an example of the form markup you can use on your frontend:')); $container = new XMLElement('form', NULL, array('method' => 'post', 'action' => '', 'enctype' => 'multipart/form-data')); $container->appendChild(Widget::Input('MAX_FILE_SIZE', (string) min(ini_size_to_bytes(ini_get('upload_max_filesize')), Symphony::Configuration()->get('max_upload_size', 'admin')), 'hidden')); if (is_numeric($fields['source'])) { $section = SectionManager::fetch($fields['source']); if ($section instanceof Section) { $section_fields = $section->fetchFields(); if (is_array($section_fields) && !empty($section_fields)) { foreach ($section_fields as $f) { if ($f->getExampleFormMarkup() instanceof XMLElement) { $container->appendChild($f->getExampleFormMarkup()); } } } } } $container->appendChild(Widget::Input('action[' . $rootelement . ']', __('Submit'), 'submit')); $code = $container->generate(true); $documentation_parts[] = self::processDocumentationCode($multiple ? str_replace('fields[', 'fields[0][', $code) : $code); $documentation_parts[] = new XMLElement('p', __('To edit an existing entry, include the entry ID value of the entry in the form. This is best as a hidden field like so:')); $documentation_parts[] = self::processDocumentationCode(Widget::Input('id' . ($multiple ? '[0]' : NULL), '23', 'hidden')); $documentation_parts[] = new XMLElement('p', __('To redirect to a different location upon a successful save, include the redirect location in the form. This is best as a hidden field like so, where the value is the URL to redirect to:')); $documentation_parts[] = self::processDocumentationCode(Widget::Input('redirect', URL . '/success/', 'hidden')); if (in_array('send-email', $filters)) { $documentation_parts[] = new XMLElement('h3', __('Send Notification Email')); $documentation_parts[] = new XMLElement('p', __('Upon the event successfully saving the entry, this option takes input from the form and send an email to the desired recipient.') . ' <strong>' . __('It currently does not work with ‘Allow Multiple’') . '</strong>. ' . __('The following are the recognised fields:')); $documentation_parts[] = self::processDocumentationCode('send-email[sender-email] // ' . __('Optional') . PHP_EOL . 'send-email[sender-name] // ' . __('Optional') . PHP_EOL . 'send-email[reply-to-email] // ' . __('Optional') . PHP_EOL . 'send-email[reply-to-name] // ' . __('Optional') . PHP_EOL . 'send-email[subject]' . PHP_EOL . 'send-email[body]' . PHP_EOL . 'send-email[recipient] // ' . __('list of comma-separated author usernames.')); $documentation_parts[] = new XMLElement('p', __('All of these fields can be set dynamically using the exact field name of another field in the form as shown below in the example form:')); $documentation_parts[] = self::processDocumentationCode('<form action="" method="post"> <fieldset> <label>' . __('Name') . ' <input type="text" name="fields[author]" value="" /></label> <label>' . __('Email') . ' <input type="text" name="fields[email]" value="" /></label> <label>' . __('Message') . ' <textarea name="fields[message]" rows="5" cols="21"></textarea></label> <input name="send-email[sender-email]" value="fields[email]" type="hidden" /> <input name="send-email[sender-name]" value="fields[author]" type="hidden" /> <input name="send-email[reply-to-email]" value="fields[email]" type="hidden" /> <input name="send-email[reply-to-name]" value="fields[author]" type="hidden" /> <input name="send-email[subject]" value="You are being contacted" type="hidden" /> <input name="send-email[body]" value="fields[message]" type="hidden" /> <input name="send-email[recipient]" value="fred" type="hidden" /> <input id="submit" type="submit" name="action[save-contact-form]" value="Send" /> </fieldset> </form>'); } /** * Allows adding documentation for new filters. A reference to the $documentation * array is provided, along with selected filters * @delegate AppendEventFilterDocumentation * @param string $context * '/blueprints/events/(edit|new|info)/' * @param array $selected * An array of all the selected filters for this Event * @param array $documentation * An array of all the documentation XMLElements, passed by reference */ Symphony::ExtensionManager()->notifyMembers('AppendEventFilterDocumentation', '/blueprints/events/' . $this->_context[0] . '/', array('selected' => $filters, 'documentation' => &$documentation_parts)); $documentation = join(PHP_EOL, array_map(create_function('$x', 'return rtrim($x->generate(true, 4));'), $documentation_parts)); $documentation = str_replace('\'', '\\\'', $documentation); $eventShell = str_replace('<!-- CLASS EXTENDS -->', $extends, $eventShell); $eventShell = str_replace('<!-- DOCUMENTATION -->', General::tabsToSpaces($documentation, 2), $eventShell); } $eventShell = str_replace('<!-- ROOT ELEMENT -->', $rootelement, $eventShell); $eventShell = str_replace('<!-- CLASS NAME -->', $classname, $eventShell); $eventShell = str_replace('<!-- SOURCE -->', $source, $eventShell); // Remove left over placeholders $eventShell = preg_replace(array('/<!--[\\w ]++-->/'), '', $eventShell); if ($this->_context[0] == 'new') { /** * Prior to creating an Event, the file path where it will be written to * is provided and well as the contents of that file. * * @delegate EventsPreCreate * @since Symphony 2.2 * @param string $context * '/blueprints/events/' * @param string $file * The path to the Event file * @param string $contents * The contents for this Event as a string passed by reference * @param array $filters * An array of the filters attached to this event */ Symphony::ExtensionManager()->notifyMembers('EventPreCreate', '/blueprints/events/', array('file' => $file, 'contents' => &$eventShell, 'filters' => $filters)); } else { /** * Prior to editing an Event, the file path where it will be written to * is provided and well as the contents of that file. * * @delegate EventPreEdit * @since Symphony 2.2 * @param string $context * '/blueprints/events/' * @param string $file * The path to the Event file * @param string $contents * The contents for this Event as a string passed by reference * @param array $filters * An array of the filters attached to this event */ Symphony::ExtensionManager()->notifyMembers('EventPreEdit', '/blueprints/events/', array('file' => $file, 'contents' => &$eventShell, 'filters' => $filters)); } // Write the file if (!is_writable(dirname($file)) || !($write = General::writeFile($file, $eventShell, Symphony::Configuration()->get('write_mode', 'file')))) { $this->pageAlert(__('Failed to write Event to disk.') . ' ' . __('Please check permissions on %s.', array('<code>/workspace/events</code>')), Alert::ERROR); } else { if ($queueForDeletion) { General::deleteFile($queueForDeletion); $pages = PageManager::fetch(false, array('events', 'id'), array("\n\t\t\t\t\t\t\t`events` REGEXP '[[:<:]]" . $existing_handle . "[[:>:]]'\n\t\t\t\t\t\t")); if (is_array($pages) && !empty($pages)) { foreach ($pages as $page) { $page['events'] = preg_replace('/\\b' . $existing_handle . '\\b/i', $classname, $page['events']); PageManager::edit($page['id'], $page); } } } if ($this->_context[0] == 'new') { /** * After creating the Event, the path to the Event file is provided * * @delegate EventPostCreate * @since Symphony 2.2 * @param string $context * '/blueprints/events/' * @param string $file * The path to the Event file */ Symphony::ExtensionManager()->notifyMembers('EventPostCreate', '/blueprints/events/', array('file' => $file)); } else { /** * After editing the Event, the path to the Event file is provided * * @delegate EventPostEdit * @since Symphony 2.2 * @param string $context * '/blueprints/events/' * @param string $file * The path to the Event file * @param string $previous_file * The path of the previous Event file in the case where an Event may * have been renamed. To get the handle from this value, see * `EventManager::__getHandleFromFilename` */ Symphony::ExtensionManager()->notifyMembers('EventPostEdit', '/blueprints/events/', array('file' => $file, 'previous_file' => $queueForDeletion ? $queueForDeletion : null)); } redirect(SYMPHONY_URL . '/blueprints/events/edit/' . $classname . '/' . ($this->_context[0] == 'new' ? 'created' : 'saved') . '/'); } } }
/** * The function handles the rotation of the log files. By default it will open * the current log file, 'main', which is written to `$_log_path` and * check it's file size doesn't exceed `$_max_size`. If it does, the log * is appended with a date stamp and if `$_archive` has been set, it will * be archived and stored. If a log file has exceeded it's size, or `Log::OVERWRITE` * flag is set, the existing log file is removed and a new one created. Essentially, * if a log file has not reached it's `$_max_size` and the the flag is not * set to `Log::OVERWRITE`, this function does nothing. * * @link http://au.php.net/manual/en/function.intval.php * @param integer $flag * One of the Log constants, either `Log::APPEND` or `Log::OVERWRITE` * By default this is `Log::APPEND` * @param integer $mode * The file mode used to apply to the archived log, by default this is 0777. Note that this * parameter is modified using PHP's intval function with base 8. * @return integer * Returns 1 if the log was overwritten, or 2 otherwise. */ public function open($flag = self::APPEND, $mode = 0777) { if (!file_exists($this->_log_path)) { $flag = self::OVERWRITE; } if ($flag == self::APPEND && file_exists($this->_log_path) && is_readable($this->_log_path)) { if ($this->_max_size > 0 && filesize($this->_log_path) > $this->_max_size) { $flag = self::OVERWRITE; if ($this->_archive) { $this->close(); $file = $this->_log_path . DateTimeObj::get('Ymdh') . '.gz'; $handle = gzopen($file, 'w9'); gzwrite($handle, file_get_contents($this->_log_path)); gzclose($handle); chmod($file, intval($mode, 8)); } } } if ($flag == self::OVERWRITE) { if (file_exists($this->_log_path) && is_writable($this->_log_path)) { General::deleteFile($this->_log_path); } $this->writeToLog('============================================', true); $this->writeToLog('Log Created: ' . DateTimeObj::get('c'), true); $this->writeToLog('============================================', true); @chmod($this->_log_path, intval($mode, 8)); return 1; } return 2; }
function processRawFieldData($data, &$status, $simulate = false, $entry_id = NULL) { $status = self::__OK__; ## Its not an array, so just retain the current data and return if (!is_array($data)) { $status = self::__OK__; // Do a simple reconstruction of the file meta information. This is a workaround for // bug which causes all meta information to be dropped return array('file' => $data, 'mimetype' => self::__sniffMIMEType($data), 'size' => filesize(WORKSPACE . $data), 'meta' => serialize(self::getMetaInfo(WORKSPACE . $data, self::__sniffMIMEType($data)))); } if ($simulate) { return; } if ($data['error'] == UPLOAD_ERR_NO_FILE || $data['error'] != UPLOAD_ERR_OK) { return; } ## Sanitize the filename $data['name'] = Lang::createFilename($data['name']); ## Upload the new file $abs_path = DOCROOT . '/' . trim($this->get('destination'), '/'); $rel_path = str_replace('/workspace', '', $this->get('destination')); if (!General::uploadFile($abs_path, $data['name'], $data['tmp_name'], $this->_engine->Configuration->get('write_mode', 'file'))) { $message = __('There was an error while trying to upload the file <code>%1$s</code> to the target directory <code>%2$s</code>.', array($data['name'], 'workspace/' . $rel_path)); $status = self::__ERROR_CUSTOM__; return; } if ($entry_id) { $row = $this->Database->fetchRow(0, "SELECT * FROM `tbl_entries_data_" . $this->get('id') . "` WHERE `entry_id` = '{$entry_id}' LIMIT 1"); $existing_file = $abs_path . '/' . basename($row['file']); General::deleteFile($existing_file); } $status = self::__OK__; $file = rtrim($rel_path, '/') . '/' . trim($data['name'], '/'); return array('file' => $file, 'size' => $data['size'], 'mimetype' => $data['type'], 'meta' => serialize(self::getMetaInfo(WORKSPACE . $file, $data['type']))); }
public static function cleanup() { $sections = Symphony::Database()->fetchCol('handle', "SELECT * FROM `tbl_sections`"); $files = General::listStructure(WORKSPACE . '/sections', array(), false); $exclude = array(); if (is_array($files['filelist']) && !empty($files['filelist'])) { foreach ($files['filelist'] as $filename) { $section = str_replace('.xml', '', $filename); if (!in_array($section, $sections)) { $exclude[] = $section; } } } if (!empty($exclude)) { foreach ($exclude as $filename) { General::deleteFile(WORKSPACE . "/sections/{$filename}.xml"); } } }
public function processRawFieldData($data, &$status, &$message = null, $simulate = false, $entry_id = null) { $status = self::__OK__; // No file given, save empty data: if ($data === null) { return array('file' => null, 'mimetype' => null, 'size' => null, 'meta' => null); } // Its not an array, so just retain the current data and return: if (is_array($data) === false) { $file = $this->getFilePath(basename($data)); $result = array('file' => $data, 'mimetype' => null, 'size' => null, 'meta' => null); // Grab the existing entry data to preserve the MIME type and size information if (isset($entry_id)) { $row = Symphony::Database()->fetchRow(0, sprintf("SELECT `file`, `mimetype`, `size`, `meta` FROM `tbl_entries_data_%d` WHERE `entry_id` = %d", $this->get('id'), $entry_id)); if (empty($row) === false) { $result = $row; } } // Found the file, add any missing meta information: if (file_exists($file) && is_readable($file)) { if (empty($result['mimetype'])) { $result['mimetype'] = General::getMimeType($file); } if (empty($result['size'])) { $result['size'] = filesize($file); } if (empty($result['meta'])) { $result['meta'] = serialize(self::getMetaInfo($file, $result['mimetype'])); } // The file was not found, or is unreadable: } else { $message = __('The file uploaded is no longer available. Please check that it exists, and is readable.'); $status = self::__INVALID_FIELDS__; } return $result; } if ($simulate && is_null($entry_id)) { return $data; } // Check to see if the entry already has a file associated with it: if (is_null($entry_id) === false) { $row = Symphony::Database()->fetchRow(0, sprintf("SELECT *\n FROM `tbl_entries_data_%s`\n WHERE `entry_id` = %d\n LIMIT 1", $this->get('id'), $entry_id)); $existing_file = isset($row['file']) ? $this->getFilePath($row['file']) : null; // File was removed: if ($data['error'] == UPLOAD_ERR_NO_FILE && !is_null($existing_file) && is_file($existing_file)) { General::deleteFile($existing_file); } } // Do not continue on upload error: if ($data['error'] == UPLOAD_ERR_NO_FILE || $data['error'] != UPLOAD_ERR_OK) { return false; } // Where to upload the new file? $abs_path = DOCROOT . '/' . trim($this->get('destination'), '/'); $rel_path = str_replace('/workspace', '', $this->get('destination')); // Sanitize the filename $data['name'] = Lang::createFilename($data['name']); // If a file already exists, then rename the file being uploaded by // adding `_1` to the filename. If `_1` already exists, the logic // will keep adding 1 until a filename is available (#672) if (file_exists($abs_path . '/' . $data['name'])) { $extension = General::getExtension($data['name']); $new_file = substr($abs_path . '/' . $data['name'], 0, -1 - strlen($extension)); $renamed_file = $new_file; $count = 1; do { $renamed_file = $new_file . '_' . $count . '.' . $extension; $count++; } while (file_exists($renamed_file)); // Extract the name filename from `$renamed_file`. $data['name'] = str_replace($abs_path . '/', '', $renamed_file); } $file = $this->getFilePath($data['name']); // Attempt to upload the file: $uploaded = General::uploadFile($abs_path, $data['name'], $data['tmp_name'], Symphony::Configuration()->get('write_mode', 'file')); if ($uploaded === false) { $message = __('There was an error while trying to upload the file %1$s to the target directory %2$s.', array('<code>' . $data['name'] . '</code>', '<code>workspace/' . ltrim($rel_path, '/') . '</code>')); $status = self::__ERROR_CUSTOM__; return false; } // File has been replaced: if (isset($existing_file) && $existing_file !== $file && is_file($existing_file)) { General::deleteFile($existing_file); } // Get the mimetype, don't trust the browser. RE: #1609 $data['type'] = General::getMimeType($file); return array('file' => basename($file), 'size' => $data['size'], 'mimetype' => $data['type'], 'meta' => serialize(self::getMetaInfo($file, $data['type']))); }
public function __formAction() { $fields = $_POST['fields']; $this->_errors = array(); $providers = Symphony::ExtensionManager()->getProvidersOf(iProvider::EVENT); $providerClass = null; if (trim($fields['name']) == '') { $this->_errors['name'] = __('This is a required field'); } if (trim($fields['source']) == '') { $this->_errors['source'] = __('This is a required field'); } $filters = isset($fields['filters']) ? $fields['filters'] : array(); // See if a Provided Datasource is saved if (!empty($providers)) { foreach ($providers as $providerClass => $provider) { if ($fields['source'] == call_user_func(array($providerClass, 'getSource'))) { call_user_func_array(array($providerClass, 'validate'), array(&$fields, &$this->_errors)); break; } unset($providerClass); } } $classname = Lang::createHandle($fields['name'], 255, '_', false, true, array('@^[^a-z\\d]+@i' => '', '/[^\\w-\\.]/i' => '')); $rootelement = str_replace('_', '-', $classname); $extends = 'SectionEvent'; // Check to make sure the classname is not empty after handlisation. if (empty($classname) && !isset($this->_errors['name'])) { $this->_errors['name'] = __('Please ensure name contains at least one Latin-based character.', array($classname)); } $file = EVENTS . '/event.' . $classname . '.php'; $isDuplicate = false; $queueForDeletion = null; if ($this->_context[0] == 'new' && is_file($file)) { $isDuplicate = true; } elseif ($this->_context[0] == 'edit') { $existing_handle = $this->_context[1]; if ($classname != $existing_handle && is_file($file)) { $isDuplicate = true; } elseif ($classname != $existing_handle) { $queueForDeletion = EVENTS . '/event.' . $existing_handle . '.php'; } } // Duplicate if ($isDuplicate) { $this->_errors['name'] = __('An Event with the name %s already exists', array('<code>' . $classname . '</code>')); } if (empty($this->_errors)) { $multiple = in_array('expect-multiple', $filters); $elements = null; $placeholder = '<!-- GRAB -->'; $source = $fields['source']; $params = array('rootelement' => $rootelement); $about = array('name' => $fields['name'], 'version' => 'Symphony ' . Symphony::Configuration()->get('version', 'symphony'), 'release date' => DateTimeObj::getGMT('c'), 'author name' => Symphony::Author()->getFullName(), 'author website' => URL, 'author email' => Symphony::Author()->get('email')); // If there is a provider, get their template if ($providerClass) { $eventShell = file_get_contents(call_user_func(array($providerClass, 'getTemplate'))); } else { $eventShell = file_get_contents($this->getTemplate('blueprints.event')); $about['trigger condition'] = $rootelement; } $this->__injectAboutInformation($eventShell, $about); // Replace the name $eventShell = str_replace('<!-- CLASS NAME -->', $classname, $eventShell); // Build the templates if ($providerClass) { $eventShell = call_user_func(array($providerClass, 'prepare'), $fields, $params, $eventShell); } else { $this->__injectFilters($eventShell, $filters); // Add Documentation require_once CONTENT . '/content.ajaxeventdocumentation.php'; $ajaxEventDoc = new contentAjaxEventDocumentation(); $documentation = null; $doc_parts = array(); // Add Documentation (Success/Failure) $ajaxEventDoc->addEntrySuccessDoc($doc_parts, $rootelement, $fields['source'], $filters); $ajaxEventDoc->addEntryFailureDoc($doc_parts, $rootelement, $fields['source'], $filters); // Filters $ajaxEventDoc->addDefaultFiltersDoc($doc_parts, $rootelement, $fields['source'], $filters); // Frontend Markup $ajaxEventDoc->addFrontendMarkupDoc($doc_parts, $rootelement, $fields['source'], $filters); $ajaxEventDoc->addSendMailFilterDoc($doc_parts, $rootelement, $fields['source'], $filters); /** * Allows adding documentation for new filters. A reference to the $documentation * array is provided, along with selected filters * @delegate AppendEventFilterDocumentation * @param string $context * '/blueprints/events/(edit|new|info)/' * @param array $selected * An array of all the selected filters for this Event * @param array $documentation * An array of all the documentation XMLElements, passed by reference */ Symphony::ExtensionManager()->notifyMembers('AppendEventFilterDocumentation', '/blueprints/events/' . $rootelement . '/', array('selected' => $filters, 'documentation' => &$doc_parts)); $documentation = join(PHP_EOL, array_map(create_function('$x', 'return rtrim($x->generate(true, 4));'), $doc_parts)); $documentation = str_replace('\'', '\\\'', $documentation); $eventShell = str_replace('<!-- CLASS EXTENDS -->', $extends, $eventShell); $eventShell = str_replace('<!-- DOCUMENTATION -->', General::tabsToSpaces($documentation, 4), $eventShell); } $eventShell = str_replace('<!-- ROOT ELEMENT -->', $rootelement, $eventShell); $eventShell = str_replace('<!-- CLASS NAME -->', $classname, $eventShell); $eventShell = str_replace('<!-- SOURCE -->', $source, $eventShell); // Remove left over placeholders $eventShell = preg_replace(array('/<!--[\\w ]++-->/'), '', $eventShell); if ($this->_context[0] == 'new') { /** * Prior to creating an Event, the file path where it will be written to * is provided and well as the contents of that file. * * @delegate EventsPreCreate * @since Symphony 2.2 * @param string $context * '/blueprints/events/' * @param string $file * The path to the Event file * @param string $contents * The contents for this Event as a string passed by reference * @param array $filters * An array of the filters attached to this event */ Symphony::ExtensionManager()->notifyMembers('EventPreCreate', '/blueprints/events/', array('file' => $file, 'contents' => &$eventShell, 'filters' => $filters)); } else { /** * Prior to editing an Event, the file path where it will be written to * is provided and well as the contents of that file. * * @delegate EventPreEdit * @since Symphony 2.2 * @param string $context * '/blueprints/events/' * @param string $file * The path to the Event file * @param string $contents * The contents for this Event as a string passed by reference * @param array $filters * An array of the filters attached to this event */ Symphony::ExtensionManager()->notifyMembers('EventPreEdit', '/blueprints/events/', array('file' => $file, 'contents' => &$eventShell, 'filters' => $filters)); } // Write the file if (!is_writable(dirname($file)) || !($write = General::writeFile($file, $eventShell, Symphony::Configuration()->get('write_mode', 'file')))) { $this->pageAlert(__('Failed to write Event to disk.') . ' ' . __('Please check permissions on %s.', array('<code>/workspace/events</code>')), Alert::ERROR); // Write successful } else { if (function_exists('opcache_invalidate')) { opcache_invalidate($file, true); } // Attach this event to pages $connections = $fields['connections']; ResourceManager::setPages(RESOURCE_TYPE_EVENT, is_null($existing_handle) ? $classname : $existing_handle, $connections); if ($queueForDeletion) { General::deleteFile($queueForDeletion); $pages = PageManager::fetch(false, array('events', 'id'), array("\n `events` REGEXP '[[:<:]]" . $existing_handle . "[[:>:]]'\n ")); if (is_array($pages) && !empty($pages)) { foreach ($pages as $page) { $page['events'] = preg_replace('/\\b' . $existing_handle . '\\b/i', $classname, $page['events']); PageManager::edit($page['id'], $page); } } } if ($this->_context[0] == 'new') { /** * After creating the Event, the path to the Event file is provided * * @delegate EventPostCreate * @since Symphony 2.2 * @param string $context * '/blueprints/events/' * @param string $file * The path to the Event file */ Symphony::ExtensionManager()->notifyMembers('EventPostCreate', '/blueprints/events/', array('file' => $file)); } else { /** * After editing the Event, the path to the Event file is provided * * @delegate EventPostEdit * @since Symphony 2.2 * @param string $context * '/blueprints/events/' * @param string $file * The path to the Event file * @param string $previous_file * The path of the previous Event file in the case where an Event may * have been renamed. To get the handle from this value, see * `EventManager::__getHandleFromFilename` */ Symphony::ExtensionManager()->notifyMembers('EventPostEdit', '/blueprints/events/', array('file' => $file, 'previous_file' => $queueForDeletion ? $queueForDeletion : null)); } redirect(SYMPHONY_URL . '/blueprints/events/edit/' . $classname . '/' . ($this->_context[0] == 'new' ? 'created' : 'saved') . '/'); } } }
public function __formAction() { $fields = $_POST['fields']; $this->_errors = array(); $providers = Symphony::ExtensionManager()->getProvidersOf('data-sources'); $providerClass = null; if (trim($fields['name']) == '') { $this->_errors['name'] = __('This is a required field'); } if ($fields['source'] == 'static_xml') { if (trim($fields['static_xml']) == '') { $this->_errors['static_xml'] = __('This is a required field'); } else { $xml_errors = NULL; include_once TOOLKIT . '/class.xsltprocess.php'; General::validateXML($fields['static_xml'], $xml_errors, false, new XsltProcess()); if (!empty($xml_errors)) { $this->_errors['static_xml'] = __('XML is invalid'); } } } elseif ($fields['source'] == 'dynamic_xml') { if (trim($fields['dynamic_xml']['url']) == '') { $this->_errors['dynamic_xml']['url'] = __('This is a required field'); } // Use the TIMEOUT that was specified by the user for a real world indication $timeout = isset($fields['dynamic_xml']['timeout']) ? (int) $fields['dynamic_xml']['timeout'] : 6; // If there is a parameter in the URL, we can't validate the existence of the URL // as we don't have the environment details of where this datasource is going // to be executed. if (!preg_match('@{([^}]+)}@i', $fields['dynamic_xml']['url'])) { $valid_url = self::__isValidURL($fields['dynamic_xml']['url'], $timeout, $error); if ($valid_url) { $data = $valid_url['data']; } else { $this->_errors['dynamic_xml']['url'] = $error; } } if (trim($fields['dynamic_xml']['xpath']) == '') { $this->_errors['dynamic_xml']['xpath'] = __('This is a required field'); } if (!is_numeric($fields['dynamic_xml']['cache'])) { $this->_errors['dynamic_xml']['cache'] = __('Must be a valid number'); } elseif ($fields['dynamic_xml']['cache'] < 1) { $this->_errors['dynamic_xml']['cache'] = __('Must be greater than zero'); } } elseif (is_numeric($fields['source'])) { if (strlen(trim($fields['max_records'])) == 0 || is_numeric($fields['max_records']) && $fields['max_records'] < 1) { if (isset($fields['paginate_results'])) { $this->_errors['max_records'] = __('A result limit must be set'); } } else { if (!self::__isValidPageString($fields['max_records'])) { $this->_errors['max_records'] = __('Must be a valid number or parameter'); } } if (strlen(trim($fields['page_number'])) == 0 || is_numeric($fields['page_number']) && $fields['page_number'] < 1) { if (isset($fields['paginate_results'])) { $this->_errors['page_number'] = __('A page number must be set'); } } else { if (!self::__isValidPageString($fields['page_number'])) { $this->_errors['page_number'] = __('Must be a valid number or parameter'); } } } elseif (!empty($providers)) { foreach ($providers as $providerClass => $provider) { if ($fields['source'] == call_user_func(array($providerClass, 'getSource'))) { call_user_func(array($providerClass, 'validate'), &$fields, &$this->_errors); break; } unset($providerClass); } } $classname = Lang::createHandle($fields['name'], 255, '_', false, true, array('@^[^a-z\\d]+@i' => '', '/[^\\w-\\.]/i' => '')); $rootelement = str_replace('_', '-', $classname); // Check to make sure the classname is not empty after handlisation. if (empty($classname) && !isset($this->_errors['name'])) { $this->_errors['name'] = __('Please ensure name contains at least one Latin-based character.', array($classname)); } $file = DATASOURCES . '/data.' . $classname . '.php'; $isDuplicate = false; $queueForDeletion = NULL; if ($this->_context[0] == 'new' && is_file($file)) { $isDuplicate = true; } elseif ($this->_context[0] == 'edit') { $existing_handle = $this->_context[1]; if ($classname != $existing_handle && is_file($file)) { $isDuplicate = true; } elseif ($classname != $existing_handle) { $queueForDeletion = DATASOURCES . '/data.' . $existing_handle . '.php'; } } // Duplicate if ($isDuplicate) { $this->_errors['name'] = __('A Data source with the name %s already exists', array('<code>' . $classname . '</code>')); } if (empty($this->_errors)) { $filters = array(); $elements = NULL; $placeholder = '<!-- GRAB -->'; $source = $fields['source']; $params = array('rootelement' => $rootelement); $about = array('name' => $fields['name'], 'version' => 'Symphony ' . Symphony::Configuration()->get('version', 'symphony'), 'release date' => DateTimeObj::getGMT('c'), 'author name' => Administration::instance()->Author->getFullName(), 'author website' => URL, 'author email' => Administration::instance()->Author->get('email')); // If there is a provider, get their template if ($providerClass) { $dsShell = file_get_contents(call_user_func(array($providerClass, 'getTemplate'))); } else { $dsShell = file_get_contents($this->getTemplate('blueprints.datasource')); } // Author metadata self::injectAboutInformation($dsShell, $about); // Do dependencies, the template file must have <!-- CLASS NAME --> // and <!-- DS DEPENDENCY LIST --> tokens $dsShell = str_replace('<!-- CLASS NAME -->', $classname, $dsShell); // If there is a provider, let them do the prepartion work if ($providerClass) { $dsShell = call_user_func(array($providerClass, 'prepare'), $fields, $params, $dsShell); } else { switch ($source) { case 'authors': $extends = 'AuthorDatasource'; if (isset($fields['filter']['author'])) { $filters = $fields['filter']['author']; } $elements = $fields['xml_elements']; $params['order'] = $fields['order']; $params['redirectonempty'] = isset($fields['redirect_on_empty']) ? 'yes' : 'no'; $params['requiredparam'] = trim($fields['required_url_param']); $params['paramoutput'] = $fields['param']; $params['sort'] = $fields['sort']; break; case 'navigation': $extends = 'NavigationDatasource'; if (isset($fields['filter']['navigation'])) { $filters = $fields['filter']['navigation']; } $params['order'] = $fields['order']; $params['redirectonempty'] = isset($fields['redirect_on_empty']) ? 'yes' : 'no'; $params['requiredparam'] = trim($fields['required_url_param']); break; case 'dynamic_xml': $extends = 'DynamicXMLDatasource'; // Automatically detect namespaces if (isset($data)) { preg_match_all('/xmlns:([a-z][a-z-0-9\\-]*)="([^\\"]+)"/i', $data, $matches); if (!is_array($fields['dynamic_xml']['namespace'])) { $fields['dynamic_xml']['namespace'] = array(); } if (isset($matches[2][0])) { $detected_namespaces = array(); foreach ($fields['dynamic_xml']['namespace'] as $name => $uri) { $detected_namespaces[] = $name; $detected_namespaces[] = $uri; } foreach ($matches[2] as $index => $uri) { $name = $matches[1][$index]; if (in_array($name, $detected_namespaces) or in_array($uri, $detected_namespaces)) { continue; } $detected_namespaces[] = $name; $detected_namespaces[] = $uri; $fields['dynamic_xml']['namespace'][] = array('name' => $name, 'uri' => $uri); } } } $filters = array(); if (is_array($fields['dynamic_xml']['namespace'])) { foreach ($fields['dynamic_xml']['namespace'] as $index => $data) { $filters[$data['name']] = $data['uri']; } } $params['url'] = $fields['dynamic_xml']['url']; $params['xpath'] = $fields['dynamic_xml']['xpath']; $params['cache'] = $fields['dynamic_xml']['cache']; $params['format'] = $fields['dynamic_xml']['format']; $params['timeout'] = isset($fields['dynamic_xml']['timeout']) ? (int) $fields['dynamic_xml']['timeout'] : '6'; break; case 'static_xml': $extends = 'StaticXMLDatasource'; $fields['static_xml'] = trim($fields['static_xml']); if (preg_match('/^<\\?xml/i', $fields['static_xml']) == true) { // Need to remove any XML declaration $fields['static_xml'] = preg_replace('/^<\\?xml[^>]+>/i', NULL, $fields['static_xml']); } $params['static'] = sprintf('%s', addslashes(trim($fields['static_xml']))); break; default: $extends = 'SectionDatasource'; $elements = $fields['xml_elements']; if (is_array($fields['filter']) && !empty($fields['filter'])) { $filters = array(); foreach ($fields['filter'] as $f) { foreach ($f as $key => $val) { $filters[$key] = $val; } } } $params['order'] = $fields['order']; $params['group'] = $fields['group']; $params['paginateresults'] = isset($fields['paginate_results']) ? 'yes' : 'no'; $params['limit'] = $fields['max_records']; $params['startpage'] = $fields['page_number']; $params['redirectonempty'] = isset($fields['redirect_on_empty']) ? 'yes' : 'no'; $params['requiredparam'] = trim($fields['required_url_param']); $params['paramoutput'] = $fields['param']; $params['sort'] = $fields['sort']; $params['htmlencode'] = $fields['html_encode']; $params['associatedentrycounts'] = $fields['associated_entry_counts']; if ($params['associatedentrycounts'] == NULL) { $params['associatedentrycounts'] = 'no'; } break; } $this->__injectVarList($dsShell, $params); $this->__injectIncludedElements($dsShell, $elements); self::injectFilters($dsShell, $filters); if (preg_match_all('@(\\$ds-[0-9a-z_\\.\\-]+)@i', $dsShell, $matches)) { $dependencies = General::array_remove_duplicates($matches[1]); $dsShell = str_replace('<!-- DS DEPENDENCY LIST -->', "'" . implode("', '", $dependencies) . "'", $dsShell); } $dsShell = str_replace('<!-- CLASS EXTENDS -->', $extends, $dsShell); $dsShell = str_replace('<!-- SOURCE -->', $source, $dsShell); } if ($this->_context[0] == 'new') { /** * Prior to creating the Datasource, the file path where it will be written to * is provided and well as the contents of that file. * * @delegate DatasourcePreCreate * @since Symphony 2.2 * @param string $context * '/blueprints/datasources/' * @param string $file * The path to the Datasource file * @param string $contents * The contents for this Datasource as a string passed by reference * @param array $params * An array of all the `$dsParam*` values * @param array $elements * An array of all the elements included in this datasource * @param array $filters * An associative array of all the filters for this datasource with the key * being the `field_id` and the value the filter. * @param array $dependencies * An array of dependencies that this datasource has */ Symphony::ExtensionManager()->notifyMembers('DatasourcePreCreate', '/blueprints/datasources/', array('file' => $file, 'contents' => &$dsShell, 'params' => $params, 'elements' => $elements, 'filters' => $filters, 'dependencies' => $dependencies)); } else { /** * Prior to editing a Datasource, the file path where it will be written to * is provided and well as the contents of that file. * * @delegate DatasourcePreEdit * @since Symphony 2.2 * @param string $context * '/blueprints/datasources/' * @param string $file * The path to the Datasource file * @param string $contents * The contents for this Datasource as a string passed by reference * @param array $dependencies * An array of dependencies that this datasource has * @param array $params * An array of all the `$dsParam*` values * @param array $elements * An array of all the elements included in this datasource * @param array $filters * An associative array of all the filters for this datasource with the key * being the `field_id` and the value the filter. */ Symphony::ExtensionManager()->notifyMembers('DatasourcePreEdit', '/blueprints/datasources/', array('file' => $file, 'contents' => &$dsShell, 'dependencies' => $dependencies, 'params' => $params, 'elements' => $elements, 'filters' => $filters)); } // Remove left over placeholders $dsShell = preg_replace(array('/<!--[\\w ]++-->/', '/(\\r\\n){2,}/', '/(\\t+[\\r\\n]){2,}/'), '', $dsShell); // Write the file if (!is_writable(dirname($file)) || !($write = General::writeFile($file, $dsShell, Symphony::Configuration()->get('write_mode', 'file')))) { $this->pageAlert(__('Failed to write Data source to disk.') . ' ' . __('Please check permissions on %s.', array('<code>/workspace/data-sources</code>')), Alert::ERROR); } else { if ($queueForDeletion) { General::deleteFile($queueForDeletion); // Update pages that use this DS $pages = PageManager::fetch(false, array('data_sources', 'id'), array("\n\t\t\t\t\t\t\t`data_sources` REGEXP '[[:<:]]" . $existing_handle . "[[:>:]]'\n\t\t\t\t\t\t")); if (is_array($pages) && !empty($pages)) { foreach ($pages as $page) { $page['data_sources'] = preg_replace('/\\b' . $existing_handle . '\\b/i', $classname, $page['data_sources']); PageManager::edit($page['id'], $page); } } } if ($this->_context[0] == 'new') { /** * After creating the Datasource, the path to the Datasource file is provided * * @delegate DatasourcePostCreate * @since Symphony 2.2 * @param string $context * '/blueprints/datasources/' * @param string $file * The path to the Datasource file */ Symphony::ExtensionManager()->notifyMembers('DatasourcePostCreate', '/blueprints/datasources/', array('file' => $file)); } else { /** * After editing the Datasource, the path to the Datasource file is provided * * @delegate DatasourcePostEdit * @since Symphony 2.2 * @param string $context * '/blueprints/datasources/' * @param string $file * The path to the Datasource file */ Symphony::ExtensionManager()->notifyMembers('DatasourcePostEdit', '/blueprints/datasources/', array('file' => $file)); } redirect(SYMPHONY_URL . '/blueprints/datasources/edit/' . $classname . '/' . ($this->_context[0] == 'new' ? 'created' : 'saved') . '/'); } } }
public function uninstall() { return General::deleteFile(MANIFEST . '/parametrisator'); }
/** * Builds the attachment section of a multipart email. * * Will return a string containing the section. Can be used to send to * an email server directly. * * @throws EmailGatewayException * @throws Exception * @return string */ protected function getSectionAttachments() { $output = ''; foreach ($this->_attachments as $key => $file) { $tmp_file = false; // If the attachment is a URL, download the file to a temporary location. // This prevents downloading the file twice - once for info, once for data. if (filter_var($file['file'], FILTER_VALIDATE_URL)) { $gateway = new Gateway(); $gateway->init($file['file']); $gateway->setopt('TIMEOUT', 30); $file_content = @$gateway->exec(); $tmp_file = tempnam(TMP, 'attachment'); General::writeFile($tmp_file, $file_content, Symphony::Configuration()->get('write_mode', 'file')); $original_filename = $file['file']; $file['file'] = $tmp_file; // Without this the temporary filename will be used. Ugly! if (is_null($file['filename'])) { $file['filename'] = basename($original_filename); } } else { $file_content = @file_get_contents($file['file']); } if ($file_content !== false && !empty($file_content)) { $output .= $this->boundaryDelimiterLine('multipart/mixed') . $this->contentInfoString($file['mime-type'], $file['file'], $file['filename'], $file['charset']) . EmailHelper::base64ContentTransferEncode($file_content); } else { if (!$tmp_file === false) { $filename = $original_filename; } else { $filename = $file['file']; } throw new EmailGatewayException(__('The content of the file `%s` could not be loaded.', array($filename))); } if (!$tmp_file === false) { General::deleteFile($tmp_file); } } return $output; }
function __formAction() { $fields = $_POST['fields']; $this->_errors = array(); if (trim($fields['name']) == '') { $this->_errors['name'] = __('This is a required field'); } if ($fields['source'] == 'static_xml') { if (trim($fields['static_xml']) == '') { $this->_errors['static_xml'] = __('This is a required field'); } else { $xml_errors = NULL; include_once TOOLKIT . '/class.xsltprocess.php'; General::validateXML($fields['static_xml'], $xml_errors, false, new XsltProcess()); if (!empty($xml_errors)) { $this->_errors['static_xml'] = __('XML is invalid'); } } } elseif ($fields['source'] == 'dynamic_xml') { if (trim($fields['dynamic_xml']['url']) == '') { $this->_errors['dynamic_xml']['url'] = __('This is a required field'); } if (trim($fields['dynamic_xml']['xpath']) == '') { $this->_errors['dynamic_xml']['xpath'] = __('This is a required field'); } if (!is_numeric($fields['dynamic_xml']['cache'])) { $this->_errors['dynamic_xml']['cache'] = __('Must be a valid number'); } elseif ($fields['dynamic_xml']['cache'] < 1) { $this->_errors['dynamic_xml']['cache'] = __('Must be greater than zero'); } } else { if ($fields['source'] != 'navigation') { if (strlen(trim($fields['max_records'])) == 0 || is_numeric($fields['max_records']) && $fields['max_records'] < 1) { $this->_errors['max_records'] = __('A result limit must be set'); } elseif (!self::__isValidPageString($fields['max_records'])) { $this->_errors['max_records'] = __('Must be a valid number or parameter'); } if (strlen(trim($fields['page_number'])) == 0 || is_numeric($fields['page_number']) && $fields['page_number'] < 1) { $this->_errors['page_number'] = __('A page number must be set'); } elseif (!self::__isValidPageString($fields['page_number'])) { $this->_errors['page_number'] = __('Must be a valid number or parameter'); } } } $classname = Lang::createHandle($fields['name'], NULL, '_', false, true, array('@^[^a-z]+@i' => '', '/[^\\w-\\.]/i' => '')); $rootelement = str_replace('_', '-', $classname); $file = DATASOURCES . '/data.' . $classname . '.php'; $isDuplicate = false; $queueForDeletion = NULL; if ($this->_context[0] == 'new' && @is_file($file)) { $isDuplicate = true; } elseif ($this->_context[0] == 'edit') { $existing_handle = $this->_context[1]; if ($classname != $existing_handle && @is_file($file)) { $isDuplicate = true; } elseif ($classname != $existing_handle) { $queueForDeletion = DATASOURCES . '/data.' . $existing_handle . '.php'; } } ##Duplicate if ($isDuplicate) { $this->_errors['name'] = __('A Data source with the name <code>%s</code> name already exists', array($classname)); } if (empty($this->_errors)) { $dsShell = file_get_contents(TEMPLATE . '/datasource.tpl'); //$oDate = $this->_Parent->getDateObj(); $params = array('rootelement' => $rootelement); $about = array('name' => $fields['name'], 'version' => '1.0', 'release date' => DateTimeObj::getGMT('c'), 'author name' => $this->_Parent->Author->getFullName(), 'author website' => URL, 'author email' => $this->_Parent->Author->get('email')); $source = $fields['source']; $filter = NULL; $elements = NULL; switch ($source) { case 'authors': $filters = $fields['filter']['author']; $elements = $fields['xml_elements']; $params['order'] = $fields['order']; $params['limit'] = $fields['max_records']; $params['redirectonempty'] = isset($fields['redirect_on_empty']) ? 'yes' : 'no'; $params['requiredparam'] = $fields['required_url_param']; $params['paramoutput'] = $fields['param']; $params['sort'] = $fields['sort']; $params['startpage'] = $fields['page_number']; $dsShell = str_replace('<!-- GRAB -->', "include(TOOLKIT . '/data-sources/datasource.author.php');", $dsShell); break; case 'navigation': $filters = $fields['filter']['navigation']; $params['order'] = $fields['order']; $params['redirectonempty'] = isset($fields['redirect_on_empty']) ? 'yes' : 'no'; $params['requiredparam'] = $fields['required_url_param']; $dsShell = str_replace('<!-- GRAB -->', "include(TOOLKIT . '/data-sources/datasource.navigation.php');", $dsShell); break; case 'dynamic_xml': $namespaces = $fields['dynamic_xml']['namespace']; $filters = array(); for ($ii = 0; $ii < count($namespaces['name']); $ii++) { $filters[$namespaces['name'][$ii]] = $namespaces['uri'][$ii]; } $params['url'] = $fields['dynamic_xml']['url']; $params['xpath'] = $fields['dynamic_xml']['xpath']; $params['cache'] = $fields['dynamic_xml']['cache']; $dsShell = str_replace('<!-- GRAB -->', "include(TOOLKIT . '/data-sources/datasource.dynamic_xml.php');", $dsShell); break; case 'static_xml': $value = sprintf('$result = "%s";', addslashes($fields['static_xml'])); $dsShell = str_replace('<!-- GRAB -->', $value, $dsShell); break; default: $elements = $fields['xml_elements']; if (is_array($fields['filter']) && !empty($fields['filter'])) { $filters = array(); foreach ($fields['filter'] as $f) { foreach ($f as $key => $val) { $filters[$key] = $val; } } } $params['order'] = $fields['order']; $params['group'] = $fields['group']; $params['limit'] = $fields['max_records']; $params['redirectonempty'] = isset($fields['redirect_on_empty']) ? 'yes' : 'no'; $params['requiredparam'] = $fields['required_url_param']; $params['paramoutput'] = $fields['param']; $params['sort'] = $fields['sort']; $params['startpage'] = $fields['page_number']; $params['htmlencode'] = $fields['html_encode']; $dsShell = str_replace('<!-- GRAB -->', "include(TOOLKIT . '/data-sources/datasource.section.php');", $dsShell); break; } $this->__injectVarList($dsShell, $params); $this->__injectAboutInformation($dsShell, $about); $this->__injectIncludedElements($dsShell, $elements); $this->__injectFilters($dsShell, $filters); $dsShell = str_replace('<!-- CLASS NAME -->', $classname, $dsShell); $dsShell = str_replace('<!-- SOURCE -->', $source, $dsShell); if (preg_match_all('@{(\\$ds-[^}]+)}@i', $dsShell, $matches)) { $dependancies = array(); foreach ($matches[1] as $match) { if (preg_match_all('/(\\$ds-[^:]+)/i', $match, $inner_matches)) { $dependancies = array_merge($dependancies, $inner_matches[1]); } } $dependancies = General::array_remove_duplicates($dependancies); $dsShell = str_replace('<!-- DS DEPENDANCY LIST -->', "'" . implode("', '", $dependancies) . "'", $dsShell); } ## Remove left over placeholders $dsShell = preg_replace(array('/<!--[\\w ]++-->/', '/(\\r\\n){2,}/', '/(\\t+[\\r\\n]){2,}/'), '', $dsShell); ##Write the file if (!is_writable(dirname($file)) || !($write = General::writeFile($file, $dsShell, $this->_Parent->Configuration->get('write_mode', 'file')))) { $this->pageAlert(__('Failed to write Data source to <code>%s</code>. Please check permissions.', array(DATASOURCES)), Alert::ERROR); } else { if ($queueForDeletion) { General::deleteFile($queueForDeletion); ## Update pages that use this DS $sql = "SELECT * FROM `tbl_pages` WHERE `data_sources` REGEXP '[[:<:]]" . $existing_handle . "[[:>:]]' "; $pages = $this->_Parent->Database->fetch($sql); if (is_array($pages) && !empty($pages)) { foreach ($pages as $page) { $page['data_sources'] = preg_replace('/\\b' . $existing_handle . '\\b/i', $classname, $page['data_sources']); $this->_Parent->Database->update($page, 'tbl_pages', "`id` = '" . $page['id'] . "'"); } } } ### TODO: Fix me ### # Delegate: Create # Description: After saving the datasource, the file path is provided and an array # of variables set by the editor #$ExtensionManager->notifyMembers('Create', getCurrentPage(), array('file' => $file, 'defines' => $defines, 'var' => $var)); redirect(URL . '/symphony/blueprints/datasources/edit/' . $classname . '/' . ($this->_context[0] == 'new' ? 'created' : 'saved') . '/'); } } }
public function setFormatter(&$name, &$error, $new) { $template = file_get_contents(EXTENSIONS . '/htmlformatter/templates/formatter.php'); $old = !empty($name) ? $this->getFormatter($name) : array(); // Update author: if (!isset($new['about']['author'])) { $new['about']['author'] = array('name' => $this->_Parent->Author->getFullName(), 'website' => URL, 'email' => $this->_Parent->Author->get('email')); } // Update dates: $new['about']['html-formatter-created'] = DateTimeObj::getGMT('c', @strtotime($new['about']['html-formatter-created'])); $new['about']['html-formatter-updated'] = DateTimeObj::getGMT('c'); // New name: $name = str_replace('-', '', Lang::createHandle($new['about']['name'])); // Create new file: if (strpos(@$new['about']['html-formatter-file'], dirname(__FILE__)) === 0) { $rootdir = dirname(__FILE__); } else { $rootdir = WORKSPACE; } $filemode = $this->_Parent->Configuration->get('write_mode', 'file'); $filename = sprintf('%s/text-formatters/formatter.%s.php', $rootdir, $name); $dirmode = $this->_Parent->Configuration->get('write_mode', 'directory'); $dirname = dirname($filename); // Make sure the directory exists: if (!is_dir($dirname)) { General::realiseDirectory($dirname, $dirmode); } // Make sure new file can be written: if (!is_writable($dirname) or file_exists($filename) and !is_writable($filename)) { $error = __('Cannot save formatter, path is not writable.'); return false; } $filedata = sprintf($template, str_replace(' ', '', ucwords(str_replace('-', ' ', Lang::createHandle($new['about']['name'])))), var_export($new['about']['name'], true), var_export($new['about']['author']['name'], true), var_export($new['about']['author']['website'], true), var_export($new['about']['author']['email'], true), var_export($new['about']['description'], true), var_export($new['about']['html-formatter-created'], true), var_export($new['about']['html-formatter-updated'], true), var_export($new['options']['pretty_acronyms'], true), var_export($new['options']['pretty_ampersands'], true), var_export($new['options']['pretty_dashes'], true), var_export($new['options']['pretty_ellipses'], true), var_export($new['options']['pretty_quotation_marks'], true), var_export($new['options']['pretty_sentence_spacing'], true), var_export($new['options']['pretty_symbols'], true), var_export($new['options']['prevent_widowed_words'], true), var_export($new['options']['editor_name'], true)); // Write file to disk: General::writeFile($filename, $filedata, $filemode); // Cleanup old file: if ($filename != @$old['about']['html-formatter-file'] and file_exists($filename) and @file_exists($old['about']['html-formatter-file'])) { General::deleteFile($old['about']['html-formatter-file']); } return true; }
public function __formAction() { $fields = $_POST['fields']; $this->_errors = array(); $providers = Symphony::ExtensionManager()->getProvidersOf(iProvider::DATASOURCE); $providerClass = null; if (trim($fields['name']) == '') { $this->_errors['name'] = __('This is a required field'); } if ($fields['source'] == 'static_xml') { if (trim($fields['static_xml']) == '') { $this->_errors['static_xml'] = __('This is a required field'); } else { $xml_errors = null; include_once TOOLKIT . '/class.xsltprocess.php'; General::validateXML($fields['static_xml'], $xml_errors, false, new XsltProcess()); if (!empty($xml_errors)) { $this->_errors['static_xml'] = __('XML is invalid.'); } } } elseif (is_numeric($fields['source'])) { if (strlen(trim($fields['max_records'])) == 0 || is_numeric($fields['max_records']) && $fields['max_records'] < 1) { if ($fields['paginate_results'] === 'yes') { $this->_errors['max_records'] = __('A result limit must be set'); } } elseif (!self::__isValidPageString($fields['max_records'])) { $this->_errors['max_records'] = __('Must be a valid number or parameter'); } if (strlen(trim($fields['page_number'])) == 0 || is_numeric($fields['page_number']) && $fields['page_number'] < 1) { if ($fields['paginate_results'] === 'yes') { $this->_errors['page_number'] = __('A page number must be set'); } } elseif (!self::__isValidPageString($fields['page_number'])) { $this->_errors['page_number'] = __('Must be a valid number or parameter'); } // See if a Provided Datasource is saved } elseif (!empty($providers)) { foreach ($providers as $providerClass => $provider) { if ($fields['source'] == call_user_func(array($providerClass, 'getSource'))) { call_user_func_array(array($providerClass, 'validate'), array(&$fields, &$this->_errors)); break; } unset($providerClass); } } $classname = Lang::createHandle($fields['name'], 255, '_', false, true, array('@^[^a-z\\d]+@i' => '', '/[^\\w-\\.]/i' => '')); $rootelement = str_replace('_', '-', $classname); // Check to make sure the classname is not empty after handlisation. if (empty($classname) && !isset($this->_errors['name'])) { $this->_errors['name'] = __('Please ensure name contains at least one Latin-based character.', array($classname)); } $file = DATASOURCES . '/data.' . $classname . '.php'; $isDuplicate = false; $queueForDeletion = null; if ($this->_context[0] == 'new' && is_file($file)) { $isDuplicate = true; } elseif ($this->_context[0] == 'edit') { $existing_handle = $this->_context[1]; if ($classname != $existing_handle && is_file($file)) { $isDuplicate = true; } elseif ($classname != $existing_handle) { $queueForDeletion = DATASOURCES . '/data.' . $existing_handle . '.php'; } } // Duplicate if ($isDuplicate) { $this->_errors['name'] = __('A Data source with the name %s already exists', array('<code>' . $classname . '</code>')); } if (empty($this->_errors)) { $filters = array(); $elements = null; $source = $fields['source']; $params = array('rootelement' => $rootelement); $about = array('name' => $fields['name'], 'version' => 'Symphony ' . Symphony::Configuration()->get('version', 'symphony'), 'release date' => DateTimeObj::getGMT('c'), 'author name' => Symphony::Author()->getFullName(), 'author website' => URL, 'author email' => Symphony::Author()->get('email')); // If there is a provider, get their template if ($providerClass) { $dsShell = file_get_contents(call_user_func(array($providerClass, 'getTemplate'))); } else { $dsShell = file_get_contents($this->getTemplate('blueprints.datasource')); } // Author metadata self::injectAboutInformation($dsShell, $about); // Do dependencies, the template file must have <!-- CLASS NAME --> $dsShell = str_replace('<!-- CLASS NAME -->', $classname, $dsShell); // If there is a provider, let them do the prepartion work if ($providerClass) { $dsShell = call_user_func(array($providerClass, 'prepare'), $fields, $params, $dsShell); } else { switch ($source) { case 'authors': $extends = 'AuthorDatasource'; if (isset($fields['filter']['author'])) { $filters = $fields['filter']['author']; } $elements = $fields['xml_elements']; $params['order'] = $fields['order']; $params['redirectonempty'] = $fields['redirect_on_empty']; $params['redirectonforbidden'] = $fields['redirect_on_forbidden']; $params['redirectonrequired'] = $fields['redirect_on_required']; $params['requiredparam'] = trim($fields['required_url_param']); $params['negateparam'] = trim($fields['negate_url_param']); $params['paramoutput'] = $fields['param']; $params['sort'] = $fields['sort']; break; case 'navigation': $extends = 'NavigationDatasource'; if (isset($fields['filter']['navigation'])) { $filters = $fields['filter']['navigation']; } $params['order'] = $fields['order']; $params['redirectonempty'] = $fields['redirect_on_empty']; $params['redirectonforbidden'] = $fields['redirect_on_forbidden']; $params['redirectonrequired'] = $fields['redirect_on_required']; $params['requiredparam'] = trim($fields['required_url_param']); $params['negateparam'] = trim($fields['negate_url_param']); break; case 'static_xml': $extends = 'StaticXMLDatasource'; $fields['static_xml'] = trim($fields['static_xml']); if (preg_match('/^<\\?xml/i', $fields['static_xml']) == true) { // Need to remove any XML declaration $fields['static_xml'] = preg_replace('/^<\\?xml[^>]+>/i', null, $fields['static_xml']); } $params['static'] = sprintf('%s', trim($fields['static_xml'])); break; default: $extends = 'SectionDatasource'; $elements = $fields['xml_elements']; if (is_array($fields['filter']) && !empty($fields['filter'])) { $filters = array(); foreach ($fields['filter'] as $f) { foreach ($f as $key => $val) { $filters[$key] = $val; } } } $params['order'] = $fields['order']; $params['group'] = $fields['group']; $params['paginateresults'] = $fields['paginate_results']; $params['limit'] = $fields['max_records']; $params['startpage'] = $fields['page_number']; $params['redirectonempty'] = $fields['redirect_on_empty']; $params['redirectonforbidden'] = $fields['redirect_on_forbidden']; $params['redirectonrequired'] = $fields['redirect_on_required']; $params['requiredparam'] = trim($fields['required_url_param']); $params['negateparam'] = trim($fields['negate_url_param']); $params['paramoutput'] = $fields['param']; $params['sort'] = $fields['sort']; $params['htmlencode'] = $fields['html_encode']; $params['associatedentrycounts'] = $fields['associated_entry_counts']; break; } $this->__injectVarList($dsShell, $params); $this->__injectIncludedElements($dsShell, $elements); self::injectFilters($dsShell, $filters); if (preg_match_all('@(\\$ds-[0-9a-z_\\.\\-]+)@i', $dsShell, $matches)) { $dependencies = General::array_remove_duplicates($matches[1]); $dsShell = str_replace('<!-- DS DEPENDENCY LIST -->', "'" . implode("', '", $dependencies) . "'", $dsShell); } $dsShell = str_replace('<!-- CLASS EXTENDS -->', $extends, $dsShell); $dsShell = str_replace('<!-- SOURCE -->', $source, $dsShell); } if ($this->_context[0] == 'new') { /** * Prior to creating the Datasource, the file path where it will be written to * is provided and well as the contents of that file. * * @delegate DatasourcePreCreate * @since Symphony 2.2 * @param string $context * '/blueprints/datasources/' * @param string $file * The path to the Datasource file * @param string $contents * The contents for this Datasource as a string passed by reference * @param array $params * An array of all the `$dsParam*` values * @param array $elements * An array of all the elements included in this datasource * @param array $filters * An associative array of all the filters for this datasource with the key * being the `field_id` and the value the filter. * @param array $dependencies * An array of dependencies that this datasource has */ Symphony::ExtensionManager()->notifyMembers('DatasourcePreCreate', '/blueprints/datasources/', array('file' => $file, 'contents' => &$dsShell, 'params' => $params, 'elements' => $elements, 'filters' => $filters, 'dependencies' => $dependencies)); } else { /** * Prior to editing a Datasource, the file path where it will be written to * is provided and well as the contents of that file. * * @delegate DatasourcePreEdit * @since Symphony 2.2 * @param string $context * '/blueprints/datasources/' * @param string $file * The path to the Datasource file * @param string $contents * The contents for this Datasource as a string passed by reference * @param array $dependencies * An array of dependencies that this datasource has * @param array $params * An array of all the `$dsParam*` values * @param array $elements * An array of all the elements included in this datasource * @param array $filters * An associative array of all the filters for this datasource with the key * being the `field_id` and the value the filter. */ Symphony::ExtensionManager()->notifyMembers('DatasourcePreEdit', '/blueprints/datasources/', array('file' => $file, 'contents' => &$dsShell, 'dependencies' => $dependencies, 'params' => $params, 'elements' => $elements, 'filters' => $filters)); } // Remove left over placeholders $dsShell = preg_replace(array('/<!--[\\w ]++-->/', '/(\\t+[\\r\\n]){2,}/', '/(\\r\\n){2,}/'), '$1', $dsShell); // Write the file if (!is_writable(dirname($file)) || !General::writeFile($file, $dsShell, Symphony::Configuration()->get('write_mode', 'file'), 'w', true)) { $this->pageAlert(__('Failed to write Data source to disk.') . ' ' . __('Please check permissions on %s.', array('<code>/workspace/data-sources</code>')), Alert::ERROR); // Write successful } else { if (function_exists('opcache_invalidate')) { opcache_invalidate($file, true); } // Attach this datasources to pages $connections = $fields['connections']; ResourceManager::setPages(ResourceManager::RESOURCE_TYPE_DS, is_null($existing_handle) ? $classname : $existing_handle, $connections); // If the datasource has been updated and the name changed, then adjust all the existing pages that have the old datasource name if ($queueForDeletion) { General::deleteFile($queueForDeletion); // Update pages that use this DS $pages = PageManager::fetch(false, array('data_sources', 'id'), array("\n `data_sources` REGEXP '[[:<:]]" . $existing_handle . "[[:>:]]'\n ")); if (is_array($pages) && !empty($pages)) { foreach ($pages as $page) { $page['data_sources'] = preg_replace('/\\b' . $existing_handle . '\\b/i', $classname, $page['data_sources']); PageManager::edit($page['id'], $page); } } } if ($this->_context[0] == 'new') { /** * After creating the Datasource, the path to the Datasource file is provided * * @delegate DatasourcePostCreate * @since Symphony 2.2 * @param string $context * '/blueprints/datasources/' * @param string $file * The path to the Datasource file */ Symphony::ExtensionManager()->notifyMembers('DatasourcePostCreate', '/blueprints/datasources/', array('file' => $file)); } else { /** * After editing the Datasource, the path to the Datasource file is provided * * @delegate DatasourcePostEdit * @since Symphony 2.2 * @param string $context * '/blueprints/datasources/' * @param string $file * The path to the Datasource file * @param string $previous_file * The path of the previous Datasource file in the case where a Datasource may * have been renamed. To get the handle from this value, see * `DatasourceManager::__getHandleFromFilename` */ Symphony::ExtensionManager()->notifyMembers('DatasourcePostEdit', '/blueprints/datasources/', array('file' => $file, 'previous_file' => $queueForDeletion ? $queueForDeletion : null)); } redirect(SYMPHONY_URL . '/blueprints/datasources/edit/' . $classname . '/' . ($this->_context[0] == 'new' ? 'created' : 'saved') . '/'); } } }
public function processRawFieldData($data, &$status, $simulate = false, $entry_id = NULL) { $status = self::__OK__; //fixes bug where files are deleted, but their database entries are not. if ($data === NULL) { return array('file' => NULL, 'mimetype' => NULL, 'size' => NULL, 'meta' => NULL); } // Its not an array, so just retain the current data and return if (!is_array($data)) { $status = self::__OK__; // Ensure the file exists in the `WORKSPACE` directory // @link http://symphony-cms.com/discuss/issues/view/610/ $file = WORKSPACE . preg_replace(array('%/+%', '%(^|/)\\.\\./%'), '/', $data); $result = array('file' => $data, 'mimetype' => NULL, 'size' => NULL, 'meta' => NULL); // Grab the existing entry data to preserve the MIME type and size information if (isset($entry_id) && !is_null($entry_id)) { $row = Symphony::Database()->fetchRow(0, sprintf("SELECT `file`, `mimetype`, `size`, `meta` FROM `tbl_entries_data_%d` WHERE `entry_id` = %d", $this->get('id'), $entry_id)); if (!empty($row)) { $result = $row; } } if (!file_exists($file) || !is_readable($file)) { $status = self::__INVALID_FIELDS__; return $result; } else { if (empty($result['mimetype'])) { $result['mimetype'] = function_exists('mime_content_type') ? mime_content_type($file) : 'application/octet-stream'; } if (empty($result['size'])) { $result['size'] = filesize($file); } if (empty($result['meta'])) { $result['meta'] = serialize(self::getMetaInfo($file, $result['mimetype'])); } } return $result; } if ($simulate && is_null($entry_id)) { return $data; } // Upload the new file $abs_path = DOCROOT . '/' . trim($this->get('destination'), '/'); $rel_path = str_replace('/workspace', '', $this->get('destination')); $existing_file = NULL; if (!is_null($entry_id)) { $row = Symphony::Database()->fetchRow(0, sprintf("SELECT * FROM `tbl_entries_data_%s` WHERE `entry_id` = %d LIMIT 1", $this->get('id'), $entry_id)); $existing_file = '/' . trim($row['file'], '/'); // File was removed if ($data['error'] == UPLOAD_ERR_NO_FILE && !is_null($existing_file) && is_file(WORKSPACE . $existing_file)) { General::deleteFile(WORKSPACE . $existing_file); } } if ($data['error'] == UPLOAD_ERR_NO_FILE || $data['error'] != UPLOAD_ERR_OK) { return; } // Sanitize the filename $data['name'] = Lang::createFilename($data['name']); if (!General::uploadFile($abs_path, $data['name'], $data['tmp_name'], Symphony::Configuration()->get('write_mode', 'file'))) { $message = __('There was an error while trying to upload the file <code>%1$s</code> to the target directory <code>%2$s</code>.', array($data['name'], 'workspace/' . ltrim($rel_path, '/'))); $status = self::__ERROR_CUSTOM__; return; } $status = self::__OK__; $file = rtrim($rel_path, '/') . '/' . trim($data['name'], '/'); // File has been replaced if (!is_null($existing_file) && strtolower($existing_file) != strtolower($file) && is_file(WORKSPACE . $existing_file)) { General::deleteFile(WORKSPACE . $existing_file); } // If browser doesn't send MIME type (e.g. .flv in Safari) if (strlen(trim($data['type'])) == 0) { $data['type'] = function_exists('mime_content_type') ? mime_content_type($file) : 'application/octet-stream'; } return array('file' => $file, 'size' => $data['size'], 'mimetype' => $data['type'], 'meta' => serialize(self::getMetaInfo(WORKSPACE . $file, $data['type']))); }