public function execute(array &$param_pool = null) { $result = new XMLElement($this->dsParamROOTELEMENT); $type_sql = $parent_sql = null; if (trim($this->dsParamFILTERS['type']) != '') { $type_sql = $this->__processNavigationTypeFilter($this->dsParamFILTERS['type'], Datasource::determineFilterType($this->dsParamFILTERS['type'])); } if (trim($this->dsParamFILTERS['parent']) != '') { $parent_sql = $this->__processNavigationParentFilter($this->dsParamFILTERS['parent']); } // Build the Query appending the Parent and/or Type WHERE clauses $pages = Symphony::Database()->fetch(sprintf("SELECT DISTINCT p.id, p.title, p.handle, (SELECT COUNT(id) FROM `tbl_pages` WHERE parent = p.id) AS children\n FROM `tbl_pages` AS p\n LEFT JOIN `tbl_pages_types` AS pt ON (p.id = pt.page_id)\n WHERE 1 = 1\n %s\n %s\n ORDER BY p.`sortorder` ASC", !is_null($parent_sql) ? $parent_sql : " AND p.parent IS null ", !is_null($type_sql) ? $type_sql : "")); if (!is_array($pages) || empty($pages)) { if ($this->dsParamREDIRECTONEMPTY === 'yes') { throw new FrontendPageNotFoundException(); } $result->appendChild($this->__noRecordsFound()); } else { // Build an array of all the types so that the page's don't have to do // individual lookups. $page_types = PageManager::fetchAllPagesPageTypes(); foreach ($pages as $page) { $result->appendChild($this->__buildPageXML($page, $page_types)); } } return $result; }
public function testExistingChildren() { // --- test load $this->createModels(CustomerDetail::class, []); $this->createModels(Customer::class, [['name' => 'Frank', 'surname' => 'Sinatra']]); $details = new CustomerDetail(); $source = Datasource::make(new CustomerDetail()); $source['id'] = 1; $source['biography'] = 'A nice life!'; $source['accepts_cookies'] = 0; $source['customer_id'] = 1; $details->id = 1; $details->biography = 'A nice life!'; $details->accepts_cookies = 0; $details->customer_id = 1; $source->save(); assertTrue(isset($source['customer'])); assertInstanceOf(Customer::class, $source['customer']); assertModelArrayEqual(Customer::all()->toArray(), [$source['customer']->toArray()]); // compare with how eloquent behaves: $this->createModels(CustomerDetail::class, []); $details->save(); assertFalse(isset($details->customer)); // always false! assertInstanceOf(Customer::class, $details->customer); }
/** * _getTables * @return array */ protected function _getTables() { $this->tables = array(); $tables = Set::extract('/TABLE_NAMES/.', $this->_db->query('SHOW TABLES')); foreach ($tables as $table) { $this->tables = array_merge($this->tables, array_values($table)); } return $this->tables; }
/** * Initialise data source */ public function __construct(&$parent, $env = NULL, $process_params = true) { parent::__construct($parent, $env, $process_params); $this->dsParamLANG = array(); // Load language codes from configuration $languages = Symphony::Configuration()->get('datetime'); foreach ($languages as $name => $codes) { $this->dsParamLANG[] = explode(', ', $codes); } }
/** * * Class constructor * @param object $parent * @param array $env * @param boolean $process_params */ public function __construct(array $env = null, $process_params = true) { parent::__construct($env, $process_params); // detect if multilangual field AND language redirect is enabled $this->isMultiLangual = Symphony::ExtensionManager()->fetchStatus('page_lhandles') == EXTENSION_ENABLED && Symphony::ExtensionManager()->fetchStatus('language_redirect') == EXTENSION_ENABLED; // add a ref to the Language redirect if ($this->isMultiLangual) { require_once EXTENSIONS . '/language_redirect/lib/class.languageredirect.php'; } }
/** * @uses EventPreSaveFilter */ public function setDefaultValues(&$context) { if (!isset($context['event']->eDefaultValues) || !is_array($context['event']->eDefaultValues)) { return; } // Create a Datasource class, which has the logic for finding Parameters // and turning them into the values. $datasource = new Datasource(null, false); // Fake an environment to find Parameters in $env = array('env' => Frontend::instance()->Page()->Env(), 'param' => Frontend::instance()->Page()->Params()); // Loop over the Default Values, setting them in $_POST or `$context['fields']` // as appropriate. foreach ($context['event']->eDefaultValues as $field => $dv) { $value = $datasource->__processParametersInString($dv['value'], $env); // Custom field, this will set $_POST instead of the `$context['fields']` // as `$context['fields']` only contains things inside $_POST['fields'] if ($dv['custom'] == 'yes') { $matches = preg_split('/\\[/U', $field); foreach ($matches as $key => $match) { $matches[$key] = trim($match, ']'); } if (count($matches) == 1) { self::setArrayValue($_POST, $field, $value, $dv['override'] == 'yes'); } else { $tree = self::addKey($matches, $value); // If the DV is an override, set it regardless // DV is not an override, so only set if it hasn't already been set if ($dv['override'] == 'no' && !self::checkArrayForTree($_POST, $tree)) { $_POST = array_merge_recursive($_POST, $tree); } else { if ($dv['override'] == 'yes') { $_POST = array_replace_recursive($_POST, $tree); } } } continue; } self::setArrayValue($_POST['fields'], $field, $value, $dv['override'] == 'yes'); self::setArrayValue($context['fields'], $field, $value, $dv['override'] == 'yes'); } }
/** * Make a query into the datasource */ public static function query($sql) { if (Datasource::$_self == null) { Datasource::$_self = Datasource::_create(); } Datasource::$_self->_logQuery($sql); try { return Datasource::$_self->_query($sql); } catch (Exception $e) { throw $e; } }
public function __construct(&$parent, $env = NULL, $process_params = true) { if (isset($_GET['q'])) { if (ctype_digit($_GET['q'])) { $this->dsParamFILTERS['id'] = '{$url-q}'; } else { $this->dsParamFILTERS['37'] = 'regexp:{$url-q}'; } } parent::__construct($parent, $env, $process_params); $this->_dependencies = array('$ds-project-project'); }
public function testCreateChildren() { $this->createModels(Customer::class, []); $this->createModels(Order::class, []); // test creation $customer = new Customer(); $source = Datasource::make($customer); $source['name'] = 'Frank'; $source['surname'] = 'Sinatra'; $source['orders.0.code'] = 'a1'; $source['orders.0.shipping'] = 'home'; $source['orders.1.code'] = 'b1'; $source['orders.1.shipping'] = 'office'; $source->save(); assertModelArrayEqual([['name' => 'Frank', 'surname' => 'Sinatra']], Customer::all()->toArray()); assertModelArrayEqual([['code' => 'a1', 'shipping' => 'home', 'customer_id' => 1], ['code' => 'b1', 'shipping' => 'office', 'customer_id' => 1]], Order::all()->toArray()); }
public function sanitize($fld, $value) { if (preg_match("#text\$#", $this->modelStructure[$fld]["type"]) || preg_match("#char\$#", $this->modelStructure[$fld]["type"]) || $this->modelStructure[$fld]["type"] == "enum" || $this->modelStructure[$fld]["type"] == "date" || $this->modelStructure[$fld]["type"] == "timestamp") { $value = "'" . Datasource::escape($value) . "'"; } else { if ($this->modelStructure[$fld]["type"] == "tinyint") { if (!(intval($value) == 0 || intval($value) == 1)) { SimpleMVCErrors::generalError("Given value ({$value}) is not a valid boolean value"); } } else { // Assume to be numeric if (!is_numeric($value) && $value != 'NULL') { SimpleMVCErrors::generalError("{$value} given as numeric database input (" . $this->modelSource . ".{$fld})"); } } } return $value; }
public function testCreateChildren() { $this->createModels(Order::class, []); $this->createModels(Book::class, []); // test creation $order = new Order(); $source = Datasource::make($order); $source['code'] = 'a1'; $source['shipping'] = 'home'; $source['customer_id'] = '1'; $source['books.0.title'] = 'Happiness'; $source['books.1.title'] = 'Delight'; $source->save(); assertModelArrayEqual([['code' => 'a1', 'shipping' => 'home', 'customer_id' => 1]], Order::all()->toArray()); assertModelArrayEqual([['title' => 'Happiness'], ['title' => 'Delight']], Book::all()->toArray()); // repeat $source->save(); assertModelArrayEqual([['code' => 'a1', 'shipping' => 'home', 'customer_id' => 1]], Order::all()->toArray()); assertModelArrayEqual([['title' => 'Happiness'], ['title' => 'Delight']], Book::all()->toArray()); }
/** * This function will replace any parameters in a string with their value. * Parameters are defined by being prefixed by a $ character. In certain * situations, the parameter will be surrounded by {}, which Symphony * takes to mean, evaluate this parameter to a value, other times it will be * omitted which is usually used to indicate that this parameter exists * * @param string $value * The string with the parameters that need to be evaluated * @param array $env * The environment variables from the Frontend class which includes * any params set by Symphony or Events or by other Datasources * @param boolean $includeParenthesis * Parameters will sometimes not be surrounded by {}. If this is the case * setting this parameter to false will make this function automatically add * them to the parameter. By default this is true, which means all parameters * in the string already are surrounded by {} * @param boolean $escape * If set to true, the resulting value will be `urlencode`'d before being returned. * By default this is false * @return string * The string will all parameters evaluated. If a parameter was not found, it will * not be replaced at all. */ public function __processParametersInString($value, array $env, $includeParenthesis = true, $escape = false) { if (trim($value) == '') { return null; } if (!$includeParenthesis) { $value = '{' . $value . '}'; } if (preg_match_all('@{([^}]+)}@i', $value, $matches, PREG_SET_ORDER)) { foreach ($matches as $match) { list($source, $cleaned) = $match; $replacement = null; $bits = preg_split('/:/', $cleaned, -1, PREG_SPLIT_NO_EMPTY); foreach ($bits as $param) { if ($param[0] != '$') { $replacement = $param; break; } $param = trim($param, '$'); $replacement = Datasource::findParameterInEnv($param, $env); if (is_array($replacement)) { $replacement = array_map(array('Datasource', 'escapeCommas'), $replacement); if (count($replacement) > 1) { $replacement = implode(',', $replacement); } else { $replacement = end($replacement); } } if (!empty($replacement)) { break; } } if ($escape == true) { $replacement = urlencode($replacement); } $value = str_replace($source, $replacement, $value); } } return $value; }
public function render(Register $Parameters, XMLDocument &$Document = NULL, DocumentHeaders &$Headers = NULL) { $ParameterOutput = new Register(); if (!is_null($Headers)) { $Headers->append('Content-Type', $this->{'content-type'}); } else { header('Content-Type: ' . $this->{'content-type'}); } if (is_null($Document)) { $Document = new XMLDocument(); $Document->appendChild($Document->createElement('data')); } $root = $Document->documentElement; $datasources = $events = array(); $events_wrapper = $Document->createElement('events'); $root->appendChild($events_wrapper); if (is_array($this->about()->{'events'}) && !empty($this->about()->{'events'})) { $events = $this->about()->{'events'}; } if (is_array($this->about()->{'data-sources'}) && !empty($this->about()->{'data-sources'})) { $datasources = $this->about()->{'data-sources'}; } #### # Delegate: FrontendEventsAppend # Description: Append additional Events. # Global: Yes Extension::notify('FrontendEventsAppend', '/frontend/', array('events' => &$events)); if (!empty($events)) { $postdata = General::getPostData(); $events_ordered = array(); foreach ($events as $handle) { $events_ordered[] = Event::loadFromHandle($handle); } uasort($events_ordered, array($this, '__cbSortEventsByPriority')); foreach ($events_ordered as $e) { if (!$e->canTrigger($postdata)) { continue; } $fragment = $e->trigger($ParameterOutput, $postdata); if ($fragment instanceof DOMDocument && !is_null($fragment->documentElement)) { $node = $Document->importNode($fragment->documentElement, true); $events_wrapper->appendChild($node); } } } #### # Delegate: FrontendDataSourceAppend # Description: Append additional DataSources. # Global: Yes Extension::notify('FrontendDataSourcesAppend', '/frontend/', array('datasources' => &$datasources)); // Find dependancies and order accordingly $datasource_pool = array(); $dependency_list = array(); $datasources_ordered = array(); $all_dependencies = array(); foreach ($datasources as $handle) { $datasource_pool[$handle] = Datasource::loadFromHandle($handle); $dependency_list[$handle] = $datasource_pool[$handle]->parameters()->dependencies; } $datasources_ordered = $this->__sortByDependencies($dependency_list); if (!empty($datasources_ordered)) { foreach ($datasources_ordered as $handle) { $ds = $datasource_pool[$handle]; try { $fragment = $ds->render($ParameterOutput); } catch (FrontendPageNotFoundException $e) { FrontendPageNotFoundExceptionHandler::render($e); } if ($fragment instanceof DOMDocument && !is_null($fragment->documentElement)) { $node = $Document->importNode($fragment->documentElement, true); $root->appendChild($node); } } } if ($ParameterOutput->length() > 0) { foreach ($ParameterOutput as $p) { $Parameters->{$p->key} = $p->value; } } #### # Delegate: FrontendParamsPostResolve # Description: Access to the resolved param pool, including additional parameters provided by Data Source outputs # Global: Yes Extension::notify('FrontendParamsPostResolve', '/frontend/', array('params' => $Parameters)); $element = $Document->createElement('parameters'); $root->appendChild($element); foreach ($Parameters as $key => $parameter) { if (is_array($parameter->value) && count($parameter->value) > 1) { $p = $Document->createElement($key); $p->setAttribute('value', (string) $parameter); foreach ($parameter->value as $v) { $p->appendChild($Document->createElement('item', (string) $v)); } $element->appendChild($p); } else { $element->appendChild($Document->createElement($key, (string) $parameter)); } } $template = $this->template; #### # Delegate: FrontendTemplatePreRender # Description: Access to the template source, before it is rendered. # Global: Yes Extension::notify('FrontendTemplatePreRender', '/frontend/', array('document' => $Document, 'template' => &$template)); $this->template = $template; // When the XSLT executes, it uses the CWD as set here $cwd = getcwd(); chdir(WORKSPACE); $output = XSLProc::transform($Document, $this->template, XSLProc::XML, $Parameters->toArray(), array()); chdir($cwd); if (XSLProc::hasErrors()) { throw new XSLProcException('Transformation Failed'); } /* header('Content-Type: text/plain; charset=utf-8'); $Document->formatOutput = true; print $Document->saveXML(); die(); */ return $output; }
/** * Default Constructor * * @param array $config options * @access public */ function __construct($config = array()) { parent::__construct($config); }
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"); }
public function render(Register $ParameterOutput, $joins = NULL, array $where = array(), $filter_operation_type = self::FILTER_AND) { $execute = true; $result = new XMLDocument(); $result->appendChild($result->createElement($this->parameters()->{'root-element'})); $root = $result->documentElement; // Conditions // If any one condtion returns true (that is, do not execute), the DS will not execute at all if (is_array($this->parameters()->conditions)) { foreach ($this->parameters()->conditions as $condition) { if (preg_match('/:/', $condition['parameter'])) { $c = Datasource::replaceParametersInString($condition['parameter'], $ParameterOutput); } else { $c = Datasource::resolveParameter($condition['parameter'], $ParameterOutput); } // Is Empty if ($condition['logic'] == 'empty' && (is_null($c) || strlen($c) == 0)) { $execute = false; } elseif ($condition['logic'] == 'set' && !is_null($c)) { $execute = false; } if ($execute !== true) { return NULL; } } } // Grab the section try { $section = Section::loadFromHandle($this->parameters()->section); } catch (SectionException $e) { } catch (Exception $e) { } $pagination = (object) array('total-entries' => NULL, 'entries-per-page' => max(1, (int) self::replaceParametersInString($this->parameters()->limit, $ParameterOutput)), 'total-pages' => NULL, 'current-page' => max(1, (int) self::replaceParametersInString($this->parameters()->page, $ParameterOutput))); $pagination->{'record-start'} = max(0, ($pagination->{'current-page'} - 1) * $pagination->{'entries-per-page'}); $order = $sort = NULL; // Apply the Sorting & Direction if ($this->parameters()->{'sort-order'} == 'random') { $order = 'RAND()'; } else { $sort = strtolower($this->parameters()->{'sort-order'}) == 'asc' ? 'ASC' : 'DESC'; // System Field if (preg_match('/^system:/i', $this->parameters()->{'sort-field'})) { switch (preg_replace('/^system:/i', NULL, $this->parameters()->{'sort-field'})) { case 'id': $order = "e.id {$sort}"; break; case 'creation-date': $order = "e.creation_date {$sort}"; break; case 'modification-date': $order = "e.modification_date {$sort}"; break; } } else { $join = NULL; $sort_field = $section->fetchFieldByHandle($this->parameters()->{'sort-field'}); if ($sort_field instanceof Field && $sort_field->isSortable() && method_exists($sort_field, "buildSortingQuery")) { $sort_field->buildSortingQuery($join, $order); $joins .= sprintf($join, $sort_field->section, $sort_field->{'element-name'}); $order = sprintf($order, $sort); } } } // Process Datasource Filters for each of the Fields if (is_array($this->parameters()->filters) && !empty($this->parameters()->filters)) { foreach ($this->parameters()->filters as $k => $filter) { if ($filter['element-name'] == 'system:id') { $filter_value = $this->prepareFilterValue($filter['value'], $ParameterOutput); if (!is_array($filter_value)) { continue; } $filter_value = array_map('intval', $filter_value); if (empty($filter_value)) { continue; } $where[] = sprintf("(e.id %s IN (%s))", $filter['type'] == 'is-not' ? 'NOT' : NULL, implode(',', $filter_value)); } else { $field = $section->fetchFieldByHandle($filter['element-name']); if ($field instanceof Field) { $field->buildFilterQuery($filter, $joins, $where, $ParameterOutput); } } } } // Escape percent symbold: $where = array_map(create_function('$string', 'return str_replace(\'%\', \'%%\', $string);'), $where); $query = sprintf('SELECT DISTINCT SQL_CALC_FOUND_ROWS e.* FROM `tbl_entries` AS `e` %1$s WHERE `section` = "%2$s" %3$s ORDER BY %4$s LIMIT %5$d, %6$d', $joins, $section->handle, is_array($where) && !empty($where) ? 'AND (' . implode($filter_operation_type == self::FILTER_AND ? ' AND ' : ' OR ', $where) . ')' : NULL, $order, $pagination->{'record-start'}, $pagination->{'entries-per-page'}); try { $entries = Symphony::Database()->query($query, array($section->handle, $section->{'publish-order-handle'}), 'EntryResult'); if (isset($this->parameters()->{'append-pagination'}) && $this->parameters()->{'append-pagination'} === true) { $pagination->{'total-entries'} = (int) Symphony::Database()->query("SELECT FOUND_ROWS() AS `total`")->current()->total; $pagination->{'total-pages'} = (int) ceil($pagination->{'total-entries'} * (1 / $pagination->{'entries-per-page'})); // Pagination Element $root->appendChild(General::buildPaginationElement($result, $pagination->{'total-entries'}, $pagination->{'total-pages'}, $pagination->{'entries-per-page'}, $pagination->{'current-page'})); } if (isset($this->parameters()->{'append-sorting'}) && $this->parameters()->{'append-sorting'} === true) { $sorting = $result->createElement('sorting'); $sorting->setAttribute('field', $this->parameters()->{'sort-field'}); $sorting->setAttribute('order', $this->parameters()->{'sort-order'}); $root->appendChild($sorting); } $schema = array(); // Build Entry Records if ($entries->valid()) { // Do some pre-processing on the include-elements. if (is_array($this->parameters()->{'included-elements'}) && !empty($this->parameters()->{'included-elements'})) { $included_elements = (object) array('system' => array(), 'fields' => array()); foreach ($this->parameters()->{'included-elements'} as $element) { $element_name = $mode = NULL; if (preg_match_all('/^([^:]+):\\s*(.+)$/', $element, $matches, PREG_SET_ORDER)) { $element_name = $matches[0][1]; $mode = $matches[0][2]; } else { $element_name = $element; } if ($element_name == 'system') { $included_elements->system[] = $mode; } else { $field = $section->fetchFieldByHandle($element_name); if (!$field instanceof Field) { continue; } $schema[] = $element_name; $included_elements->fields[] = array('element-name' => $element_name, 'instance' => $field, 'mode' => !is_null($mode) > 0 ? trim($mode) : NULL); } } } // Do some pre-processing on the param output array if (is_array($this->parameters()->{'parameter-output'}) && !empty($this->parameters()->{'parameter-output'})) { $parameter_output = (object) array('system' => array(), 'fields' => array()); foreach ($this->parameters()->{'parameter-output'} as $element) { if (preg_match('/^system:/i', $element)) { $parameter_output->system[preg_replace('/^system:/i', NULL, $element)] = array(); } else { $schema[] = $element; $parameter_output->fields[$element] = array(); } } } $entries->setSchema($schema); foreach ($entries as $e) { // If there are included elements, need an entry element. if (is_array($this->parameters()->{'included-elements'}) && !empty($this->parameters()->{'included-elements'})) { $entry = $result->createElement('entry'); $entry->setAttribute('id', $e->id); $root->appendChild($entry); foreach ($included_elements->system as $field) { switch ($field) { case 'creation-date': $entry->appendChild(General::createXMLDateObject($result, DateTimeObj::fromGMT($e->creation_date), 'creation-date')); break; case 'modification-date': $entry->appendChild(General::createXMLDateObject($result, DateTimeObj::fromGMT($e->modification_date), 'modification-date')); break; case 'user': $obj = User::load($e->user_id); $user = $result->createElement('user', $obj->getFullName()); $user->setAttribute('id', $e->user_id); $user->setAttribute('username', $obj->username); $user->setAttribute('email-address', $obj->email); $entry->appendChild($user); break; } } foreach ($included_elements->fields as $field) { $field['instance']->appendFormattedElement($entry, $e->data()->{$field['element-name']}, false, $field['mode'], $e); } } if (is_array($this->parameters()->{'parameter-output'}) && !empty($this->parameters()->{'parameter-output'})) { foreach ($parameter_output->system as $field => $existing_values) { switch ($field) { case 'id': $parameter_output->system[$field][] = $e->id; break; case 'creation-date': $parameter_output->system[$field][] = DateTimeObj::get('Y-m-d H:i:s', DateTimeObj::fromGMT($e->creation_date)); break; case 'modification-date': $parameter_output->system[$field][] = DateTimeObj::get('Y-m-d H:i:s', DateTimeObj::fromGMT($e->modification_date)); break; case 'user': $parameter_output->system[$field][] = $e->user_id; break; } } foreach ($parameter_output->fields as $field => $existing_values) { if (!isset($e->data()->{$field}) or is_null($e->data()->{$field})) { continue; } $o = $section->fetchFieldByHandle($field)->getParameterOutputValue($e->data()->{$field}, $e); if (is_array($o)) { $parameter_output->fields[$field] = array_merge($o, $parameter_output->fields[$field]); } else { $parameter_output->fields[$field][] = $o; } } } } // Add in the param output values to the ParameterOutput object if (is_array($this->parameters()->{'parameter-output'}) && !empty($this->parameters()->{'parameter-output'})) { foreach ($parameter_output->system as $field => $values) { $key = sprintf('ds-%s.system.%s', $this->parameters()->{'root-element'}, $field); $values = array_filter($values); if (is_array($values) && !empty($values)) { $ParameterOutput->{$key} = array_unique($values); } } foreach ($parameter_output->fields as $field => $values) { $key = sprintf('ds-%s.%s', $this->parameters()->{'root-element'}, $field); $values = array_filter($values); if (is_array($values) && !empty($values)) { $ParameterOutput->{$key} = array_unique($values); } } } } elseif ($this->parameters()->{'redirect-404-on-empty'} === true) { throw new FrontendPageNotFoundException(); } else { $this->emptyXMLSet($root); } } catch (DatabaseException $e) { $root->appendChild($result->createElement('error', $e->getMessage())); } return $result; }
protected function __actionDelete(array $datasources, $redirect = NULL) { $success = true; foreach ($datasources as $handle) { try { Datasource::delete($handle); } catch (DatasourceException $e) { $success = false; $this->alerts()->append($e->getMessage(), AlertStack::ERROR, $e); } catch (Exception $e) { $success = false; $this->alerts()->append(__('An unknown error has occurred. <a class="more">Show trace information.</a>'), AlertStack::ERROR, $e); } // TODO: Delete reference from View XML /*$sql = "SELECT * FROM `tbl_pages` WHERE `data_sources` REGEXP '[[:<:]]".$ds."[[:>:]]' "; $pages = Symphony::Database()->fetch($sql); if(is_array($pages) && !empty($pages)){ foreach($pages as $page){ $page['data_sources'] = preg_replace('/\b'.$ds.'\b/i', '', $page['data_sources']); Symphony::Database()->update($page, 'tbl_pages', "`id` = '".$page['id']."'"); } }*/ } if ($success) { redirect($redirect); } }
function __construct(&$parent, $env = NULL, $process_params = true) { $this->dsParamFILTERS = $this->__getParamFilters(); $this->_tm = new TranslationManager($parent); parent::__construct($parent, $env, $process_params); }
public function __construct(&$parent, $env = NULL, $process_params = true) { parent::__construct($parent, $env, $process_params); $this->_dependencies = array('$ds-galleries', '$ds-photos-tags'); }
public function __construct(&$parent, $env = NULL, $process_params = true) { parent::__construct($parent, $env, $process_params); $this->_dependencies = array(); }
public function __construct(&$parent, $env = NULL, $process_params = true) { parent::__construct($parent, $env, $process_params); $this->_dependencies = array('$ds-homepage-articles', '$ds-article', '$ds-drafts'); }
/** * This function iterates over `dsParamFILTERS` and builds the relevant * `$where` and `$joins` parameters with SQL. This SQL is generated from * `Field->buildDSRetrievalSQL`. A third parameter, `$group` is populated * with boolean from `Field->requiresSQLGrouping()` * * @param string $where * @param string $joins * @param boolean $group * @throws Exception */ public function processFilters(&$where, &$joins, &$group) { if (!is_array($this->dsParamFILTERS) || empty($this->dsParamFILTERS)) { return; } $pool = FieldManager::fetch(array_filter(array_keys($this->dsParamFILTERS), 'is_int')); self::$_fieldPool += $pool; if (!is_string($where)) { $where = ''; } foreach ($this->dsParamFILTERS as $field_id => $filter) { if (is_array($filter) && empty($filter) || trim($filter) == '') { continue; } if (!is_array($filter)) { $filter_type = Datasource::determineFilterType($filter); $value = preg_split('/' . ($filter_type == Datasource::FILTER_AND ? '\\+' : '(?<!\\\\),') . '\\s*/', $filter, -1, PREG_SPLIT_NO_EMPTY); $value = array_map('trim', $value); $value = array_map(array('Datasource', 'removeEscapedCommas'), $value); } else { $value = $filter; } if (!in_array($field_id, self::$_system_parameters) && $field_id != 'id' && !self::$_fieldPool[$field_id] instanceof Field) { throw new Exception(__('Error creating field object with id %1$d, for filtering in data source %2$s. Check this field exists.', array($field_id, '<code>' . $this->dsParamROOTELEMENT . '</code>'))); } // Support system:id as well as the old 'id'. #1691 if ($field_id === 'system:id' || $field_id === 'id') { $c = 'IN'; if (stripos($value[0], 'not:') === 0) { $value[0] = preg_replace('/^not:\\s*/', null, $value[0]); $c = 'NOT IN'; } // Cast all ID's to integers. (RE: #2191) $value = array_map(function ($val) { $val = General::intval($val); // General::intval can return -1, so reset that to 0 // so there are no side effects for the following // array_sum and array_filter calls. RE: #2475 if ($val === -1) { $val = 0; } return $val; }, $value); $count = array_sum($value); $value = array_filter($value); // If the ID was cast to 0, then we need to filter on 'id' = 0, // which will of course return no results, but without it the // Datasource will return ALL results, which is not the // desired behaviour. RE: #1619 if ($count === 0) { $value[] = 0; } // If there are no ID's, no need to filter. RE: #1567 if (!empty($value)) { $where .= " AND `e`.id " . $c . " (" . implode(", ", $value) . ") "; } } elseif ($field_id === 'system:creation-date' || $field_id === 'system:modification-date' || $field_id === 'system:date') { $date_joins = ''; $date_where = ''; $date = new FieldDate(); $date->buildDSRetrievalSQL($value, $date_joins, $date_where, $filter_type == Datasource::FILTER_AND ? true : false); // Replace the date field where with the `creation_date` or `modification_date`. $date_where = preg_replace('/`t\\d+`.date/', $field_id !== 'system:modification-date' ? '`e`.creation_date_gmt' : '`e`.modification_date_gmt', $date_where); $where .= $date_where; } else { if (!self::$_fieldPool[$field_id]->buildDSRetrievalSQL($value, $joins, $where, $filter_type == Datasource::FILTER_AND ? true : false)) { $this->_force_empty_result = true; return; } if (!$group) { $group = self::$_fieldPool[$field_id]->requiresSQLGrouping(); } } } }
public function __construct(&$parent, $env = NULL, $process_params = true) { parent::__construct($parent, $env, $process_params); $this->_dependencies = array('$ds-project-project-contributors', '$ds-index-anonymous'); }
public final function __sleep() { Datasource::disconnect(); }
public function __construct(&$parent, $env = NULL, $process_params = TRUE) { parent::__construct($parent, $env, $process_params); }
public function __construct(array $env = null, $process_params = true) { parent::__construct($env, $process_params); }
public function __viewIndex() { if (!($section_id = SectionManager::fetchIDFromHandle($this->_context['section_handle']))) { Administration::instance()->throwCustomError(__('The Section, %s, could not be found.', array('<code>' . $this->_context['section_handle'] . '</code>')), __('Unknown Section'), Page::HTTP_STATUS_NOT_FOUND); } else { if (!is_writable(CONFIG)) { $this->pageAlert(__('The Symphony configuration file, %s, is not writable. The sort order cannot be modified.', array('<code>/manifest/config.php</code>')), Alert::NOTICE); } } $section = SectionManager::fetch($section_id); $this->setPageType('table'); $this->setTitle(__('%1$s – %2$s', array($section->get('name'), __('Symphony')))); $filters = array(); $filter_querystring = $prepopulate_querystring = $where = $joins = null; $current_page = isset($_REQUEST['pg']) && is_numeric($_REQUEST['pg']) ? max(1, intval($_REQUEST['pg'])) : 1; if (isset($_REQUEST['filter'])) { // legacy implementation, convert single filter to an array // split string in the form ?filter=handle:value if (!is_array($_REQUEST['filter'])) { list($field_handle, $filter_value) = explode(':', $_REQUEST['filter'], 2); $filters[$field_handle] = rawurldecode($filter_value); } else { $filters = $_REQUEST['filter']; } foreach ($filters as $handle => $value) { // Handle multiple values through filtering. RE: #2290 if (is_array($value) && empty($value) || trim($value) == '') { continue; } if (!is_array($value)) { $filter_type = Datasource::determineFilterType($value); $value = preg_split('/' . ($filter_type == Datasource::FILTER_AND ? '\\+' : '(?<!\\\\),') . '\\s*/', $value, -1, PREG_SPLIT_NO_EMPTY); $value = array_map('trim', $value); $value = array_map(array('Datasource', 'removeEscapedCommas'), $value); } // Handle date meta data #2003 $handle = Symphony::Database()->cleanValue($handle); if (in_array($handle, array('system:creation-date', 'system:modification-date'))) { $date_joins = ''; $date_where = ''; $date = new FieldDate(); $date->buildDSRetrievalSQL($value, $date_joins, $date_where, $filter_type == Datasource::FILTER_AND ? true : false); // Replace the date field where with the `creation_date` or `modification_date`. $date_where = preg_replace('/`t\\d+`.date/', $field_id !== 'system:modification-date' ? '`e`.creation_date_gmt' : '`e`.modification_date_gmt', $date_where); $where .= $date_where; } else { // Handle normal fields $field_id = FieldManager::fetchFieldIDFromElementName($handle, $section->get('id')); $field = FieldManager::fetch($field_id); if ($field instanceof Field) { $field->buildDSRetrievalSQL($value, $joins, $where, $filter_type == Datasource::FILTER_AND ? true : false); $value = implode(',', $value); $encoded_value = rawurlencode($value); $filter_querystring .= sprintf("filter[%s]=%s&", $handle, $encoded_value); // Some fields require that prepopulation be done via ID. RE: #2331 if (!is_numeric($value) && method_exists($field, 'fetchIDfromValue')) { $encoded_value = $field->fetchIDfromValue($value); } $prepopulate_querystring .= sprintf("prepopulate[%d]=%s&", $field_id, $encoded_value); } else { unset($filters[$handle]); } } } $filter_querystring = preg_replace("/&\$/", '', $filter_querystring); $prepopulate_querystring = preg_replace("/&\$/", '', $prepopulate_querystring); } Sortable::initialize($this, $entries, $sort, $order, array('current-section' => $section, 'filters' => $filter_querystring ? "&" . $filter_querystring : '', 'unsort' => isset($_REQUEST['unsort']))); $this->Form->setAttribute('action', Administration::instance()->getCurrentPageURL() . '?pg=' . $current_page . ($filter_querystring ? "&" . $filter_querystring : '')); // Build filtering interface $this->createFilteringInterface(); $subheading_buttons = array(Widget::Anchor(__('Create New'), Administration::instance()->getCurrentPageURL() . 'new/' . ($prepopulate_querystring ? '?' . $prepopulate_querystring : ''), __('Create a new entry'), 'create button', null, array('accesskey' => 'c'))); // Only show the Edit Section button if the Author is a developer. #938 ^BA if (Symphony::Author()->isDeveloper()) { array_unshift($subheading_buttons, Widget::Anchor(__('Edit Section'), SYMPHONY_URL . '/blueprints/sections/edit/' . $section_id . '/', __('Edit Section Configuration'), 'button')); } $this->appendSubheading($section->get('name'), $subheading_buttons); /** * Allows adjustments to be made to the SQL where and joins statements * before they are used to fetch the entries for the page * * @delegate AdjustPublishFiltering * @since Symphony 2.3.3 * @param string $context * '/publish/' * @param integer $section_id * An array of the current columns, passed by reference * @param string $where * The current where statement, or null if not set * @param string $joins */ Symphony::ExtensionManager()->notifyMembers('AdjustPublishFiltering', '/publish/', array('section-id' => $section_id, 'where' => &$where, 'joins' => &$joins)); // Check that the filtered query fails that the filter is dropped and an // error is logged. #841 ^BA try { $entries = EntryManager::fetchByPage($current_page, $section_id, Symphony::Configuration()->get('pagination_maximum_rows', 'symphony'), $where, $joins, true); } catch (DatabaseException $ex) { $this->pageAlert(__('An error occurred while retrieving filtered entries. Showing all entries instead.'), Alert::ERROR); $filter_querystring = null; Symphony::Log()->pushToLog(sprintf('%s - %s%s%s', $section->get('name') . ' Publish Index', $ex->getMessage(), $ex->getFile() ? " in file " . $ex->getFile() : null, $ex->getLine() ? " on line " . $ex->getLine() : null), E_NOTICE, true); $entries = EntryManager::fetchByPage($current_page, $section_id, Symphony::Configuration()->get('pagination_maximum_rows', 'symphony')); } // Flag filtering if (isset($_REQUEST['filter'])) { $filter_stats = new XMLElement('p', '<span>– ' . __('%d of %d entries (filtered)', array($entries['total-entries'], EntryManager::fetchCount($section_id))) . '</span>', array('class' => 'inactive')); } else { $filter_stats = new XMLElement('p', '<span>– ' . __('%d entries', array($entries['total-entries'])) . '</span>', array('class' => 'inactive')); } $this->Breadcrumbs->appendChild($filter_stats); // Build table $visible_columns = $section->fetchVisibleColumns(); $columns = array(); if (is_array($visible_columns) && !empty($visible_columns)) { foreach ($visible_columns as $column) { $columns[] = array('label' => $column->get('label'), 'sortable' => $column->isSortable(), 'handle' => $column->get('id'), 'attrs' => array('id' => 'field-' . $column->get('id'), 'class' => 'field-' . $column->get('type'))); } } else { $columns[] = array('label' => __('ID'), 'sortable' => true, 'handle' => 'id'); } $aTableHead = Sortable::buildTableHeaders($columns, $sort, $order, $filter_querystring ? "&" . $filter_querystring : ''); $child_sections = array(); $associated_sections = $section->fetchChildAssociations(true); if (is_array($associated_sections) && !empty($associated_sections)) { foreach ($associated_sections as $key => $as) { $child_sections[$key] = SectionManager::fetch($as['child_section_id']); $aTableHead[] = array($child_sections[$key]->get('name'), 'col'); } } /** * Allows the creation of custom table columns for each entry. Called * after all the Section Visible columns have been added as well * as the Section Associations * * @delegate AddCustomPublishColumn * @since Symphony 2.2 * @param string $context * '/publish/' * @param array $tableHead * An array of the current columns, passed by reference * @param integer $section_id * The current Section ID */ Symphony::ExtensionManager()->notifyMembers('AddCustomPublishColumn', '/publish/', array('tableHead' => &$aTableHead, 'section_id' => $section->get('id'))); // Table Body $aTableBody = array(); if (!is_array($entries['records']) || empty($entries['records'])) { $aTableBody = array(Widget::TableRow(array(Widget::TableData(__('None found.'), 'inactive', null, count($aTableHead))), 'odd')); } else { $field_pool = array(); if (is_array($visible_columns) && !empty($visible_columns)) { foreach ($visible_columns as $column) { $field_pool[$column->get('id')] = $column; } } $link_column = array_reverse($visible_columns); $link_column = end($link_column); reset($visible_columns); foreach ($entries['records'] as $entry) { $tableData = array(); // Setup each cell if (!is_array($visible_columns) || empty($visible_columns)) { $tableData[] = Widget::TableData(Widget::Anchor($entry->get('id'), Administration::instance()->getCurrentPageURL() . 'edit/' . $entry->get('id') . '/')); } else { $link = Widget::Anchor('', Administration::instance()->getCurrentPageURL() . 'edit/' . $entry->get('id') . '/' . ($filter_querystring ? '?' . $prepopulate_querystring : ''), $entry->get('id'), 'content'); foreach ($visible_columns as $position => $column) { $data = $entry->getData($column->get('id')); $field = $field_pool[$column->get('id')]; $value = $field->prepareTableValue($data, $column == $link_column ? $link : null, $entry->get('id')); if (!is_object($value) && (strlen(trim($value)) == 0 || $value == __('None'))) { $value = $position == 0 ? $link->generate() : __('None'); } if ($value == __('None')) { $tableData[] = Widget::TableData($value, 'inactive field-' . $column->get('type') . ' field-' . $column->get('id')); } else { $tableData[] = Widget::TableData($value, 'field-' . $column->get('type') . ' field-' . $column->get('id')); } unset($field); } } if (is_array($child_sections) && !empty($child_sections)) { foreach ($child_sections as $key => $as) { $field = FieldManager::fetch((int) $associated_sections[$key]['child_section_field_id']); $parent_section_field_id = (int) $associated_sections[$key]['parent_section_field_id']; if (!is_null($parent_section_field_id)) { $search_value = $field->fetchAssociatedEntrySearchValue($entry->getData($parent_section_field_id), $parent_section_field_id, $entry->get('id')); } else { $search_value = $entry->get('id'); } if (!is_array($search_value)) { $associated_entry_count = $field->fetchAssociatedEntryCount($search_value); $tableData[] = Widget::TableData(Widget::Anchor(sprintf('%d →', max(0, intval($associated_entry_count))), sprintf('%s/publish/%s/?filter[%s]=%s', SYMPHONY_URL, $as->get('handle'), $field->get('element_name'), rawurlencode($search_value)), $entry->get('id'), 'content')); } } } /** * Allows Extensions to inject custom table data for each Entry * into the Publish Index * * @delegate AddCustomPublishColumnData * @since Symphony 2.2 * @param string $context * '/publish/' * @param array $tableData * An array of `Widget::TableData`, passed by reference * @param integer $section_id * The current Section ID * @param Entry $entry_id * The entry object, please note that this is by error and this will * be removed in Symphony 2.4. The entry object is available in * the 'entry' key as of Symphony 2.3.1. * @param Entry $entry * The entry object for this row */ Symphony::ExtensionManager()->notifyMembers('AddCustomPublishColumnData', '/publish/', array('tableData' => &$tableData, 'section_id' => $section->get('id'), 'entry_id' => $entry, 'entry' => $entry)); $tableData[count($tableData) - 1]->appendChild(Widget::Label(__('Select Entry %d', array($entry->get('id'))), null, 'accessible', null, array('for' => 'entry-' . $entry->get('id')))); $tableData[count($tableData) - 1]->appendChild(Widget::Input('items[' . $entry->get('id') . ']', null, 'checkbox', array('id' => 'entry-' . $entry->get('id')))); // Add a row to the body array, assigning each cell to the row $aTableBody[] = Widget::TableRow($tableData, null, 'id-' . $entry->get('id')); } } $table = Widget::Table(Widget::TableHead($aTableHead), null, Widget::TableBody($aTableBody), 'selectable', null, array('role' => 'directory', 'aria-labelledby' => 'symphony-subheading', 'data-interactive' => 'data-interactive')); $this->Form->appendChild($table); $tableActions = new XMLElement('div'); $tableActions->setAttribute('class', 'actions'); $options = array(array(null, false, __('With Selected...')), array('delete', false, __('Delete'), 'confirm', null, array('data-message' => __('Are you sure you want to delete the selected entries?')))); $toggable_fields = $section->fetchToggleableFields(); if (is_array($toggable_fields) && !empty($toggable_fields)) { $index = 2; foreach ($toggable_fields as $field) { $toggle_states = $field->getToggleStates(); if (is_array($toggle_states)) { $options[$index] = array('label' => __('Set %s', array($field->get('label'))), 'options' => array()); foreach ($toggle_states as $value => $state) { $options[$index]['options'][] = array('toggle-' . $field->get('id') . '-' . $value, false, $state); } } $index++; } } /** * Allows an extension to modify the existing options for this page's * With Selected menu. If the `$options` parameter is an empty array, * the 'With Selected' menu will not be rendered. * * @delegate AddCustomActions * @since Symphony 2.3.2 * @param string $context * '/publish/' * @param array $options * An array of arrays, where each child array represents an option * in the With Selected menu. Options should follow the same format * expected by `Widget::__SelectBuildOption`. Passed by reference. */ Symphony::ExtensionManager()->notifyMembers('AddCustomActions', '/publish/', array('options' => &$options)); if (!empty($options)) { $tableActions->appendChild(Widget::Apply($options)); $this->Form->appendChild($tableActions); } if ($entries['total-pages'] > 1) { $ul = new XMLElement('ul'); $ul->setAttribute('class', 'page'); // First $li = new XMLElement('li'); if ($current_page > 1) { $li->appendChild(Widget::Anchor(__('First'), Administration::instance()->getCurrentPageURL() . '?pg=1' . ($filter_querystring ? "&" . $filter_querystring : ''))); } else { $li->setValue(__('First')); } $ul->appendChild($li); // Previous $li = new XMLElement('li'); if ($current_page > 1) { $li->appendChild(Widget::Anchor(__('← Previous'), Administration::instance()->getCurrentPageURL() . '?pg=' . ($current_page - 1) . ($filter_querystring ? "&" . $filter_querystring : ''))); } else { $li->setValue(__('← Previous')); } $ul->appendChild($li); // Summary $li = new XMLElement('li'); $li->setAttribute('title', __('Viewing %1$s - %2$s of %3$s entries', array($entries['start'], $current_page != $entries['total-pages'] ? $current_page * Symphony::Configuration()->get('pagination_maximum_rows', 'symphony') : $entries['total-entries'], $entries['total-entries']))); $pgform = Widget::Form(Administration::instance()->getCurrentPageURL(), 'get', 'paginationform'); $pgmax = max($current_page, $entries['total-pages']); $pgform->appendChild(Widget::Input('pg', null, 'text', array('data-active' => __('Go to page …'), 'data-inactive' => __('Page %1$s of %2$s', array((string) $current_page, $pgmax)), 'data-max' => $pgmax))); $li->appendChild($pgform); $ul->appendChild($li); // Next $li = new XMLElement('li'); if ($current_page < $entries['total-pages']) { $li->appendChild(Widget::Anchor(__('Next →'), Administration::instance()->getCurrentPageURL() . '?pg=' . ($current_page + 1) . ($filter_querystring ? "&" . $filter_querystring : ''))); } else { $li->setValue(__('Next →')); } $ul->appendChild($li); // Last $li = new XMLElement('li'); if ($current_page < $entries['total-pages']) { $li->appendChild(Widget::Anchor(__('Last'), Administration::instance()->getCurrentPageURL() . '?pg=' . $entries['total-pages'] . ($filter_querystring ? "&" . $filter_querystring : ''))); } else { $li->setValue(__('Last')); } $ul->appendChild($li); $this->Contents->appendChild($ul); } }
function __construct(&$parent) { parent::__construct($parent); }
public function __construct(&$parent, $env = NULL, $process_params = true) { parent::__construct($parent, $env, $process_params); $this->_dependencies = array('$ds-dashboard-projects'); }
/** * Executes a data source. Invalid XML is escaped (CDATA) but still * cached. Prevents persistent cached XML from breaking pages. * * @param Datasource $datasource * The current data source object * @param int $file_age * Cache file age (in seconds), passed by reference */ private function __executeDatasource($datasource, &$param_pool = array()) { $result = $datasource->grab($param_pool); $xml = is_object($result) ? $result->generate(true, 1) : $result; // Parse DS XML to check for errors. If contains malformed XML such as // an unescaped database error, the error is escaped in CDATA $doc = new DOMDocument('1.0', 'utf-8'); libxml_use_internal_errors(true); $doc->loadXML($xml); $errors = libxml_get_errors(); libxml_clear_errors(); libxml_use_internal_errors(false); // No error, just return the result if (empty($errors)) { return $result; } // There's an error, so $doc will be empty // Use regex to get the root node // If something's wrong, just push back the broken XML if (!preg_match('/<([^ \\/>]+)/', $xml, $matches)) { return $result; } $ret = new XMLElement($matches[1]); // Set the invalid flag $ret->setAttribute("xml-invalid", "true"); $errornode = new XMLElement("errors"); // Store the errors foreach ($errors as $error) { $item = new XMLElement("error", trim($error->message)); $item->setAttribute('line', $error->line); $item->setAttribute('column', $error->column); $errornode->appendChild($item); } $ret->appendChild($errornode); // Return the XML $ret->appendChild(new XMLElement('broken-xml', "<![CDATA[" . $xml . "]]>")); return $ret; }