示例#1
0
    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;
    }