Property changes on: branches/5.3.x/LICENSE ___________________________________________________________________ Modified: svn:mergeinfo Merged /in-portal/branches/5.2.x/LICENSE:r16067-16123 Property changes on: branches/5.3.x/robots.txt ___________________________________________________________________ Modified: svn:mergeinfo Merged /in-portal/branches/5.2.x/robots.txt:r16067-16123 Index: branches/5.3.x/core/kernel/db/dblist.php =================================================================== --- branches/5.3.x/core/kernel/db/dblist.php (revision 16123) +++ branches/5.3.x/core/kernel/db/dblist.php (revision 16124) @@ -1,1773 +1,1778 @@ OrderFields = Array(); $filters = $this->getFilterStructure(); foreach ($filters as $filter_params) { $filter =& $this->$filter_params['type']; $filter[ $filter_params['class'] ] = $this->Application->makeClass('kMultipleFilter', Array ($filter_params['join_using'])); } $this->PerPage = -1; } function setGridName($grid_name) { $this->gridName = $grid_name; } /** * Returns information about all possible filter types * * @return Array * @access protected */ protected function getFilterStructure() { $filters = Array ( Array ('type' => 'WhereFilter', 'class' => self::FLT_SYSTEM, 'join_using' => self::FLT_TYPE_AND), Array ('type' => 'WhereFilter', 'class' => self::FLT_NORMAL, 'join_using' => self::FLT_TYPE_OR), Array ('type' => 'WhereFilter', 'class' => self::FLT_SEARCH, 'join_using' => self::FLT_TYPE_OR), Array ('type' => 'WhereFilter', 'class' => self::FLT_VIEW, 'join_using' => self::FLT_TYPE_AND), Array ('type' => 'WhereFilter', 'class' => self::FLT_CUSTOM, 'join_using' => self::FLT_TYPE_AND), Array ('type' => 'HavingFilter', 'class' => self::FLT_SYSTEM, 'join_using' => self::FLT_TYPE_AND), Array ('type' => 'HavingFilter', 'class' => self::FLT_NORMAL, 'join_using' => self::FLT_TYPE_OR), Array ('type' => 'HavingFilter', 'class' => self::FLT_SEARCH, 'join_using' => self::FLT_TYPE_OR), Array ('type' => 'HavingFilter', 'class' => self::FLT_VIEW, 'join_using' => self::FLT_TYPE_AND), Array ('type' => 'HavingFilter', 'class' => self::FLT_CUSTOM, 'join_using' => self::FLT_TYPE_AND), Array ('type' => 'AggregateFilter', 'class' => self::FLT_SYSTEM, 'join_using' => self::FLT_TYPE_AND), Array ('type' => 'AggregateFilter', 'class' => self::FLT_NORMAL, 'join_using' => self::FLT_TYPE_OR), Array ('type' => 'AggregateFilter', 'class' => self::FLT_VIEW, 'join_using' => self::FLT_TYPE_AND), ); return $filters; } /** * Adds new or replaces old filter with same name * * @param string $name filter name (for internal use) * @param string $clause where/having clause part (no OR/AND allowed) * @param int $filter_type is filter having filter or where filter * @param int $filter_scope filter subtype: FLT_NORMAL,FLT_SYSTEM,FLT_SEARCH,FLT_VIEW,FLT_CUSTOM * @access public */ public function addFilter($name, $clause, $filter_type = self::WHERE_FILTER, $filter_scope = self::FLT_SYSTEM) { $filter_source = Array ( self::WHERE_FILTER => 'WhereFilter', self::HAVING_FILTER => 'HavingFilter', self::AGGREGATE_FILTER => 'AggregateFilter' ); $filter_name = $filter_source[$filter_type]; $filter =& $this->$filter_name; $filter =& $filter[$filter_scope]; /* @var $filter kMultipleFilter */ $filter->addFilter($name, $clause); } /** * Reads filter content * * @param string $name filter name (for internal use) * @param int $filter_type is filter having filter or where filter * @param int $filter_scope filter subtype: FLT_NORMAL,FLT_SYSTEM,FLT_SEARCH,FLT_VIEW,FLT_CUSTOM * @return string * @access public */ public function getFilter($name, $filter_type = self::WHERE_FILTER, $filter_scope = self::FLT_SYSTEM) { $filter_source = Array ( self::WHERE_FILTER => 'WhereFilter', self::HAVING_FILTER => 'HavingFilter', self::AGGREGATE_FILTER => 'AggregateFilter' ); $filter_name = $filter_source[$filter_type]; $filter =& $this->$filter_name; $filter =& $filter[$filter_scope]; /* @var $filter kMultipleFilter */ return $filter->getFilter($name); } /** * Removes specified filter from filters list * * @param string $name filter name (for internal use) * @param int $filter_type is filter having filter or where filter * @param int $filter_scope filter subtype: FLT_NORMAL,FLT_SYSTEM,FLT_SEARCH,FLT_VIEW,FLT_CUSTOM * @access public */ public function removeFilter($name, $filter_type = self::WHERE_FILTER, $filter_scope = self::FLT_SYSTEM) { $filter_source = Array ( self::WHERE_FILTER => 'WhereFilter', self::HAVING_FILTER => 'HavingFilter', self::AGGREGATE_FILTER => 'AggregateFilter' ); $filter_name = $filter_source[$filter_type]; $filter =& $this->$filter_name; $filter =& $filter[$filter_scope]; /* @var $filter kMultipleFilter */ $filter->removeFilter($name); } /** * Clear all filters * * @access public */ public function clearFilters() { $filters = $this->getFilterStructure(); foreach ($filters as $filter_params) { $filter =& $this->$filter_params['type']; $filter[ $filter_params['class'] ]->clearFilters(); } } /** * Counts the total number of records base on the query resulted from {@link kDBList::GetSelectSQL()} * * The method modifies the query to substitude SELECT part (fields listing) with COUNT(*). * Special care should be applied when working with lists based on grouped queries, all aggregate function fields * like SUM(), AVERAGE() etc. should be added to CountedSQL by using {@link kDBList::SetCountedSQL()} * * @access protected */ protected function CountRecs() { $all_sql = $this->GetSelectSQL(true,false); $sql = $this->getCountSQL($all_sql); $this->Counted = true; if( $this->GetGroupClause() ) { $this->RecordsCount = count( $this->Conn->GetCol($sql) ); } else { $this->RecordsCount = (int)$this->Conn->GetOne($sql); } $system_sql = $this->GetSelectSQL(true,true); if($system_sql == $all_sql) //no need to query the same again { $this->NoFilterCount = $this->RecordsCount; return; } $sql = $this->getCountSQL($system_sql); if( $this->GetGroupClause() ) { $this->NoFilterCount = count( $this->Conn->GetCol($sql) ); } else { $this->NoFilterCount = (int)$this->Conn->GetOne($sql); } } /** * Returns record count in list with/without user filters applied * * @param bool $with_filters * @return int * @access public */ public function GetRecordsCount($with_filters = true) { if (!$this->Counted) { $this->CountRecs(); } return $with_filters ? $this->RecordsCount : $this->NoFilterCount; } /** * Returns record count, that were actually selected * * @return int * @access public */ public function GetSelectedCount() { return $this->SelectedCount; } /** * Transforms given query into count query (DISTINCT is also processed) * * @param string $sql * @return string * @access public */ public function getCountSQL($sql) { if ( preg_match("/^\s*SELECT\s+DISTINCT(.*?\s)FROM(?!_)/is",$sql,$regs ) ) { return preg_replace("/^\s*SELECT\s+DISTINCT(.*?\s)FROM(?!_)/is", "SELECT COUNT(DISTINCT ".$regs[1].") AS count FROM", $sql); } else { return preg_replace("/^\s*SELECT(.*?\s)FROM(?!_)/is", "SELECT COUNT(*) AS count FROM ", $sql); } } /** * Queries the database with SQL resulted from {@link kDBList::GetSelectSQL()} and stores result in {@link kDBList::SelectRS} * * All the sorting, pagination, filtration of the list should be set prior to calling Query(). * * @param bool $force force re-query, when already queried * @return bool * @access public */ public function Query($force=false) { if (!$force && $this->Queried) return true; $q = $this->GetSelectSQL(); //$rs = $this->Conn->SelectLimit($q, $this->PerPage, $this->Offset); //in case we have not counted records try to select one more item to find out if we have something more than perpage $limit = $this->Counted ? $this->PerPage : $this->PerPage+1; $sql = $q.' '.$this->Conn->getLimitClause($this->Offset,$limit); $this->Records = $this->Conn->Query($sql); if (!$this->Records && ($this->Page > 1)) { if ( $this->Application->isAdmin ) { // no records & page > 1, try to reset to 1st page (works only when list in not counted before) $this->Application->StoreVar($this->getPrefixSpecial() . '_Page', 1, true); $this->SetPage(1); $this->Query($force); } + else if ( $this->Application->HttpQuery->refererIsOurSite() ) { + // no records & page > 1, try to reset to last page + $this->SetPage($this->GetTotalPages()); + $this->Query($force); + } else { // no records & page > 1, show 404 page trigger_error('Unknown page ' . $this->Page . ' in ' . $this->getPrefixSpecial() . ' list, leading to "404 Not Found"', E_USER_NOTICE); $this->Application->UrlManager->show404(); } } $this->SelectedCount = count($this->Records); if (!$this->Counted) $this->RecordsCount = $this->SelectedCount; if (!$this->Counted && $this->SelectedCount > $this->PerPage && $this->PerPage != -1) $this->SelectedCount--; if ($this->Records === false) { //handle errors here return false; } $this->Queried = true; $this->Application->HandleEvent(new kEvent($this->getPrefixSpecial() . ':OnAfterListQuery')); return true; } /** * Adds one more record to list virtually and updates all counters * * @param Array $record * @access public */ public function addRecord($record) { $this->Records[] = $record; $this->SelectedCount++; $this->RecordsCount++; } /** * Calculates totals based on config * * @access protected */ protected function CalculateTotals() { $fields = Array (); $this->Totals = Array (); if ( $this->gridName ) { $grid = $this->getUnitConfig()->getGridByName($this->gridName); $grid_fields = $grid['Fields']; } else { $grid_fields = $this->Fields; } foreach ($grid_fields as $field_name => $field_options) { if ( $this->gridName && array_key_exists('totals', $field_options) && $field_options['totals'] ) { $totals = $field_options['totals']; } elseif ( array_key_exists('totals', $this->Fields[$field_name]) && $this->Fields[$field_name]['totals'] ) { $totals = $this->Fields[$field_name]['totals']; } else { continue; } $calculated_field = array_key_exists($field_name, $this->CalculatedFields) && array_key_exists($field_name, $this->VirtualFields); $db_field = !array_key_exists($field_name, $this->VirtualFields); if ( $calculated_field || $db_field ) { $field_expression = $calculated_field ? $this->CalculatedFields[$field_name] : '`' . $this->TableName . '`.`' . $field_name . '`'; $fields[$field_name] = $totals . '(' . $field_expression . ') AS ' . $field_name . '_' . $totals; } } if ( !$fields ) { return; } $sql = $this->GetSelectSQL(true, false); $fields = str_replace('%1$s', $this->TableName, implode(', ', $fields)); if ( preg_match("/DISTINCT(.*?\s)FROM(?!_)/is", $sql, $regs) ) { $sql = preg_replace("/^\s*SELECT DISTINCT(.*?\s)FROM(?!_)/is", 'SELECT ' . $fields . ' FROM', $sql); } else { $sql = preg_replace("/^\s*SELECT(.*?\s)FROM(?!_)/is", 'SELECT ' . $fields . ' FROM ', $sql); } $totals = $this->Conn->Query($sql); foreach ($totals as $totals_row) { foreach ($totals_row as $total_field => $field_value) { if ( !isset($this->Totals[$total_field]) ) { $this->Totals[$total_field] = 0; } $this->Totals[$total_field] += $field_value; } } $this->TotalsCalculated = true; } /** * Returns previously calculated total (not formatted) * * @param string $field * @param string $total_function * @return float * @access public */ public function getTotal($field, $total_function) { if (!$this->TotalsCalculated) { $this->CalculateTotals(); } return $this->Totals[$field . '_' . $total_function]; } function setTotal($field, $total_function, $value) { $this->Totals[$field . '_' . $total_function] = $value; } function getTotalFunction($field) { if ( $this->gridName ) { $grid = $this->getUnitConfig()->getGridByName($this->gridName); $field_options = $grid['Fields'][$field]; } else { $field_options = $this->Fields[$field]; } if ( $this->gridName && array_key_exists('totals', $field_options) && $field_options['totals'] ) { return $field_options['totals']; } elseif ( array_key_exists('totals', $this->Fields[$field]) && $this->Fields[$field]['totals'] ) { return $this->Fields[$field]['totals']; } return false; } /** * Returns previously calculated total (formatted) * * @param string $field * @param string $total_function * @return float * @access public */ function GetFormattedTotal($field, $total_function) { $res = $this->getTotal($field, $total_function); $formatter_class = $this->GetFieldOption($field, 'formatter'); if ( $formatter_class ) { $formatter = $this->Application->recallObject($formatter_class); /* @var $formatter kFormatter */ $res = $formatter->Format($res, $field, $this); } return $res; } /** * Builds full select query except for LIMIT clause * * @param bool $for_counting * @param bool $system_filters_only * @param string $keep_clause * @return string * @access public */ public function GetSelectSQL($for_counting = false, $system_filters_only = false, $keep_clause = '') { $q = parent::GetSelectSQL($this->SelectClause); $q = !$for_counting ? $this->addCalculatedFields($q, 0) : str_replace('%2$s', '', $q); $where = $this->GetWhereClause($for_counting,$system_filters_only); $having = $this->GetHavingClause($for_counting,$system_filters_only); $order = $this->GetOrderClause(); $group = $this->GetGroupClause(); if ( $for_counting ) { $usage_string = $where . '|' . $having . '|' . $order . '|' . $group . '|' . $keep_clause; $optimizer = new LeftJoinOptimizer($q, $this->replaceModePrefix( str_replace('%1$s', $this->TableName, $usage_string) )); $q = $optimizer->simplify(); } if (!empty($where)) $q .= ' WHERE ' . $where; if (!empty($group)) $q .= ' GROUP BY ' . $group; if (!empty($having)) $q .= ' HAVING ' . $having; if ( !$for_counting && !empty($order) ) $q .= ' ORDER BY ' . $order; return $this->replaceModePrefix( str_replace('%1$s', $this->TableName, $q) ); } /** * Replaces all calculated field occurrences with their associated expressions * * @param string $clause where clause to extract calculated fields from * @param int $aggregated 0 - having + aggregated, 1 - having only, 2 - aggregated only * @param bool $replace_table * @return string * @access public */ public function extractCalculatedFields($clause, $aggregated = 1, $replace_table = false) { $fields = $this->getCalculatedFields($aggregated); if ( is_array($fields) && count($fields) > 0 ) { foreach ($fields as $field_name => $field_expression) { $clause = preg_replace('/(\\(+)[(,` ]*' . $field_name . '[` ]{1}/', '\1 (' . $field_expression . ') ', $clause); $clause = preg_replace('/[,` ]{1}' . $field_name . '[` ]{1}/', ' (' . $field_expression . ') ', $clause); } } return $replace_table ? str_replace('%1$s', $this->TableName, $clause) : $clause; } /** * Returns WHERE clause of the query * * @param bool $for_counting merge where filters with having filters + replace field names for having fields with their values * @param bool $system_filters_only * @return string * @access private */ private function GetWhereClause($for_counting=false,$system_filters_only=false) { $where = $this->Application->makeClass('kMultipleFilter'); /* @var $where kMultipleFilter */ if ( $for_counting ) { $where->addFilter('system_where', $this->extractCalculatedFields($this->WhereFilter[self::FLT_SYSTEM]->getSQL()) ); } else { $where->addFilter('system_where', $this->WhereFilter[self::FLT_SYSTEM] ); } if (!$system_filters_only) { $where->addFilter('view_where', $this->WhereFilter[self::FLT_VIEW] ); $search_w = $this->WhereFilter[self::FLT_SEARCH]->getSQL(); if ($search_w || $for_counting) { // move search_having to search_where in case search_where isset or we are counting $search_h = $this->extractCalculatedFields( $this->HavingFilter[self::FLT_SEARCH]->getSQL() ); $search_w = ($search_w && $search_h) ? $search_w.' OR '.$search_h : $search_w.$search_h; $where->addFilter('search_where', $search_w ); } // CUSTOM $search_w = $this->WhereFilter[self::FLT_CUSTOM]->getSQL(); if ($search_w || $for_counting) { // move search_having to search_where in case search_where isset or we are counting $search_h = $this->extractCalculatedFields( $this->HavingFilter[self::FLT_CUSTOM]->getSQL() ); $search_w = ($search_w && $search_h) ? $search_w.' AND '.$search_h : $search_w.$search_h; $where->addFilter('custom_where', $search_w ); } // CUSTOM } if( $for_counting ) // add system_having and view_having to where { $where->addFilter('system_having', $this->extractCalculatedFields($this->HavingFilter[kDBList::FLT_SYSTEM]->getSQL()) ); if (!$system_filters_only) $where->addFilter('view_having', $this->extractCalculatedFields( $this->HavingFilter[kDBList::FLT_VIEW]->getSQL() ) ); } return $where->getSQL(); } /** * Returns HAVING clause of the query * * @param bool $for_counting don't return having filter in case if this is counting sql * @param bool $system_filters_only return only system having filters * @param int $aggregated 0 - aggregated and having, 1 - having only, 2 - aggregated only * @return string * @access private */ private function GetHavingClause($for_counting=false, $system_filters_only=false, $aggregated = 0) { if ($for_counting) { $aggregate_filter = $this->Application->makeClass('kMultipleFilter'); /* @var $aggregate_filter kMultipleFilter */ $aggregate_filter->addFilter('aggregate_system', $this->AggregateFilter[kDBList::FLT_SYSTEM]); if (!$system_filters_only) { $aggregate_filter->addFilter('aggregate_view', $this->AggregateFilter[kDBList::FLT_VIEW]); } return $this->extractCalculatedFields($aggregate_filter->getSQL(), 2); } $having = $this->Application->makeClass('kMultipleFilter'); /* @var $having kMultipleFilter */ $having->addFilter('system_having', $this->HavingFilter[kDBList::FLT_SYSTEM] ); if ($aggregated == 0) { if (!$system_filters_only) { $having->addFilter('view_aggregated', $this->AggregateFilter[kDBList::FLT_VIEW] ); } $having->addFilter('system_aggregated', $this->AggregateFilter[kDBList::FLT_SYSTEM]); } if (!$system_filters_only) { $having->addFilter('view_having', $this->HavingFilter[kDBList::FLT_VIEW] ); $having->addFilter('custom_having', $this->HavingFilter[kDBList::FLT_CUSTOM] ); $search_w = $this->WhereFilter[kDBList::FLT_SEARCH]->getSQL(); if (!$search_w) { $having->addFilter('search_having', $this->HavingFilter[kDBList::FLT_SEARCH] ); } } return $having->getSQL(); } /** * Returns GROUP BY clause of the query * * @return string * @access protected */ protected function GetGroupClause() { return $this->GroupByFields ? implode(',', $this->GroupByFields) : ''; } /** * Adds new group by field * * @param string $field * @access public */ public function AddGroupByField($field) { $this->GroupByFields[$field] = $field; } /** * Removes group by field added before * * @param string $field * @access public */ public function RemoveGroupByField($field) { unset($this->GroupByFields[$field]); } /** * Adds order field to ORDER BY clause * * @param string $field Field name * @param string $direction Direction of ordering (asc|desc) * @param bool $is_expression this is expression, that should not be escapted by "`" symbols * @return int * @access public */ public function AddOrderField($field, $direction = 'asc', $is_expression = false) { // original multilanguage field - convert to current lang field $formatter = isset($this->Fields[$field]['formatter']) ? $this->Fields[$field]['formatter'] : false; if ($formatter == 'kMultiLanguage' && !isset($this->Fields[$field]['master_field'])) { // for now kMultiLanguage formatter is only supported for real (non-virtual) fields $is_expression = true; $field = $this->getMLSortField($field); } if (!isset($this->Fields[$field]) && $field != 'RAND()' && !$is_expression) { trigger_error('Incorrect sorting defined (field = '.$field.'; direction = '.$direction.') in config for prefix '.$this->Prefix.'', E_USER_NOTICE); } $this->OrderFields[] = Array($field, $direction, $is_expression); return count($this->OrderFields) - 1; } /** * Sets new order fields, replacing existing ones * * @param Array $order_fields * @return void * @access public */ public function setOrderFields($order_fields) { $this->OrderFields = $order_fields; } /** * Changes sorting direction for a given sorting field index * * @param int $field_index * @param string $direction * @return void * @access public */ public function changeOrderDirection($field_index, $direction) { if ( !isset($this->OrderFields[$field_index]) ) { return; } $this->OrderFields[$field_index][1] = $direction; } /** * Returns expression, used to sort given multilingual field * * @param string $field * @return string */ function getMLSortField($field) { $table_name = '`' . $this->TableName . '`'; $lang = $this->Application->GetVar('m_lang'); $primary_lang = $this->Application->GetDefaultLanguageId(); $ret = 'IF(COALESCE(%1$s.l' . $lang . '_' . $field . ', ""), %1$s.l' . $lang . '_' . $field . ', %1$s.l' . $primary_lang . '_' . $field . ')'; return sprintf($ret, $table_name); } /** * Removes all order fields * * @access public */ public function ClearOrderFields() { $this->OrderFields = Array(); } /** * Returns ORDER BY Clause of the query * * The method builds order by clause by iterating {@link kDBList::OrderFields} array and concatenating it. * * @return string * @access private */ private function GetOrderClause() { $ret = ''; foreach ($this->OrderFields as $field) { $name = $field[0]; $ret .= isset($this->Fields[$name]) && !isset($this->VirtualFields[$name]) ? '`'.$this->TableName.'`.' : ''; if ($field[0] == 'RAND()' || $field[2]) { $ret .= $field[0].' '.$field[1].','; } else { $ret .= (strpos($field[0], '.') === false ? '`'.$field[0] . '`' : $field[0]) . ' ' . $field[1] . ','; } } $ret = rtrim($ret, ','); return $ret; } /** * Returns order field name in given position * * @param int $pos * @param bool $no_default * @return string * @access public */ public function GetOrderField($pos = NULL, $no_default = false) { if ( !(isset($this->OrderFields[$pos]) && $this->OrderFields[$pos]) && !$no_default ) { $pos = 0; } if ( isset($this->OrderFields[$pos][0]) ) { $field = $this->OrderFields[$pos][0]; $lang = $this->Application->GetVar('m_lang'); if ( preg_match('/^IF\(COALESCE\(.*?\.(l' . $lang . '_.*?), ""\),/', $field, $regs) ) { // undo result of kDBList::getMLSortField method return $regs[1]; } return $field; } return ''; } /** * Returns list order fields * * @return Array * @access public */ public function getOrderFields() { return $this->OrderFields; } /** * Returns order field direction in given position * * @param int $pos * @param bool $no_default * @return string * @access public */ public function GetOrderDirection($pos = NULL, $no_default = false) { if ( !(isset($this->OrderFields[$pos]) && $this->OrderFields[$pos]) && !$no_default ) { $pos = 0; } return isset($this->OrderFields[$pos][1]) ? $this->OrderFields[$pos][1] : ''; } /** * Returns ID of currently processed record * * @return int * @access public */ public function GetID() { return $this->Queried ? $this->GetDBField($this->IDField) : null; } /** * Allows kDBTagProcessor.SectionTitle to detect if it's editing or new item creation * * @return bool * @access public */ public function IsNewItem() { // no such thing as NewItem for lists :) return false; } /** * Return unformatted field value * * @param string $name * @return string * @access public */ public function GetDBField($name) { $row =& $this->getCurrentRecord(); if (defined('DEBUG_MODE') && DEBUG_MODE && $this->Queried && !array_key_exists($name, $row)) { if ( $this->Application->isDebugMode() ) { $this->Application->Debugger->appendTrace(); } trigger_error('Field "' . $name . '" doesn\'t exist in prefix ' . $this->getPrefixSpecial() . '', E_USER_WARNING); return 'NO SUCH FIELD'; } // return "null" for missing fields, because formatter require such behaviour ! return array_key_exists($name, $row) ? $row[$name] : null; } /** * Checks if requested field is present after database query * * @param string $name * @return bool * @access public */ public function HasField($name) { $row =& $this->getCurrentRecord(); return isset($row[$name]); } /** * Returns current record fields * * @return Array * @access public */ public function GetFieldValues() { $record =& $this->getCurrentRecord(); return $record; } /** * Returns current record from list * * @param int $offset Offset relative to current record index * @return Array * @access public */ public function &getCurrentRecord($offset = 0) { $record_index = $this->CurrentIndex + $offset; if ($record_index >=0 && $record_index < $this->SelectedCount) { return $this->Records[$record_index]; } $false = false; return $false; } /** * Goes to record with given index * * @param int $index * @access public */ public function GoIndex($index) { $this->CurrentIndex = $index; } /** * Goes to first record * * @access public */ public function GoFirst() { $this->CurrentIndex = 0; } /** * Goes to next record * * @access public */ public function GoNext() { $this->CurrentIndex++; } /** * Goes to previous record * * @access public */ public function GoPrev() { if ($this->CurrentIndex>0) { $this->CurrentIndex--; } } /** * Checks if there is no end of list * * @return bool * @access public */ public function EOL() { return ($this->CurrentIndex >= $this->SelectedCount); } /** * Returns total page count based on list per-page * * @return int * @access public */ public function GetTotalPages() { if ( !$this->Counted ) { $this->CountRecs(); } if ( $this->PerPage == -1 ) { return 1; } $integer_part = ($this->RecordsCount - ($this->RecordsCount % $this->PerPage)) / $this->PerPage; $reminder = ($this->RecordsCount % $this->PerPage) != 0; // adds 1 if there is a reminder $this->TotalPages = $integer_part + $reminder; return $this->TotalPages; } /** * Sets number of records to query per page * * @param int $per_page Number of records to display per page * @access public */ public function SetPerPage($per_page) { $this->PerPage = $per_page; } /** * Returns records per page count * * @param bool $in_fact * @return int * @access public */ public function GetPerPage($in_fact = false) { if ($in_fact) { return $this->PerPage; } return $this->PerPage == -1 ? $this->RecordsCount : $this->PerPage; } /** * Sets current page in list * * @param int $page * @access public */ public function SetPage($page) { if ($this->PerPage == -1) { $this->Page = 1; return; } if ($page < 1) $page = 1; $this->Offset = ($page-1)*$this->PerPage; if ($this->Counted && $this->Offset > $this->RecordsCount) { $this->SetPage(1); } else { $this->Page = $page; } //$this->GoFirst(); } /** * Returns current list page * * @return int * @access public */ public function GetPage() { return $this->Page; } /** * Sets list query offset * * @param int $offset * @access public */ public function SetOffset($offset) { $this->Offset = $offset; } /** * Gets list query offset * * @return int * @access public */ public function GetOffset() { return $this->Offset; } /** * Sets current item field value (doesn't apply formatting) * * @param string $name Name of the field * @param mixed $value Value to set the field to * @access public */ public function SetDBField($name,$value) { $this->Records[$this->CurrentIndex][$name] = $value; } /** * Apply where clause, that links this object to it's parent item * * @param string $special * @access public */ public function linkToParent($special) { $config = $this->getUnitConfig(); $parent_prefix = $config->getParentPrefix(); if ( $parent_prefix ) { $parent_table_key = $config->getParentTableKey($parent_prefix); $foreign_key_field = $config->getForeignKey($parent_prefix); if ( !$parent_table_key || !$foreign_key_field ) { return; } $parent_object = $this->Application->recallObject($parent_prefix . '.' . $special); /* @var $parent_object kDBItem */ if ( !$parent_object->isLoaded() ) { $this->addFilter('parent_filter', 'FALSE'); trigger_error('Parent ID not found (prefix: "' . rtrim($parent_prefix . '.' . $special, '.') . '"; sub-prefix: "' . $this->getPrefixSpecial() . '")', E_USER_NOTICE); return; } // only for list in this case $parent_id = $parent_object->GetDBField($parent_table_key); $this->addFilter('parent_filter', '`' . $this->TableName . '`.`' . $foreign_key_field . '` = ' . $this->Conn->qstr($parent_id)); } } /** * Returns true if list was queried (same name as for kDBItem for easy usage) * * @return bool * @access public */ public function isLoaded() { return $this->Queried && !$this->EOL(); } /** * Returns specified field value from all selected rows. * Don't affect current record index * * @param string $field * @param bool $formatted * @param string $format * @return Array * @access public */ public function GetCol($field, $formatted = false, $format = null) { $i = 0; $ret = Array (); if ($formatted && array_key_exists('formatter', $this->Fields[$field])) { $formatter = $this->Application->recallObject($this->Fields[$field]['formatter']); /* @var $formatter kFormatter */ while ($i < $this->SelectedCount) { $ret[] = $formatter->Format($this->Records[$i][$field], $field, $this, $format); $i++; } } else { while ($i < $this->SelectedCount) { $ret[] = $this->Records[$i][$field]; $i++; } } return $ret; } /** * Set's field error, if pseudo passed not found then create it with message text supplied. * Don't overwrite existing pseudo translation. * * @param string $field * @param string $pseudo * @param string $error_label * @param Array $error_params * @return bool * @access public * @see kSearchHelper::processRangeField() * @see kDateFormatter::Parse() */ public function SetError($field, $pseudo, $error_label = null, $error_params = null) { $error_field = isset($this->Fields[$field]['error_field']) ? $this->Fields[$field]['error_field'] : $field; $this->FieldErrors[$error_field]['pseudo'] = $pseudo; $var_name = $this->getPrefixSpecial() . '_' . $field . '_error'; $previous_pseudo = $this->Application->RecallVar($var_name); if ( $previous_pseudo ) { // don't set more then one error on field return false; } $this->Application->StoreVar($var_name, $pseudo); return true; } /** * Returns error pseudo * * @param string $field * @return string * @access public * @see kSearchHelper::processRangeField() */ public function GetErrorPseudo($field) { if ( !isset($this->FieldErrors[$field]) ) { return ''; } return isset($this->FieldErrors[$field]['pseudo']) ? $this->FieldErrors[$field]['pseudo'] : ''; } /** * Removes error on field * * @param string $field * @access public */ public function RemoveError($field) { unset( $this->FieldErrors[$field] ); } /** * Group list records by header, saves internal order in group * * @param string $heading_field * @access public */ public function groupRecords($heading_field) { $i = 0; $sorted = Array (); while ($i < $this->SelectedCount) { $sorted[ $this->Records[$i][$heading_field] ][] = $this->Records[$i]; $i++; } $this->Records = Array (); foreach ($sorted as $heading => $heading_records) { $this->Records = array_merge_recursive($this->Records, $heading_records); } } /** * Reset list (use for requering purposes) * * @access public */ public function reset() { $this->Counted = false; $this->clearFilters(); $this->ClearOrderFields(); } /** * Checks if list was counted * * @return bool * @access public */ public function isCounted() { return $this->Counted; } /** * Tells, that given list is main * * @return bool * @access public */ public function isMainList() { return $this->mainList; } /** * Makes given list as main * * @access public */ public function becameMain() { $this->mainList = true; } /** * Moves recordset pointer to first element * * @return void * @access public * @implements Iterator::rewind */ public function rewind() { $this->Query(); $this->GoFirst(); } /** * Returns value at current position * * @return mixed * @access public * @implements Iterator::current */ function current() { return $this->getCurrentRecord(); } /** * Returns key at current position * * @return mixed * @access public * @implements Iterator::key */ function key() { return $this->CurrentIndex; } /** * Moves recordset pointer to next position * * @return void * @access public * @implements Iterator::next */ function next() { $this->GoNext(); } /** * Detects if current position is within recordset bounds * * @return bool * @access public * @implements Iterator::valid */ public function valid() { return !$this->EOL(); } /** * Counts recordset rows * * @return int * @access public * @implements Countable::count */ public function count() { return $this->SelectedCount; } } class LeftJoinOptimizer { /** * Input sql for optimization * * @var string * @access private */ private $sql = ''; /** * All sql parts, where LEFT JOINed table aliases could be used * * @var string * @access private */ private $usageString = ''; /** * List of discovered LEFT JOINs * * @var Array * @access private */ private $joins = Array (); /** * LEFT JOIN relations * * @var Array * @access private */ private $joinRelations = Array (); /** * LEFT JOIN table aliases scheduled for removal * * @var Array * @access private */ private $aliasesToRemove = Array (); /** * Creates new instance of the class * * @param string $sql * @param string $usage_string */ public function __construct($sql, $usage_string) { $this->sql = $sql; $this->usageString = $usage_string; $this->parseJoins(); } /** * Tries to remove unused LEFT JOINs * * @return string * @access public */ public function simplify() { if ( !$this->joins ) { // no LEFT JOIN used, return unchanged sql return $this->sql; } $this->updateRelations(); $this->removeAliases(); return $this->sql; } /** * Discovers LEFT JOINs based on given sql * * @return void * @access private */ private function parseJoins() { if ( !preg_match_all('/LEFT\s+JOIN\s+(.*?|.*?\s+AS\s+.*?|.*?\s+.*?)\s+ON\s+(.*?\n|.*?$)/si', $this->sql, $regs) ) { $this->joins = Array (); } // get all LEFT JOIN clause info from sql (without filters) foreach ($regs[1] as $index => $match) { $match_parts = preg_split('/\s+AS\s+|\s+/i', $match, 2); $table_alias = count($match_parts) == 1 ? $match : $match_parts[1]; $this->joins[$table_alias] = Array ( 'table' => $match_parts[0], 'join_clause' => $regs[0][$index], ); } } /** * Detects relations between LEFT JOINs * * @return void * @access private */ private function updateRelations() { foreach ($this->joins as $table_alias => $left_join_info) { $escaped_alias = preg_quote($table_alias, '/'); foreach ($this->joins as $sub_table_alias => $sub_left_join_info) { if ($table_alias == $sub_table_alias) { continue; } if ( $this->matchAlias($escaped_alias, $sub_left_join_info['join_clause']) ) { $this->joinRelations[] = $sub_table_alias . ':' . $table_alias; } } } } /** * Removes scheduled LEFT JOINs, but only if they are not protected * * @return void * @access private */ private function removeAliases() { $this->prepareAliasesRemoval(); foreach ($this->aliasesToRemove as $to_remove_alias) { if ( !$this->aliasProtected($to_remove_alias) ) { $this->sql = str_replace($this->joins[$to_remove_alias]['join_clause'], '', $this->sql); } } } /** * Schedules unused LEFT JOINs to for removal * * @return void * @access private */ private function prepareAliasesRemoval() { foreach ($this->joins as $table_alias => $left_join_info) { $escaped_alias = preg_quote($table_alias, '/'); if ( !$this->matchAlias($escaped_alias, $this->usageString) ) { $this->aliasesToRemove[] = $table_alias; } } } /** * Checks if someone wants to remove LEFT JOIN, but it's used by some other LEFT JOIN, that stays * * @param string $table_alias * @return bool * @access private */ private function aliasProtected($table_alias) { foreach ($this->joinRelations as $relation) { list ($main_alias, $used_alias) = explode(':', $relation); if ( ($used_alias == $table_alias) && !in_array($main_alias, $this->aliasesToRemove) ) { return true; } } return false; } /** * Matches given escaped alias to a string * * @param string $escaped_alias * @param string $string * @return bool * @access private */ private function matchAlias($escaped_alias, $string) { return preg_match('/(`' . $escaped_alias . '`|' . $escaped_alias . ')\./', $string); } } Index: branches/5.3.x/core/kernel/startup.php =================================================================== --- branches/5.3.x/core/kernel/startup.php (revision 16123) +++ branches/5.3.x/core/kernel/startup.php (revision 16124) @@ -1,198 +1,205 @@ getData(); } catch ( kSystemConfigException $e ) { echo 'In-Portal is probably not installed, or configuration file is missing.
'; echo 'Please use the installation script to fix the problem.

'; $base_path = rtrim(str_replace('\\', '/', dirname($_SERVER['PHP_SELF'])), '/'); echo 'Go to installation script

'; flush(); exit; } define('CHARSET', $vars['WebsiteCharset']); define('ADMIN_DIRECTORY', $vars['AdminDirectory']); define('ADMIN_PRESETS_DIRECTORY', $vars['AdminPresetsDirectory']); $https_mark = getArrayValue($_SERVER, 'HTTPS'); define('PROTOCOL', ($https_mark == 'on') || ($https_mark == '1') ? 'https://' : 'http://'); if ( isset($_SERVER['HTTP_HOST']) ) { // accessed from browser $http_host = $_SERVER['HTTP_HOST']; } else { // accessed from command line $http_host = $vars['Domain']; $_SERVER['HTTP_HOST'] = $vars['Domain']; } $port = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : false; if ($port) { if ( (PROTOCOL == 'http://' && $port != '80') || (PROTOCOL == 'https://' && $port != '443') ) { // if non-standard port is used, then define it define('PORT', $port); } $http_host = preg_replace('/:' . $port . '$/', '', $http_host); } define('SERVER_NAME', $http_host); + if ( !file_exists(FULL_PATH . '/vendor/autoload.php') ) { + echo 'Cannot find an "/vendor/autoload.php" file, have you executed "composer install" command?
'; + flush(); + exit; + } + // variable WebsitePath is auto-detected once during installation/upgrade define('BASE_PATH', $vars['WebsitePath']); define('APPLICATION_CLASS', $vars['ApplicationClass']); define('APPLICATION_PATH', $vars['ApplicationPath']); if (isset($vars['WriteablePath'])) { define('WRITEABLE', FULL_PATH . $vars['WriteablePath']); define('WRITEBALE_BASE', $vars['WriteablePath']); } if ( isset($vars['RestrictedPath']) ) { define('RESTRICTED', FULL_PATH . $vars['RestrictedPath']); } define('SQL_TYPE', $vars['DBType']); define('SQL_SERVER', $vars['DBHost']); define('SQL_USER', $vars['DBUser']); define('SQL_PASS', $vars['DBUserPassword']); define('SQL_DB', $vars['DBName']); if (isset($vars['DBCollation']) && isset($vars['DBCharset'])) { define('SQL_COLLATION', $vars['DBCollation']); // utf8_general_ci define('SQL_CHARSET', $vars['DBCharset']); // utf8 } define('TABLE_PREFIX', $vars['TablePrefix']); define('DOMAIN', getArrayValue($vars, 'Domain')); ini_set('memory_limit', '50M'); define('MODULES_PATH', FULL_PATH . DIRECTORY_SEPARATOR . 'modules'); define('EXPORT_BASE_PATH', WRITEBALE_BASE . '/export'); define('EXPORT_PATH', FULL_PATH . EXPORT_BASE_PATH); define('GW_CLASS_PATH', MODULES_PATH . '/in-commerce/units/gateways/gw_classes'); // Payment Gateway Classes Path define('SYNC_CLASS_PATH', FULL_PATH . '/sync'); // path for 3rd party user syncronization scripts define('ENV_VAR_NAME','env'); define('IMAGES_PATH', WRITEBALE_BASE . '/images/'); define('IMAGES_PENDING_PATH', IMAGES_PATH . 'pending/'); define('MAX_UPLOAD_SIZE', min(ini_get('upload_max_filesize'), ini_get('post_max_size'))*1024*1024); define('EDITOR_PATH', $vars['EditorPath']); // caching types define('CACHING_TYPE_NONE', 0); define('CACHING_TYPE_MEMORY', 1); define('CACHING_TYPE_TEMPORARY', 2); class CacheSettings { static public $unitCacheRebuildTime; static public $structureTreeRebuildTime; static public $cmsMenuRebuildTime; static public $templateMappingRebuildTime; static public $sectionsParsedRebuildTime; static public $domainsParsedRebuildTime; } CacheSettings::$unitCacheRebuildTime = $vars['UnitCacheRebuildTime']; CacheSettings::$structureTreeRebuildTime = $vars['StructureTreeRebuildTime']; CacheSettings::$cmsMenuRebuildTime = $vars['CmsMenuRebuildTime']; CacheSettings::$templateMappingRebuildTime = $vars['TemplateMappingRebuildTime']; CacheSettings::$sectionsParsedRebuildTime = $vars['SectionsParsedRebuildTime']; CacheSettings::$domainsParsedRebuildTime = $vars['DomainsParsedRebuildTime']; class MaintenanceMode { const NONE = 0; const SOFT = 1; const HARD = 2; } unset($vars); // just in case someone will be still using it if (ini_get('safe_mode')) { // safe mode will be removed at all in PHP6 define('SAFE_MODE', 1); } if (file_exists(WRITEABLE . '/debug.php')) { include_once(WRITEABLE . '/debug.php'); if (array_key_exists('DEBUG_MODE', $dbg_options) && $dbg_options['DEBUG_MODE']) { $debugger_start = microtime(true); include_once(KERNEL_PATH . '/utility/debugger.php'); $debugger_end = microtime(true); if (isset($debugger) && kUtil::constOn('DBG_PROFILE_INCLUDES')) { $debugger->profileStart('inc_globals', KERNEL_PATH . '/globals.php', $globals_start); $debugger->profileFinish('inc_globals', KERNEL_PATH . '/globals.php', $globals_end); $debugger->profilerAddTotal('includes', 'inc_globals'); $debugger->profileStart('inc_debugger', KERNEL_PATH . '/utility/debugger.php', $debugger_start); $debugger->profileFinish('inc_debugger', KERNEL_PATH . '/utility/debugger.php', $debugger_end); $debugger->profilerAddTotal('includes', 'inc_debugger'); } } } kUtil::safeDefine('SILENT_LOG', 0); // can be set in "debug.php" too $includes = Array( KERNEL_PATH . "/interfaces/cacheable.php", KERNEL_PATH . '/application.php', FULL_PATH . APPLICATION_PATH, KERNEL_PATH . "/kbase.php", KERNEL_PATH . '/db/i_db_connection.php', KERNEL_PATH . '/db/db_connection.php', KERNEL_PATH . '/db/db_load_balancer.php', KERNEL_PATH . '/utility/event.php', KERNEL_PATH . '/utility/logger.php', KERNEL_PATH . "/utility/factory.php", KERNEL_PATH . "/languages/phrases_cache.php", KERNEL_PATH . "/db/dblist.php", KERNEL_PATH . "/db/dbitem.php", KERNEL_PATH . "/event_handler.php", KERNEL_PATH . '/db/db_event_handler.php', + FULL_PATH . '/vendor/autoload.php', ); foreach ($includes as $a_file) { kUtil::includeOnce($a_file); } if (defined('DEBUG_MODE') && DEBUG_MODE && isset($debugger)) { $debugger->AttachToApplication(); } // system users define('USER_ROOT', -1); - define('USER_GUEST', -2); \ No newline at end of file + define('USER_GUEST', -2); Index: branches/5.3.x/core/kernel/application.php =================================================================== --- branches/5.3.x/core/kernel/application.php (revision 16123) +++ branches/5.3.x/core/kernel/application.php (revision 16124) @@ -1,3076 +1,3082 @@ * The class encapsulates the main run-cycle of the script, provide access to all other objects in the framework.
*
* The class is a singleton, which means that there could be only one instance of kApplication in the script.
* This could be guaranteed by NOT calling the class constructor directly, but rather calling kApplication::Instance() method, * which returns an instance of the application. The method guarantees that it will return exactly the same instance for any call.
* See singleton pattern by GOF. */ class kApplication implements kiCacheable { /** * Location of module helper class (used in installator too) */ const MODULE_HELPER_PATH = '/../units/helpers/modules_helper.php'; /** * Is true, when Init method was called already, prevents double initialization * * @var bool */ public $InitDone = false; /** * Holds internal NParser object * * @var NParser * @access public */ public $Parser; /** * Holds parser output buffer * * @var string * @access protected */ protected $HTML = ''; /** * The main Factory used to create * almost any class of kernel and * modules * * @var kFactory * @access protected */ protected $Factory; /** * Template names, that will be used instead of regular templates * * @var Array * @access public */ public $ReplacementTemplates = Array (); /** * Mod-Rewrite listeners used during url building and parsing * * @var Array * @access public */ public $RewriteListeners = Array (); /** * Reference to debugger * * @var Debugger * @access public */ public $Debugger = null; /** * Holds all phrases used * in code and template * * @var PhrasesCache * @access public */ public $Phrases; /** * Modules table content, key - module name * * @var Array * @access public */ public $ModuleInfo = Array (); /** * Holds DBConnection * * @var IDBConnection * @access public */ public $Conn = null; /** * Reference to event log * * @var Array|kLogger * @access public */ protected $_logger = Array (); // performance needs: /** * Holds a reference to httpquery * * @var kHttpQuery * @access public */ public $HttpQuery = null; /** * Holds a reference to UnitConfigReader * * @var kUnitConfigReader * @access public */ public $UnitConfigReader = null; /** * Holds a reference to Session * * @var Session * @access public */ public $Session = null; /** * Holds a ref to kEventManager * * @var kEventManager * @access public */ public $EventManager = null; /** * Holds a ref to kUrlManager * * @var kUrlManager * @access public */ public $UrlManager = null; /** * Ref for TemplatesCache * * @var TemplatesCache * @access public */ public $TemplatesCache = null; /** * Holds current NParser tag while parsing, can be used in error messages to display template file and line * * @var _BlockTag * @access public */ public $CurrentNTag = null; /** * Object of unit caching class * * @var kCacheManager * @access public */ public $cacheManager = null; /** * Tells, that administrator has authenticated in administrative console * Should be used to manipulate data change OR data restrictions! * * @var bool * @access public */ public $isAdminUser = false; /** * Tells, that admin version of "index.php" was used, nothing more! * Should be used to manipulate data display! * * @var bool * @access public */ public $isAdmin = false; /** * Instance of site domain object * * @var kDBItem * @access public * @todo move away into separate module */ public $siteDomain = null; /** * Prevent kApplication class to be created directly, only via Instance method * * @access private */ private function __construct() { } final private function __clone() {} /** * Returns kApplication instance anywhere in the script. * * This method should be used to get single kApplication object instance anywhere in the * Kernel-based application. The method is guaranteed to return the SAME instance of kApplication. * Anywhere in the script you could write: * * $application =& kApplication::Instance(); * * or in an object: * * $this->Application =& kApplication::Instance(); * * to get the instance of kApplication. Note that we call the Instance method as STATIC - directly from the class. * To use descendant of standard kApplication class in your project you would need to define APPLICATION_CLASS constant * BEFORE calling kApplication::Instance() for the first time. If APPLICATION_CLASS is not defined the method would * create and return default KernelApplication instance. * * Pattern: Singleton * * @static * @return kApplication * @access public */ public static function &Instance() { static $instance = false; if ( !$instance ) { $class = defined('APPLICATION_CLASS') ? APPLICATION_CLASS : 'kApplication'; $instance = new $class(); } return $instance; } /** * Initializes the Application * * @param string $factory_class * @return bool Was Init actually made now or before * @access public * @see kHTTPQuery * @see Session * @see TemplatesCache */ public function Init($factory_class = 'kFactory') { if ( $this->InitDone ) { return false; } if ( preg_match('/utf-8/i', CHARSET) ) { setlocale(LC_ALL, 'en_US.UTF-8'); mb_internal_encoding('UTF-8'); } $this->isAdmin = kUtil::constOn('ADMIN'); if ( !kUtil::constOn('SKIP_OUT_COMPRESSION') ) { ob_start(); // collect any output from method (other then tags) into buffer } if ( defined('DEBUG_MODE') && $this->isDebugMode() && kUtil::constOn('DBG_PROFILE_MEMORY') ) { $this->Debugger->appendMemoryUsage('Application before Init:'); } $this->_logger = new kLogger($this->_logger); $this->Factory = new $factory_class(); $this->registerDefaultClasses(); $system_config = new kSystemConfig(true); $vars = $system_config->getData(); $db_class = isset($vars['Databases']) ? 'kDBLoadBalancer' : ($this->isDebugMode() ? 'kDBConnectionDebug' : 'kDBConnection'); $this->Conn = $this->Factory->makeClass($db_class, Array (SQL_TYPE, Array ($this->_logger, 'handleSQLError'))); $this->Conn->setup($vars); $this->cacheManager = $this->makeClass('kCacheManager'); $this->cacheManager->InitCache(); if ( defined('DEBUG_MODE') && $this->isDebugMode() ) { $this->Debugger->appendTimestamp('Before UnitConfigReader'); } // init config reader and all managers $this->UnitConfigReader = $this->makeClass('kUnitConfigReader'); $this->UnitConfigReader->scanModules(MODULES_PATH); // will also set RewriteListeners when existing cache is read $this->registerModuleConstants(); if ( defined('DEBUG_MODE') && $this->isDebugMode() ) { $this->Debugger->appendTimestamp('After UnitConfigReader'); } define('MOD_REWRITE', $this->ConfigValue('UseModRewrite') && !$this->isAdmin ? 1 : 0); // start processing request $this->HttpQuery = $this->recallObject('HTTPQuery'); $this->HttpQuery->process(); if ( defined('DEBUG_MODE') && $this->isDebugMode() ) { $this->Debugger->appendTimestamp('Processed HTTPQuery initial'); } $this->Session = $this->recallObject('Session'); if ( defined('DEBUG_MODE') && $this->isDebugMode() ) { $this->Debugger->appendTimestamp('Processed Session'); } $this->Session->ValidateExpired(); // needs mod_rewrite url already parsed to keep user at proper template after session expiration if ( defined('DEBUG_MODE') && $this->isDebugMode() ) { $this->Debugger->appendTimestamp('Processed HTTPQuery AfterInit'); } $this->cacheManager->LoadApplicationCache(); $site_timezone = $this->ConfigValue('Config_Site_Time'); if ( $site_timezone ) { date_default_timezone_set($site_timezone); } if ( defined('DEBUG_MODE') && $this->isDebugMode() ) { $this->Debugger->appendTimestamp('Loaded cache and phrases'); } $this->ValidateLogin(); // must be called before AfterConfigRead, because current user should be available there $this->UnitConfigReader->AfterConfigRead(); // will set RewriteListeners when missing cache is built first time if ( defined('DEBUG_MODE') && $this->isDebugMode() ) { $this->Debugger->appendTimestamp('Processed AfterConfigRead'); } if ( $this->GetVar('m_cat_id') === false ) { $this->SetVar('m_cat_id', 0); } if ( !$this->RecallVar('curr_iso') ) { $this->StoreVar('curr_iso', $this->GetPrimaryCurrency(), true); // true for optional } $visit_id = $this->RecallVar('visit_id'); if ( $visit_id !== false ) { $this->SetVar('visits_id', $visit_id); } if ( defined('DEBUG_MODE') && $this->isDebugMode() ) { $this->Debugger->profileFinish('kernel4_startup'); } $this->InitDone = true; $this->HandleEvent(new kEvent('adm:OnStartup')); return true; } /** * Performs initialization of manager classes, that can be overridden from unit configs * * @return void * @access public * @throws Exception */ public function InitManagers() { if ( $this->InitDone ) { throw new Exception('Duplicate call of ' . __METHOD__, E_USER_ERROR); } $this->UrlManager = $this->makeClass('kUrlManager'); $this->EventManager = $this->makeClass('EventManager'); $this->Phrases = $this->makeClass('kPhraseCache'); $this->RegisterDefaultBuildEvents(); } /** * Returns module information. Searches module by requested field * * @param string $field * @param mixed $value * @param string $return_field field value to returns, if not specified, then return all fields * @return Array */ public function findModule($field, $value, $return_field = null) { $found = $module_info = false; foreach ($this->ModuleInfo as $module_info) { if ( strtolower($module_info[$field]) == strtolower($value) ) { $found = true; break; } } if ( $found ) { return isset($return_field) ? $module_info[$return_field] : $module_info; } return false; } /** * Refreshes information about loaded modules * * @return void * @access public */ public function refreshModuleInfo() { if ( defined('IS_INSTALL') && IS_INSTALL && !$this->TableFound('Modules', true) ) { $this->registerModuleConstants(); return; } // use makeClass over recallObject, since used before kApplication initialization during installation $modules_helper = $this->makeClass('ModulesHelper'); /* @var $modules_helper kModulesHelper */ $this->Conn->nextQueryCachable = true; $sql = 'SELECT * FROM ' . TABLE_PREFIX . 'Modules WHERE ' . $modules_helper->getWhereClause() . ' ORDER BY LoadOrder'; $this->ModuleInfo = $this->Conn->Query($sql, 'Name'); $this->registerModuleConstants(); } /** * Checks if passed language id if valid and sets it to primary otherwise * * @return void * @access public */ public function VerifyLanguageId() { - $language_id = $this->GetVar('m_lang'); - - if ( !$language_id ) { - $language_id = 'default'; - } - - $this->SetVar('lang.current_id', $language_id); - $this->SetVar('m_lang', $language_id); - - $lang_mode = $this->GetVar('lang_mode'); - $this->SetVar('lang_mode', ''); - + /** @var LanguagesItem $lang */ $lang = $this->recallObject('lang.current'); - /* @var $lang kDBItem */ if ( !$lang->isLoaded() || (!$this->isAdmin && !$lang->GetDBField('Enabled')) ) { if ( !defined('IS_INSTALL') ) { $this->ApplicationDie('Unknown or disabled language'); } } - - $this->SetVar('lang_mode', $lang_mode); } /** * Checks if passed theme id if valid and sets it to primary otherwise * * @return void * @access public */ public function VerifyThemeId() { if ( $this->isAdmin ) { kUtil::safeDefine('THEMES_PATH', '/core/admin_templates'); return; } $path = $this->GetFrontThemePath(); if ( $path === false ) { $this->ApplicationDie('No Primary Theme Selected or Current Theme is Unknown or Disabled'); } kUtil::safeDefine('THEMES_PATH', $path); } /** * Returns relative path to current front-end theme * * @param bool $force * @return string * @access public */ public function GetFrontThemePath($force = false) { static $path = null; if ( !$force && isset($path) ) { return $path; } - $theme_id = $this->GetVar('m_theme'); - if ( !$theme_id ) { - $theme_id = 'default'; // $this->GetDefaultThemeId(1); // 1 to force front-end mode! - } - - $this->SetVar('m_theme', $theme_id); - $this->SetVar('theme.current_id', $theme_id); // KOSTJA: this is to fool theme' getPassedID - + /** @var ThemeItem $theme */ $theme = $this->recallObject('theme.current'); - /* @var $theme ThemeItem */ if ( !$theme->isLoaded() || !$theme->GetDBField('Enabled') ) { return false; } // assign & then return, since it's static variable $path = '/themes/' . $theme->GetDBField('Name'); return $path; } /** * Returns primary front/admin language id * * @param bool $init * @return int * @access public */ public function GetDefaultLanguageId($init = false) { $cache_key = 'primary_language_info[%LangSerial%]'; $language_info = $this->getCache($cache_key); if ( $language_info === false ) { // cache primary language info first $language_config = $this->getUnitConfig('lang'); $table = $language_config->getTableName(); $id_field = $language_config->getIDField(); $this->Conn->nextQueryCachable = true; $sql = 'SELECT ' . $id_field . ', IF(AdminInterfaceLang, "Admin", "Front") AS LanguageKey FROM ' . $table . ' WHERE (AdminInterfaceLang = 1 OR PrimaryLang = 1) AND (Enabled = 1)'; $language_info = $this->Conn->GetCol($sql, 'LanguageKey'); if ( $language_info !== false ) { $this->setCache($cache_key, $language_info); } } $language_key = ($this->isAdmin && $init) || count($language_info) == 1 ? 'Admin' : 'Front'; if ( array_key_exists($language_key, $language_info) && $language_info[$language_key] > 0 ) { // get from cache return $language_info[$language_key]; } $language_id = $language_info && array_key_exists($language_key, $language_info) ? $language_info[$language_key] : false; if ( !$language_id && defined('IS_INSTALL') && IS_INSTALL ) { $language_id = 1; } return $language_id; } /** * Returns front-end primary theme id (even, when called from admin console) * * @param bool $force_front * @return int * @access public */ public function GetDefaultThemeId($force_front = false) { static $theme_id = 0; if ( $theme_id > 0 ) { return $theme_id; } if ( kUtil::constOn('DBG_FORCE_THEME') ) { $theme_id = DBG_FORCE_THEME; } elseif ( !$force_front && $this->isAdmin ) { $theme_id = 999; } else { $cache_key = 'primary_theme[%ThemeSerial%]'; $theme_id = $this->getCache($cache_key); if ( $theme_id === false ) { $this->Conn->nextQueryCachable = true; $theme_config = $this->getUnitConfig('theme'); $sql = 'SELECT ' . $theme_config->getIDField() . ' FROM ' . $theme_config->getTableName() . ' WHERE (PrimaryTheme = 1) AND (Enabled = 1)'; $theme_id = $this->Conn->GetOne($sql); if ( $theme_id !== false ) { $this->setCache($cache_key, $theme_id); } } } return $theme_id; } /** * Returns site primary currency ISO code * * @return string * @access public * @todo Move into In-Commerce */ public function GetPrimaryCurrency() { $cache_key = 'primary_currency[%CurrSerial%][%SiteDomainSerial%]:' . $this->siteDomainField('DomainId'); $currency_iso = $this->getCache($cache_key); if ( $currency_iso === false ) { if ( $this->prefixRegistred('curr') ) { $this->Conn->nextQueryCachable = true; $currency_id = $this->siteDomainField('PrimaryCurrencyId'); $sql = 'SELECT ISO FROM ' . $this->getUnitConfig('curr')->getTableName() . ' WHERE ' . ($currency_id > 0 ? 'CurrencyId = ' . $currency_id : 'IsPrimary = 1'); $currency_iso = $this->Conn->GetOne($sql); } else { $currency_iso = 'USD'; } $this->setCache($cache_key, $currency_iso); } return $currency_iso; } /** * Returns site domain field. When none of site domains are found false is returned. * * @param string $field * @param bool $formatted * @param string $format * @return mixed * @todo Move into separate module */ public function siteDomainField($field, $formatted = false, $format = null) { if ( $this->isAdmin ) { // don't apply any filtering in administrative console return false; } if ( !$this->siteDomain ) { $this->siteDomain = $this->recallObject('site-domain.current', null, Array ('live_table' => true)); /* @var $site_domain kDBItem */ } if ( $this->siteDomain->isLoaded() ) { return $formatted ? $this->siteDomain->GetField($field, $format) : $this->siteDomain->GetDBField($field); } return false; } /** * Registers default classes such as kDBEventHandler, kUrlManager * * Called automatically while initializing kApplication * * @return void * @access public */ public function RegisterDefaultClasses() { $this->registerClass('kHelper', KERNEL_PATH . '/kbase.php'); $this->registerClass('kMultipleFilter', KERNEL_PATH . '/utility/filters.php'); $this->registerClass('kiCacheable', KERNEL_PATH . '/interfaces/cacheable.php'); $this->registerClass('kEventManager', KERNEL_PATH . '/event_manager.php', 'EventManager'); $this->registerClass('kHookManager', KERNEL_PATH . '/managers/hook_manager.php'); $this->registerClass('kScheduledTaskManager', KERNEL_PATH . '/managers/scheduled_task_manager.php'); $this->registerClass('kRequestManager', KERNEL_PATH . '/managers/request_manager.php'); $this->registerClass('kSubscriptionManager', KERNEL_PATH . '/managers/subscription_manager.php'); $this->registerClass('kUrlManager', KERNEL_PATH . '/managers/url_manager.php'); $this->registerClass('kUrlProcessor', KERNEL_PATH . '/managers/url_processor.php'); $this->registerClass('kPlainUrlProcessor', KERNEL_PATH . '/managers/plain_url_processor.php'); $this->registerClass('kRewriteUrlProcessor', KERNEL_PATH . '/managers/rewrite_url_processor.php'); $this->registerClass('kCacheManager', KERNEL_PATH . '/managers/cache_manager.php'); $this->registerClass('PhrasesCache', KERNEL_PATH . '/languages/phrases_cache.php', 'kPhraseCache'); $this->registerClass('kTempTablesHandler', KERNEL_PATH . '/utility/temp_handler.php'); $this->registerClass('kValidator', KERNEL_PATH . '/utility/validator.php'); $this->registerClass('kOpenerStack', KERNEL_PATH . '/utility/opener_stack.php'); $this->registerClass('kLogger', KERNEL_PATH . '/utility/logger.php'); $this->registerClass('kUnitConfig', KERNEL_PATH . '/utility/unit_config.php'); $this->registerClass('kUnitConfigReader', KERNEL_PATH . '/utility/unit_config_reader.php'); $this->registerClass('kUnitConfigCloner', KERNEL_PATH . '/utility/unit_config_cloner.php'); $this->registerClass('PasswordHash', KERNEL_PATH . '/utility/php_pass.php'); // Params class descendants $this->registerClass('kArray', KERNEL_PATH . '/utility/params.php'); $this->registerClass('Params', KERNEL_PATH . '/utility/params.php'); $this->registerClass('Params', KERNEL_PATH . '/utility/params.php', 'kActions'); $this->registerClass('kCache', KERNEL_PATH . '/utility/cache.php', 'kCache', 'Params'); $this->registerClass('kHTTPQuery', KERNEL_PATH . '/utility/http_query.php', 'HTTPQuery'); // session $this->registerClass('kCookieHasher', KERNEL_PATH . '/utility/cookie_hasher.php'); $this->registerClass('Session', KERNEL_PATH . '/session/session.php'); $this->registerClass('SessionStorage', KERNEL_PATH . '/session/session_storage.php'); $this->registerClass('InpSession', KERNEL_PATH . '/session/inp_session.php', 'Session'); $this->registerClass('InpSessionStorage', KERNEL_PATH . '/session/inp_session_storage.php', 'SessionStorage'); // template parser $this->registerClass('kTagProcessor', KERNEL_PATH . '/processors/tag_processor.php'); $this->registerClass('kMainTagProcessor', KERNEL_PATH . '/processors/main_processor.php', 'm_TagProcessor'); $this->registerClass('kDBTagProcessor', KERNEL_PATH . '/db/db_tag_processor.php'); $this->registerClass('kCatDBTagProcessor', KERNEL_PATH . '/db/cat_tag_processor.php'); $this->registerClass('NParser', KERNEL_PATH . '/nparser/nparser.php'); $this->registerClass('TemplatesCache', KERNEL_PATH . '/nparser/template_cache.php'); // database $this->registerClass('kDBConnection', KERNEL_PATH . '/db/db_connection.php'); $this->registerClass('kDBConnectionDebug', KERNEL_PATH . '/db/db_connection.php'); $this->registerClass('kDBLoadBalancer', KERNEL_PATH . '/db/db_load_balancer.php'); $this->registerClass('kDBItem', KERNEL_PATH . '/db/dbitem.php'); $this->registerClass('kCatDBItem', KERNEL_PATH . '/db/cat_dbitem.php'); $this->registerClass('kDBList', KERNEL_PATH . '/db/dblist.php'); $this->registerClass('kCatDBList', KERNEL_PATH . '/db/cat_dblist.php'); $this->registerClass('kDBEventHandler', KERNEL_PATH . '/db/db_event_handler.php'); $this->registerClass('kCatDBEventHandler', KERNEL_PATH . '/db/cat_event_handler.php'); // email sending $this->registerClass('kEmail', KERNEL_PATH . '/utility/email.php'); $this->registerClass('kEmailSendingHelper', KERNEL_PATH . '/utility/email_send.php', 'EmailSender'); $this->registerClass('kSocket', KERNEL_PATH . '/utility/socket.php', 'Socket'); // do not move to config - this helper is used before configs are read $this->registerClass('kModulesHelper', KERNEL_PATH . self::MODULE_HELPER_PATH, 'ModulesHelper'); } /** * Registers default build events * * @return void * @access protected */ protected function RegisterDefaultBuildEvents() { $this->EventManager->registerBuildEvent('kTempTablesHandler', 'OnTempHandlerBuild'); } /** * Returns cached category information by given cache name. All given category * information is recached, when at least one of 4 caches is missing. * * @param int $category_id * @param string $name cache name = {filenames, category_designs, category_tree} * @return string * @access public */ public function getCategoryCache($category_id, $name) { return $this->cacheManager->getCategoryCache($category_id, $name); } /** * Returns caching type (none, memory, temporary) * * @param int $caching_type * @return bool * @access public */ public function isCachingType($caching_type) { return $this->cacheManager->isCachingType($caching_type); } /** * Increments serial based on prefix and it's ID (optional) * * @param string $prefix * @param int $id ID (value of IDField) or ForeignKeyField:ID * @param bool $increment * @return string * @access public */ public function incrementCacheSerial($prefix, $id = null, $increment = true) { return $this->cacheManager->incrementCacheSerial($prefix, $id, $increment); } /** * Returns cached $key value from cache named $cache_name * * @param int $key key name from cache * @param bool $store_locally store data locally after retrieved * @param int $max_rebuild_seconds * @return mixed * @access public */ public function getCache($key, $store_locally = true, $max_rebuild_seconds = 0) { return $this->cacheManager->getCache($key, $store_locally, $max_rebuild_seconds); } /** * Stores new $value in cache with $key name * * @param int $key key name to add to cache * @param mixed $value value of cached record * @param int $expiration when value expires (0 - doesn't expire) * @return bool * @access public */ public function setCache($key, $value, $expiration = 0) { return $this->cacheManager->setCache($key, $value, $expiration); } /** * Stores new $value in cache with $key name (only if it's not there) * * @param int $key key name to add to cache * @param mixed $value value of cached record * @param int $expiration when value expires (0 - doesn't expire) * @return bool * @access public */ public function addCache($key, $value, $expiration = 0) { return $this->cacheManager->addCache($key, $value, $expiration); } /** * Sets rebuilding mode for given cache * * @param string $name * @param int $mode * @param int $max_rebuilding_time * @return bool * @access public */ public function rebuildCache($name, $mode = null, $max_rebuilding_time = 0) { return $this->cacheManager->rebuildCache($name, $mode, $max_rebuilding_time); } /** * Deletes key from cache * * @param string $key * @return void * @access public */ public function deleteCache($key) { $this->cacheManager->deleteCache($key); } /** * Reset's all memory cache at once * * @return void * @access public */ public function resetCache() { $this->cacheManager->resetCache(); } /** * Returns value from database cache * * @param string $name key name * @param int $max_rebuild_seconds * @return mixed * @access public */ public function getDBCache($name, $max_rebuild_seconds = 0) { return $this->cacheManager->getDBCache($name, $max_rebuild_seconds); } /** * Sets value to database cache * * @param string $name * @param mixed $value * @param int|bool $expiration * @return void * @access public */ public function setDBCache($name, $value, $expiration = false) { $this->cacheManager->setDBCache($name, $value, $expiration); } /** * Sets rebuilding mode for given cache * * @param string $name * @param int $mode * @param int $max_rebuilding_time * @return bool * @access public */ public function rebuildDBCache($name, $mode = null, $max_rebuilding_time = 0) { return $this->cacheManager->rebuildDBCache($name, $mode, $max_rebuilding_time); } /** * Deletes key from database cache * * @param string $name * @return void * @access public */ public function deleteDBCache($name) { $this->cacheManager->deleteDBCache($name); } /** * Registers each module specific constants if any found * * @return bool * @access protected */ protected function registerModuleConstants() { if ( file_exists(KERNEL_PATH . '/constants.php') ) { kUtil::includeOnce(KERNEL_PATH . '/constants.php'); } if ( !$this->ModuleInfo ) { return false; } foreach ($this->ModuleInfo as $module_info) { $constants_file = FULL_PATH . '/' . $module_info['Path'] . 'constants.php'; if ( file_exists($constants_file) ) { kUtil::includeOnce($constants_file); } } return true; } /** * Performs redirect to hard maintenance template * * @return void * @access public */ public function redirectToMaintenance() { $maintenance_page = WRITEBALE_BASE . '/maintenance.html'; $query_string = ''; // $this->isAdmin ? '' : '?next_template=' . kUtil::escape($_SERVER['REQUEST_URI'], kUtil::ESCAPE_URL); if ( file_exists(FULL_PATH . $maintenance_page) ) { header('Location: ' . BASE_PATH . $maintenance_page . $query_string); exit; } } /** * Actually runs the parser against current template and stores parsing result * * This method gets 't' variable passed to the script, loads the template given in 't' variable and * parses it. The result is store in {@link $this->HTML} property. * * @return void * @access public */ public function Run() { // process maintenance mode redirect: begin $maintenance_mode = $this->getMaintenanceMode(); if ( $maintenance_mode == MaintenanceMode::HARD ) { $this->redirectToMaintenance(); } elseif ( $maintenance_mode == MaintenanceMode::SOFT ) { $maintenance_template = $this->isAdmin ? 'login' : $this->ConfigValue('SoftMaintenanceTemplate'); if ( $this->GetVar('t') != $maintenance_template ) { $redirect_params = Array (); if ( !$this->isAdmin ) { $redirect_params['next_template'] = $_SERVER['REQUEST_URI']; } $this->Redirect($maintenance_template, $redirect_params); } } // process maintenance mode redirect: end if ( defined('DEBUG_MODE') && $this->isDebugMode() && kUtil::constOn('DBG_PROFILE_MEMORY') ) { $this->Debugger->appendMemoryUsage('Application before Run:'); } if ( $this->isAdminUser ) { // for permission checking in events & templates $this->LinkVar('module'); // for common configuration templates $this->LinkVar('module_key'); // for common search templates $this->LinkVar('section'); // for common configuration templates if ( $this->GetVar('m_opener') == 'p' ) { $this->LinkVar('main_prefix'); // window prefix, that opened selector $this->LinkVar('dst_field'); // field to set value choosed in selector } if ( $this->GetVar('ajax') == 'yes' && !$this->GetVar('debug_ajax') ) { // hide debug output from ajax requests automatically kUtil::safeDefine('DBG_SKIP_REPORTING', 1); // safeDefine, because debugger also defines it } } elseif ( $this->GetVar('admin') ) { $admin_session = $this->recallObject('Session.admin'); /* @var $admin_session Session */ // store Admin Console User's ID to Front-End's session for cross-session permission checks $this->StoreVar('admin_user_id', (int)$admin_session->RecallVar('user_id')); if ( $this->CheckAdminPermission('CATEGORY.MODIFY', 0, $this->getBaseCategory()) ) { // user can edit cms blocks (when viewing front-end through admin's frame) $editing_mode = $this->GetVar('editing_mode'); define('EDITING_MODE', $editing_mode ? $editing_mode : EDITING_MODE_BROWSE); } } kUtil::safeDefine('EDITING_MODE', ''); // user can't edit anything $this->Phrases->setPhraseEditing(); $this->EventManager->ProcessRequest(); $this->InitParser(); $t = $this->GetVar('render_template', $this->GetVar('t')); if ( !$this->TemplatesCache->TemplateExists($t) && !$this->isAdmin ) { $cms_handler = $this->recallObject('st_EventHandler'); /* @var $cms_handler CategoriesEventHandler */ $t = ltrim($cms_handler->GetDesignTemplate(), '/'); if ( defined('DEBUG_MODE') && $this->isDebugMode() ) { $this->Debugger->appendHTML('Design Template: ' . $t . '; CategoryID: ' . $this->GetVar('m_cat_id')); } } /*else { $cms_handler->SetCatByTemplate(); }*/ if ( defined('DEBUG_MODE') && $this->isDebugMode() && kUtil::constOn('DBG_PROFILE_MEMORY') ) { $this->Debugger->appendMemoryUsage('Application before Parsing:'); } $this->HTML = $this->Parser->Run($t); if ( defined('DEBUG_MODE') && $this->isDebugMode() && kUtil::constOn('DBG_PROFILE_MEMORY') ) { $this->Debugger->appendMemoryUsage('Application after Parsing:'); } } /** * Only renders template * * @see kDBEventHandler::_errorNotFound() */ public function QuickRun() { // discard any half-parsed content ob_clean(); // replace current page content with 404 $this->InitParser(); $this->HTML = $this->Parser->Run($this->GetVar('t')); } /** * Performs template parser/cache initialization * * @param bool|string $theme_name * @return void * @access public */ public function InitParser($theme_name = false) { if ( !is_object($this->Parser) ) { $this->Parser = $this->recallObject('NParser'); $this->TemplatesCache = $this->recallObject('TemplatesCache'); } $this->TemplatesCache->forceThemeName = $theme_name; } /** * Send the parser results to browser * * Actually send everything stored in {@link $this->HTML}, to the browser by echoing it. * * @return void * @access public */ public function Done() { $this->HandleEvent(new kEvent('adm:OnBeforeShutdown')); $debug_mode = defined('DEBUG_MODE') && $this->isDebugMode(); if ( $debug_mode ) { if ( kUtil::constOn('DBG_PROFILE_MEMORY') ) { $this->Debugger->appendMemoryUsage('Application before Done:'); } $this->Session->SaveData(); // adds session data to debugger report $this->HTML = ob_get_clean() . $this->HTML . $this->Debugger->printReport(true); } else { // send "Set-Cookie" header before any output is made $this->Session->SetSession(); $this->HTML = ob_get_clean() . $this->HTML; } $this->_outputPage(); $this->cacheManager->UpdateApplicationCache(); if ( !$debug_mode ) { $this->Session->SaveData(); } $this->EventManager->runScheduledTasks(); if ( defined('DBG_CAPTURE_STATISTICS') && DBG_CAPTURE_STATISTICS && !$this->isAdmin ) { $this->_storeStatistics(); } } /** * Outputs generated page content to end-user * * @return void * @access protected */ protected function _outputPage() { $this->setContentType(); ob_start(); if ( $this->UseOutputCompression() ) { $compression_level = $this->ConfigValue('OutputCompressionLevel'); if ( !$compression_level || $compression_level < 0 || $compression_level > 9 ) { $compression_level = 7; } header('Content-Encoding: gzip'); echo gzencode($this->HTML, $compression_level); } else { // when gzip compression not used connection won't be closed early! echo $this->HTML; } // send headers to tell the browser to close the connection header('Content-Length: ' . ob_get_length()); header('Connection: close'); // flush all output ob_end_flush(); if ( ob_get_level() ) { ob_flush(); } flush(); // close current session if ( session_id() ) { session_write_close(); } } /** * Stores script execution statistics to database * * @return void * @access protected */ protected function _storeStatistics() { global $start; $script_time = microtime(true) - $start; $query_statistics = $this->Conn->getQueryStatistics(); // time & count $sql = 'SELECT * FROM ' . TABLE_PREFIX . 'StatisticsCapture WHERE TemplateName = ' . $this->Conn->qstr($this->GetVar('t')); $data = $this->Conn->GetRow($sql); if ( $data ) { $this->_updateAverageStatistics($data, 'ScriptTime', $script_time); $this->_updateAverageStatistics($data, 'SqlTime', $query_statistics['time']); $this->_updateAverageStatistics($data, 'SqlCount', $query_statistics['count']); $data['Hits']++; $data['LastHit'] = time(); $this->Conn->doUpdate($data, TABLE_PREFIX . 'StatisticsCapture', 'StatisticsId = ' . $data['StatisticsId']); } else { $data['ScriptTimeMin'] = $data['ScriptTimeAvg'] = $data['ScriptTimeMax'] = $script_time; $data['SqlTimeMin'] = $data['SqlTimeAvg'] = $data['SqlTimeMax'] = $query_statistics['time']; $data['SqlCountMin'] = $data['SqlCountAvg'] = $data['SqlCountMax'] = $query_statistics['count']; $data['TemplateName'] = $this->GetVar('t'); $data['Hits'] = 1; $data['LastHit'] = time(); $this->Conn->doInsert($data, TABLE_PREFIX . 'StatisticsCapture'); } } /** * Calculates average time for statistics * * @param Array $data * @param string $field_prefix * @param float $current_value * @return void * @access protected */ protected function _updateAverageStatistics(&$data, $field_prefix, $current_value) { $data[$field_prefix . 'Avg'] = (($data['Hits'] * $data[$field_prefix . 'Avg']) + $current_value) / ($data['Hits'] + 1); if ( $current_value < $data[$field_prefix . 'Min'] ) { $data[$field_prefix . 'Min'] = $current_value; } if ( $current_value > $data[$field_prefix . 'Max'] ) { $data[$field_prefix . 'Max'] = $current_value; } } /** * Remembers slow query SQL and execution time into log * * @param string $slow_sql * @param int $time * @return void * @access public */ public function logSlowQuery($slow_sql, $time) { $query_crc = kUtil::crc32($slow_sql); $sql = 'SELECT * FROM ' . TABLE_PREFIX . 'SlowSqlCapture WHERE QueryCrc = ' . $query_crc; $data = $this->Conn->Query($sql, null, true); if ( $data ) { $this->_updateAverageStatistics($data, 'Time', $time); $template_names = explode(',', $data['TemplateNames']); array_push($template_names, $this->GetVar('t')); $data['TemplateNames'] = implode(',', array_unique($template_names)); $data['Hits']++; $data['LastHit'] = time(); $this->Conn->doUpdate($data, TABLE_PREFIX . 'SlowSqlCapture', 'CaptureId = ' . $data['CaptureId']); } else { $data['TimeMin'] = $data['TimeAvg'] = $data['TimeMax'] = $time; $data['SqlQuery'] = $slow_sql; $data['QueryCrc'] = $query_crc; $data['TemplateNames'] = $this->GetVar('t'); $data['Hits'] = 1; $data['LastHit'] = time(); $this->Conn->doInsert($data, TABLE_PREFIX . 'SlowSqlCapture'); } } /** * Checks if output compression options is available * * @return bool * @access protected */ protected function UseOutputCompression() { if ( kUtil::constOn('IS_INSTALL') || kUtil::constOn('DBG_ZEND_PRESENT') || kUtil::constOn('SKIP_OUT_COMPRESSION') ) { return false; } $accept_encoding = isset($_SERVER['HTTP_ACCEPT_ENCODING']) ? $_SERVER['HTTP_ACCEPT_ENCODING'] : ''; return $this->ConfigValue('UseOutputCompression') && function_exists('gzencode') && strstr($accept_encoding, 'gzip'); } // Facade /** * Returns current session id (SID) * * @return int * @access public */ public function GetSID() { $session = $this->recallObject('Session'); /* @var $session Session */ return $session->GetID(); } /** * Destroys current session * * @return void * @access public * @see UserHelper::logoutUser() */ public function DestroySession() { $session = $this->recallObject('Session'); /* @var $session Session */ $session->Destroy(); } /** * Returns variable passed to the script as GET/POST/COOKIE * * @param string $name Name of variable to retrieve * @param mixed $default default value returned in case if variable not present * @return mixed * @access public */ public function GetVar($name, $default = false) { return isset($this->HttpQuery->_Params[$name]) ? $this->HttpQuery->_Params[$name] : $default; } /** * Removes forceful escaping done to the variable upon Front-End submission. * * @param string|array $value Value. * * @return string|array * @see kHttpQuery::StripSlashes * @todo Temporary method for marking problematic places to take care of, when forceful escaping will be removed. */ public function unescapeRequestVariable($value) { return $this->HttpQuery->unescapeRequestVariable($value); } /** * Returns variable passed to the script as $type * * @param string $name Name of variable to retrieve * @param string $type Get/Post/Cookie * @param mixed $default default value returned in case if variable not present * @return mixed * @access public */ public function GetVarDirect($name, $type, $default = false) { // $type = ucfirst($type); $array = $this->HttpQuery->$type; return isset($array[$name]) ? $array[$name] : $default; } /** * Returns ALL variables passed to the script as GET/POST/COOKIE * * @return Array * @access public * @deprecated */ public function GetVars() { return $this->HttpQuery->GetParams(); } /** * Set the variable 'as it was passed to the script through GET/POST/COOKIE' * * This could be useful to set the variable when you know that * other objects would relay on variable passed from GET/POST/COOKIE * or you could use SetVar() / GetVar() pairs to pass the values between different objects.
* * @param string $var Variable name to set * @param mixed $val Variable value * @return void * @access public */ public function SetVar($var,$val) { $this->HttpQuery->Set($var, $val); } /** * Deletes kHTTPQuery variable * * @param string $var * @return void * @todo Think about method name */ public function DeleteVar($var) { $this->HttpQuery->Remove($var); } /** * Deletes Session variable * * @param string $var * @return void * @access public */ public function RemoveVar($var) { $this->Session->RemoveVar($var); } /** * Removes variable from persistent session * * @param string $var * @return void * @access public */ public function RemovePersistentVar($var) { $this->Session->RemovePersistentVar($var); } /** * Restores Session variable to it's db version * * @param string $var * @return void * @access public */ public function RestoreVar($var) { $this->Session->RestoreVar($var); } /** * Returns session variable value * * Return value of $var variable stored in Session. An optional default value could be passed as second parameter. * * @param string $var Variable name * @param mixed $default Default value to return if no $var variable found in session * @return mixed * @access public * @see Session::RecallVar() */ public function RecallVar($var,$default=false) { return $this->Session->RecallVar($var,$default); } /** * Returns variable value from persistent session * * @param string $var * @param mixed $default * @return mixed * @access public * @see Session::RecallPersistentVar() */ public function RecallPersistentVar($var, $default = false) { return $this->Session->RecallPersistentVar($var, $default); } /** * Stores variable $val in session under name $var * * Use this method to store variable in session. Later this variable could be recalled. * * @param string $var Variable name * @param mixed $val Variable value * @param bool $optional * @return void * @access public * @see kApplication::RecallVar() */ public function StoreVar($var, $val, $optional = false) { $session = $this->recallObject('Session'); /* @var $session Session */ $this->Session->StoreVar($var, $val, $optional); } /** * Stores variable to persistent session * * @param string $var * @param mixed $val * @param bool $optional * @return void * @access public */ public function StorePersistentVar($var, $val, $optional = false) { $this->Session->StorePersistentVar($var, $val, $optional); } /** * Stores default value for session variable * * @param string $var * @param string $val * @param bool $optional * @return void * @access public * @see Session::RecallVar() * @see Session::StoreVar() */ public function StoreVarDefault($var, $val, $optional = false) { $session = $this->recallObject('Session'); /* @var $session Session */ $this->Session->StoreVarDefault($var, $val, $optional); } /** * Links HTTP Query variable with session variable * * If variable $var is passed in HTTP Query it is stored in session for later use. If it's not passed it's recalled from session. * This method could be used for making sure that GetVar will return query or session value for given * variable, when query variable should overwrite session (and be stored there for later use).
* This could be used for passing item's ID into popup with multiple tab - * in popup script you just need to call LinkVar('id', 'current_id') before first use of GetVar('id'). * After that you can be sure that GetVar('id') will return passed id or id passed earlier and stored in session * * @param string $var HTTP Query (GPC) variable name * @param mixed $ses_var Session variable name * @param mixed $default Default variable value * @param bool $optional * @return void * @access public */ public function LinkVar($var, $ses_var = null, $default = '', $optional = false) { if ( !isset($ses_var) ) { $ses_var = $var; } if ( $this->GetVar($var) !== false ) { $this->StoreVar($ses_var, $this->GetVar($var), $optional); } else { $this->SetVar($var, $this->RecallVar($ses_var, $default)); } } /** * Returns variable from HTTP Query, or from session if not passed in HTTP Query * * The same as LinkVar, but also returns the variable value taken from HTTP Query if passed, or from session if not passed. * Returns the default value if variable does not exist in session and was not passed in HTTP Query * * @param string $var HTTP Query (GPC) variable name * @param mixed $ses_var Session variable name * @param mixed $default Default variable value * @return mixed * @access public * @see LinkVar */ public function GetLinkedVar($var, $ses_var = null, $default = '') { $this->LinkVar($var, $ses_var, $default); return $this->GetVar($var); } /** * Renders given tag and returns it's output * * @param string $prefix * @param string $tag * @param Array $params * @return mixed * @access public * @see kApplication::InitParser() */ public function ProcessParsedTag($prefix, $tag, $params) { $processor = $this->Parser->GetProcessor($prefix); /* @var $processor kDBTagProcessor */ return $processor->ProcessParsedTag($tag, $params, $prefix); } /** * Return object of IDBConnection interface * * Return object of IDBConnection interface already connected to the project database, configurable in config.php * * @return IDBConnection * @access public */ public function &GetADODBConnection() { return $this->Conn; } /** * Allows to parse given block name or include template * * @param Array $params Parameters to pass to block. Reserved parameter "name" used to specify block name. * @param bool $pass_params Forces to pass current parser params to this block/template. Use with caution, because you can accidentally pass "block_no_data" parameter. * @param bool $as_template * @return string * @access public */ public function ParseBlock($params, $pass_params = false, $as_template = false) { if ( substr($params['name'], 0, 5) == 'html:' ) { return substr($params['name'], 5); } return $this->Parser->ParseBlock($params, $pass_params, $as_template); } /** * Checks, that we have given block defined * * @param string $name * @return bool * @access public */ public function ParserBlockFound($name) { return $this->Parser->blockFound($name); } /** * Allows to include template with a given name and given parameters * * @param Array $params Parameters to pass to template. Reserved parameter "name" used to specify template name. * @return string * @access public */ public function IncludeTemplate($params) { return $this->Parser->IncludeTemplate($params, isset($params['is_silent']) ? 1 : 0); } /** * Return href for template * * @param string $t Template path * @param string $prefix index.php prefix - could be blank, 'admin' * @param Array $params * @param string $index_file * @return string */ public function HREF($t, $prefix = '', $params = Array (), $index_file = null) { return $this->UrlManager->HREF($t, $prefix, $params, $index_file); } /** * Returns theme template filename and it's corresponding page_id based on given seo template * * @param string $seo_template * @return string * @access public */ public function getPhysicalTemplate($seo_template) { return $this->UrlManager->getPhysicalTemplate($seo_template); } /** * Returns seo template by physical template * * @param string $physical_template * @return string * @access public */ public function getSeoTemplate($physical_template) { return $this->UrlManager->getSeoTemplate($physical_template); } /** * Returns template name, that corresponds with given virtual (not physical) page id * * @param int $page_id * @return string|bool * @access public */ public function getVirtualPageTemplate($page_id) { return $this->UrlManager->getVirtualPageTemplate($page_id); } /** * Returns section template for given physical/virtual template * * @param string $template * @param int $theme_id * @return string * @access public */ public function getSectionTemplate($template, $theme_id = null) { return $this->UrlManager->getSectionTemplate($template, $theme_id); } /** * Returns variables with values that should be passed through with this link + variable list * * @param Array $params * @return Array * @access public */ public function getPassThroughVariables(&$params) { return $this->UrlManager->getPassThroughVariables($params); } /** * Builds url * * @param string $t * @param Array $params * @param string $pass * @param bool $pass_events * @param bool $env_var * @return string * @access public */ public function BuildEnv($t, $params, $pass = 'all', $pass_events = false, $env_var = true) { return $this->UrlManager->plain->build($t, $params, $pass, $pass_events, $env_var); } /** * Process QueryString only, create * events, ids, based on config * set template name and sid in * desired application variables. * * @param string $env_var environment string value * @param string $pass_name * @return Array * @access public */ public function processQueryString($env_var, $pass_name = 'passed') { return $this->UrlManager->plain->parse($env_var, $pass_name); } /** * Parses rewrite url and returns parsed variables * * @param string $url * @param string $pass_name * @return Array * @access public */ public function parseRewriteUrl($url, $pass_name = 'passed') { return $this->UrlManager->rewrite->parse($url, $pass_name); } /** * Returns base part of all urls, build on website * * @param string $domain Domain override. * @param boolean $ssl_redirect Redirect to/from SSL. * * @return string */ public function BaseURL($domain = '', $ssl_redirect = null) { if ( $ssl_redirect === null ) { // stay on same encryption level return PROTOCOL . ($domain ? $domain : SERVER_NAME) . (defined('PORT') ? ':' . PORT : '') . BASE_PATH . '/'; } if ( $ssl_redirect ) { // going from http:// to https:// $protocol = 'https://'; $domain = $this->getSecureDomain(); } else { // going from https:// to http:// $protocol = 'http://'; $domain = $this->siteDomainField('DomainName'); if ( $domain === false ) { $domain = DOMAIN; // not on site domain } } return $protocol . $domain . (defined('PORT') ? ':' . PORT : '') . BASE_PATH . '/'; } /** * Returns secure domain. * * @return string */ public function getSecureDomain() { $ret = $this->isAdmin ? $this->ConfigValue('AdminSSLDomain') : false; if ( !$ret ) { $ssl_domain = $this->siteDomainField('SSLDomainName'); return strlen($ssl_domain) ? $ssl_domain : $this->ConfigValue('SSLDomain'); } return $ret; } /** * Redirects user to url, that's build based on given parameters * * @param string $t * @param Array $params * @param string $prefix * @param string $index_file * @return void * @access public */ public function Redirect($t = '', $params = Array(), $prefix = '', $index_file = null) { $js_redirect = getArrayValue($params, 'js_redirect'); if ( $t == '' || $t === true ) { $t = $this->GetVar('t'); } // pass prefixes and special from previous url if ( array_key_exists('js_redirect', $params) ) { unset($params['js_redirect']); } // allows to send custom responce code along with redirect header if ( array_key_exists('response_code', $params) ) { $response_code = (int)$params['response_code']; unset($params['response_code']); } else { $response_code = 302; // Found } if ( !array_key_exists('pass', $params) ) { $params['pass'] = 'all'; } if ( $this->GetVar('ajax') == 'yes' && $t == $this->GetVar('t') ) { // redirects to the same template as current $params['ajax'] = 'yes'; } $location = $this->HREF($t, $prefix, $params, $index_file); if ( $this->isDebugMode() && (kUtil::constOn('DBG_REDIRECT') || (kUtil::constOn('DBG_RAISE_ON_WARNINGS') && $this->Debugger->WarningCount)) ) { $this->Debugger->appendTrace(); echo 'Debug output above !!!
' . "\n"; if ( array_key_exists('HTTP_REFERER', $_SERVER) ) { echo 'Referer: ' . $_SERVER['HTTP_REFERER'] . '
' . "\n"; } echo "Proceed to redirect: {$location}
\n"; } else { if ( $js_redirect ) { // show "redirect" template instead of redirecting, // because "Set-Cookie" header won't work, when "Location" // header is used later $this->SetVar('t', 'redirect'); $this->SetVar('redirect_to', $location); // make all additional parameters available on "redirect" template too foreach ($params as $name => $value) { $this->SetVar($name, $value); } return; } else { - if ( $this->GetVar('ajax') == 'yes' && $t != $this->GetVar('t') ) { - // redirection to other then current template during ajax request + if ( $this->GetVar('ajax') == 'yes' && ($t != $this->GetVar('t') || !$this->isSOPSafe($location, $t)) ) { + // redirection to other then current template during ajax request OR SOP violation kUtil::safeDefine('DBG_SKIP_REPORTING', 1); echo '#redirect#' . $location; } elseif ( headers_sent() != '' ) { // some output occurred -> redirect using javascript echo ''; } else { // no output before -> redirect using HTTP header // header('HTTP/1.1 302 Found'); header('Location: ' . $location, true, $response_code); } } } // session expiration is called from session initialization, // that's why $this->Session may be not defined here $session = $this->recallObject('Session'); /* @var $session Session */ if ( $this->InitDone ) { // if redirect happened in the middle of application initialization don't call event, // that presumes that application was successfully initialized $this->HandleEvent(new kEvent('adm:OnBeforeShutdown')); } $session->SaveData(); ob_end_flush(); exit; } /** + * Determines if real redirect should be made within AJAX request. + * + * @param string $url Location. + * @param string $template Template. + * + * @return boolean + * @link http://en.wikipedia.org/wiki/Same-origin_policy + */ + protected function isSOPSafe($url, $template) + { + $parsed_url = parse_url($url); + + if ( $parsed_url['scheme'] . '://' != PROTOCOL ) { + return false; + } + + if ( $parsed_url['host'] != SERVER_NAME ) { + return false; + } + + if ( defined('PORT') && isset($parsed_url['port']) && $parsed_url['port'] != PORT ) { + return false; + } + + return true; + } + + /** * Returns translation of given label * * @param string $label * @param bool $allow_editing return translation link, when translation is missing on current language * @param bool $use_admin use current Admin Console language to translate phrase * @return string * @access public */ public function Phrase($label, $allow_editing = true, $use_admin = false) { return $this->Phrases->GetPhrase($label, $allow_editing, $use_admin); } /** * Replace language tags in exclamation marks found in text * * @param string $text * @param bool $force_escape force escaping, not escaping of resulting string * @return string * @access public */ public function ReplaceLanguageTags($text, $force_escape = null) { return $this->Phrases->ReplaceLanguageTags($text, $force_escape); } /** * Checks if user is logged in, and creates * user object if so. User object can be recalled * later using "u.current" prefix_special. Also you may * get user id by getting "u.current_id" variable. * * @return void * @access protected */ protected function ValidateLogin() { $session = $this->recallObject('Session'); /* @var $session Session */ $user_id = $session->GetField('PortalUserId'); if ( !$user_id && $user_id != USER_ROOT ) { $user_id = USER_GUEST; } $this->SetVar('u.current_id', $user_id); if ( !$this->isAdmin ) { // needed for "profile edit", "registration" forms ON FRONT ONLY $this->SetVar('u_id', $user_id); } $this->StoreVar('user_id', $user_id, $user_id == USER_GUEST); // storing Guest user_id (-2) is optional $this->isAdminUser = $this->isAdmin && $this->LoggedIn(); if ( $this->GetVar('expired') == 1 ) { // this parameter is set only from admin $user = $this->recallObject('u.login-admin', null, Array ('form_name' => 'login')); /* @var $user UsersItem */ $user->SetError('UserLogin', 'session_expired', 'la_text_sess_expired'); } $this->HandleEvent(new kEvent('adm:OnLogHttpRequest')); if ( $user_id != USER_GUEST ) { // normal users + root $this->LoadPersistentVars(); } $user_timezone = $this->Session->GetField('TimeZone'); if ( $user_timezone ) { date_default_timezone_set($user_timezone); } } /** * Loads current user persistent session data * * @return void * @access public */ public function LoadPersistentVars() { $this->Session->LoadPersistentVars(); } /** * Returns configuration option value by name * * @param string $name * @return string * @access public */ public function ConfigValue($name) { return $this->cacheManager->ConfigValue($name); } /** * Changes value of individual configuration variable (+resets cache, when needed) * * @param string $name * @param string $value * @param bool $local_cache_only * @return string * @access public */ public function SetConfigValue($name, $value, $local_cache_only = false) { return $this->cacheManager->SetConfigValue($name, $value, $local_cache_only); } /** * Allows to process any type of event * * @param kEvent $event * @param Array $params * @param Array $specific_params * @return void * @access public */ public function HandleEvent($event, $params = null, $specific_params = null) { if ( isset($params) ) { $event = new kEvent($params, $specific_params); } $this->EventManager->HandleEvent($event); } /** * Notifies event subscribers, that event has occured * * @param kEvent $event * @return void */ public function notifyEventSubscribers(kEvent $event) { $this->EventManager->notifySubscribers($event); } /** * Allows to process any type of event * * @param kEvent $event * @return bool * @access public */ public function eventImplemented(kEvent $event) { return $this->EventManager->eventImplemented($event); } /** * Registers new class in the factory * * @param string $real_class Real name of class as in class declaration * @param string $file Filename in what $real_class is declared * @param string $pseudo_class Name under this class object will be accessed using getObject method * @return void * @access public */ public function registerClass($real_class, $file, $pseudo_class = null) { $this->Factory->registerClass($real_class, $file, $pseudo_class); } /** * Unregisters existing class from factory * * @param string $real_class Real name of class as in class declaration * @param string $pseudo_class Name under this class object is accessed using getObject method * @return void * @access public */ public function unregisterClass($real_class, $pseudo_class = null) { $this->Factory->unregisterClass($real_class, $pseudo_class); } /** * Add new scheduled task * * @param string $short_name name to be used to store last maintenance run info * @param string $event_string * @param int $run_schedule run schedule like for Cron * @param string $module * @param int $status * @access public */ public function registerScheduledTask($short_name, $event_string, $run_schedule, $module, $status = STATUS_ACTIVE) { $this->EventManager->registerScheduledTask($short_name, $event_string, $run_schedule, $module, $status); } /** * Registers Hook from subprefix event to master prefix event * * Pattern: Observer * * @param string $hook_event * @param string $do_event * @param int $mode * @param bool $conditional * @access public */ public function registerHook($hook_event, $do_event, $mode = hAFTER, $conditional = false) { $this->EventManager->registerHook($hook_event, $do_event, $mode, $conditional); } /** * Registers build event for given pseudo class * * @param string $pseudo_class * @param string $event_name * @access public */ public function registerBuildEvent($pseudo_class, $event_name) { $this->EventManager->registerBuildEvent($pseudo_class, $event_name); } /** * Allows one TagProcessor tag act as other TagProcessor tag * * @param Array $tag_info * @return void * @access public */ public function registerAggregateTag($tag_info) { $aggregator = $this->recallObject('TagsAggregator', 'kArray'); /* @var $aggregator kArray */ $tag_data = Array ( $tag_info['LocalPrefix'], $tag_info['LocalTagName'], getArrayValue($tag_info, 'LocalSpecial') ); $aggregator->SetArrayValue($tag_info['AggregateTo'], $tag_info['AggregatedTagName'], $tag_data); } /** * Returns object using params specified, creates it if is required * * @param string $name * @param string $pseudo_class * @param Array $event_params * @param Array $arguments * @return kBase */ public function recallObject($name, $pseudo_class = null, $event_params = Array(), $arguments = Array ()) { /*if ( !$this->hasObject($name) && $this->isDebugMode() && ($name == '_prefix_here_') ) { // first time, when object with "_prefix_here_" prefix is accessed $this->Debugger->appendTrace(); }*/ return $this->Factory->getObject($name, $pseudo_class, $event_params, $arguments); } /** * Returns tag processor for prefix specified * * @param string $prefix * @return kDBTagProcessor * @access public */ public function recallTagProcessor($prefix) { $this->InitParser(); // because kDBTagProcesor is in NParser dependencies return $this->recallObject($prefix . '_TagProcessor'); } /** * Checks if object with prefix passes was already created in factory * * @param string $name object pseudo_class, prefix * @return bool * @access public */ public function hasObject($name) { return $this->Factory->hasObject($name); } /** * Removes object from storage by given name * * @param string $name Object's name in the Storage * @return void * @access public */ public function removeObject($name) { $this->Factory->DestroyObject($name); } /** * Get's real class name for pseudo class, includes class file and creates class instance * * Pattern: Factory Method * * @param string $pseudo_class * @param Array $arguments * @return kBase * @access public */ public function makeClass($pseudo_class, $arguments = Array ()) { return $this->Factory->makeClass($pseudo_class, $arguments); } /** * Checks if application is in debug mode * * @param bool $check_debugger check if kApplication debugger is initialized too, not only for defined DEBUG_MODE constant * @return bool * @author Alex * @access public */ public function isDebugMode($check_debugger = true) { $debug_mode = defined('DEBUG_MODE') && DEBUG_MODE; if ($check_debugger) { $debug_mode = $debug_mode && is_object($this->Debugger); } return $debug_mode; } /** * Apply url rewriting used by mod_rewrite or not * * @param bool|null $ssl Force ssl link to be build * @return bool * @access public */ public function RewriteURLs($ssl = false) { // case #1,#4: // we want to create https link from http mode // we want to create https link from https mode // conditions: ($ssl || PROTOCOL == 'https://') && $this->ConfigValue('UseModRewriteWithSSL') // case #2,#3: // we want to create http link from https mode // we want to create http link from http mode // conditions: !$ssl && (PROTOCOL == 'https://' || PROTOCOL == 'http://') $allow_rewriting = (!$ssl && (PROTOCOL == 'https://' || PROTOCOL == 'http://')) // always allow mod_rewrite for http || // or allow rewriting for redirect TO httpS or when already in httpS (($ssl || PROTOCOL == 'https://') && $this->ConfigValue('UseModRewriteWithSSL')); // but only if it's allowed in config! return kUtil::constOn('MOD_REWRITE') && $allow_rewriting; } /** * Returns unit config for given prefix * * @param string $prefix * @return kUnitConfig * @access public */ public function getUnitConfig($prefix) { return $this->UnitConfigReader->getUnitConfig($prefix); } /** * Returns true if config exists and is allowed for reading * * @param string $prefix * @return bool */ public function prefixRegistred($prefix) { return $this->UnitConfigReader->prefixRegistered($prefix); } /** * Splits any mixing of prefix and * special into correct ones * * @param string $prefix_special * @return Array * @access public */ public function processPrefix($prefix_special) { return $this->Factory->processPrefix($prefix_special); } /** * Set's new event for $prefix_special * passed * * @param string $prefix_special * @param string $event_name * @return void * @access public */ public function setEvent($prefix_special, $event_name) { $this->EventManager->setEvent($prefix_special, $event_name); } /** * SQL Error Handler * * @param int $code * @param string $msg * @param string $sql * @return bool * @access public * @throws Exception * @deprecated */ public function handleSQLError($code, $msg, $sql) { return $this->_logger->handleSQLError($code, $msg, $sql); } /** * Returns & blocks next ResourceId available in system * * @return int * @access public */ public function NextResourceId() { $table_name = TABLE_PREFIX . 'IdGenerator'; $this->Conn->Query('LOCK TABLES ' . $table_name . ' WRITE'); $this->Conn->Query('UPDATE ' . $table_name . ' SET lastid = lastid + 1'); $id = $this->Conn->GetOne('SELECT lastid FROM ' . $table_name); if ( $id === false ) { $this->Conn->Query('INSERT INTO ' . $table_name . ' (lastid) VALUES (2)'); $id = 2; } $this->Conn->Query('UNLOCK TABLES'); return $id - 1; } /** * Returns genealogical main prefix for sub-table prefix passes * OR prefix, that has been found in REQUEST and some how is parent of passed sub-table prefix * * @param string $current_prefix * @param bool $real_top if set to true will return real topmost prefix, regardless of its id is passed or not * @return string * @access public */ public function GetTopmostPrefix($current_prefix, $real_top = false) { // 1. get genealogical tree of $current_prefix $prefixes = Array ($current_prefix); while ($parent_prefix = $this->getUnitConfig($current_prefix)->getParentPrefix()) { if ( !$this->prefixRegistred($parent_prefix) ) { // stop searching, when parent prefix is not registered break; } $current_prefix = $parent_prefix; array_unshift($prefixes, $current_prefix); } if ( $real_top ) { return $current_prefix; } // 2. find what if parent is passed $passed = explode(',', $this->GetVar('all_passed')); foreach ($prefixes as $a_prefix) { if ( in_array($a_prefix, $passed) ) { return $a_prefix; } } return $current_prefix; } /** * Triggers email event of type Admin * * @param string $email_template_name * @param int $to_user_id * @param array $send_params associative array of direct send params, possible keys: to_email, to_name, from_email, from_name, message, message_text * @return kEvent * @access public */ public function emailAdmin($email_template_name, $to_user_id = null, $send_params = Array ()) { return $this->_email($email_template_name, EmailTemplate::TEMPLATE_TYPE_ADMIN, $to_user_id, $send_params); } /** * Triggers email event of type User * * @param string $email_template_name * @param int $to_user_id * @param array $send_params associative array of direct send params, possible keys: to_email, to_name, from_email, from_name, message, message_text * @return kEvent * @access public */ public function emailUser($email_template_name, $to_user_id = null, $send_params = Array ()) { return $this->_email($email_template_name, EmailTemplate::TEMPLATE_TYPE_FRONTEND, $to_user_id, $send_params); } /** * Triggers general email event * * @param string $email_template_name * @param int $email_template_type (0 for User, 1 for Admin) * @param int $to_user_id * @param array $send_params associative array of direct send params, * possible keys: to_email, to_name, from_email, from_name, message, message_text * @return kEvent * @access protected */ protected function _email($email_template_name, $email_template_type, $to_user_id = null, $send_params = Array ()) { $email = $this->makeClass('kEmail'); /* @var $email kEmail */ if ( !$email->findTemplate($email_template_name, $email_template_type) ) { return false; } $email->setParams($send_params); return $email->send($to_user_id); } /** * Allows to check if user in this session is logged in or not * * @return bool * @access public */ public function LoggedIn() { // no session during expiration process return is_null($this->Session) ? false : $this->Session->LoggedIn(); } /** * Check current user permissions based on it's group permissions in specified category * * @param string $name permission name * @param int $cat_id category id, current used if not specified * @param int $type permission type {1 - system, 0 - per category} * @return int * @access public */ public function CheckPermission($name, $type = 1, $cat_id = null) { $perm_helper = $this->recallObject('PermissionsHelper'); /* @var $perm_helper kPermissionsHelper */ return $perm_helper->CheckPermission($name, $type, $cat_id); } /** * Check current admin permissions based on it's group permissions in specified category * * @param string $name permission name * @param int $cat_id category id, current used if not specified * @param int $type permission type {1 - system, 0 - per category} * @return int * @access public */ public function CheckAdminPermission($name, $type = 1, $cat_id = null) { $perm_helper = $this->recallObject('PermissionsHelper'); /* @var $perm_helper kPermissionsHelper */ return $perm_helper->CheckAdminPermission($name, $type, $cat_id); } /** * Set's any field of current visit * * @param string $field * @param mixed $value * @return void * @access public * @todo move to separate module */ public function setVisitField($field, $value) { if ( $this->isAdmin || !$this->ConfigValue('UseVisitorTracking') ) { // admin logins are not registered in visits list return; } $visit = $this->recallObject('visits', null, Array ('raise_warnings' => 0)); /* @var $visit kDBItem */ if ( $visit->isLoaded() ) { $visit->SetDBField($field, $value); $visit->Update(); } } /** * Allows to check if in-portal is installed * * @return bool * @access public */ public function isInstalled() { return $this->InitDone && (count($this->ModuleInfo) > 0); } /** * Allows to determine if module is installed & enabled * * @param string $module_name * @return bool * @access public */ public function isModuleEnabled($module_name) { return $this->findModule('Name', $module_name) !== false; } /** * Returns Window ID of passed prefix main prefix (in edit mode) * * @param string $prefix * @return int * @access public */ public function GetTopmostWid($prefix) { $top_prefix = $this->GetTopmostPrefix($prefix); $mode = $this->GetVar($top_prefix . '_mode'); return $mode != '' ? substr($mode, 1) : ''; } /** * Get temp table name * * @param string $table * @param mixed $wid * @return string * @access public */ public function GetTempName($table, $wid = '') { return $this->GetTempTablePrefix($wid) . $table; } /** * Builds temporary table prefix based on given window id * * @param string $wid * @return string * @access public */ public function GetTempTablePrefix($wid = '') { if ( preg_match('/prefix:(.*)/', $wid, $regs) ) { $wid = $this->GetTopmostWid($regs[1]); } return TABLE_PREFIX . 'ses_' . $this->GetSID() . ($wid ? '_' . $wid : '') . '_edit_'; } /** * Checks if given table is a temporary table * * @param string $table * @return bool * @access public */ public function IsTempTable($table) { static $cache = Array (); if ( !array_key_exists($table, $cache) ) { $cache[$table] = preg_match('/' . TABLE_PREFIX . 'ses_' . $this->GetSID() . '(_[\d]+){0,1}_edit_(.*)/', $table); } return (bool)$cache[$table]; } /** * Checks, that given prefix is in temp mode * * @param string $prefix * @param string $special * @return bool * @access public */ public function IsTempMode($prefix, $special = '') { $top_prefix = $this->GetTopmostPrefix($prefix); $var_names = Array ( $top_prefix, rtrim($top_prefix . '_' . $special, '_'), // from post rtrim($top_prefix . '.' . $special, '.'), // assembled locally ); $var_names = array_unique($var_names); $temp_mode = false; foreach ($var_names as $var_name) { $value = $this->GetVar($var_name . '_mode'); if ( $value && (substr($value, 0, 1) == 't') ) { $temp_mode = true; break; } } return $temp_mode; } /** * Return live table name based on temp table name * * @param string $temp_table * @return string */ public function GetLiveName($temp_table) { if ( preg_match('/' . TABLE_PREFIX . 'ses_' . $this->GetSID() . '(_[\d]+){0,1}_edit_(.*)/', $temp_table, $rets) ) { // cut wid from table end if any return $rets[2]; } else { return $temp_table; } } /** * Stops processing of user request and displays given message * * @param string $message * @access public */ public function ApplicationDie($message = '') { while ( ob_get_level() ) { ob_end_clean(); } if ( $this->isDebugMode() ) { $message .= $this->Debugger->printReport(true); } $this->HTML = $message; $this->_outputPage(); } /** * Returns comma-separated list of groups from given user * * @param int $user_id * @return string */ public function getUserGroups($user_id) { switch ($user_id) { case USER_ROOT: $user_groups = $this->ConfigValue('User_LoggedInGroup'); break; case USER_GUEST: $user_groups = $this->ConfigValue('User_LoggedInGroup') . ',' . $this->ConfigValue('User_GuestGroup'); break; default: $sql = 'SELECT GroupId FROM ' . TABLE_PREFIX . 'UserGroupRelations WHERE PortalUserId = ' . (int)$user_id; $res = $this->Conn->GetCol($sql); $user_groups = Array ($this->ConfigValue('User_LoggedInGroup')); if ( $res ) { $user_groups = array_merge($user_groups, $res); } $user_groups = implode(',', $user_groups); } return $user_groups; } /** * Allows to detect if page is browsed by spider (293 scheduled_tasks supported) * * @return bool * @access public */ /*public function IsSpider() { static $is_spider = null; if ( !isset($is_spider) ) { $user_agent = trim($_SERVER['HTTP_USER_AGENT']); $robots = file(FULL_PATH . '/core/robots_list.txt'); foreach ($robots as $robot_info) { $robot_info = explode("\t", $robot_info, 3); if ( $user_agent == trim($robot_info[2]) ) { $is_spider = true; break; } } } return $is_spider; }*/ /** * Allows to detect table's presence in database * * @param string $table_name * @param bool $force * @return bool * @access public */ public function TableFound($table_name, $force = false) { return $this->Conn->TableFound($table_name, $force); } /** * Returns counter value * * @param string $name counter name * @param Array $params counter parameters * @param string $query_name specify query name directly (don't generate from parameters) * @param bool $multiple_results * @return mixed * @access public */ public function getCounter($name, $params = Array (), $query_name = null, $multiple_results = false) { $count_helper = $this->recallObject('CountHelper'); /* @var $count_helper kCountHelper */ return $count_helper->getCounter($name, $params, $query_name, $multiple_results); } /** * Resets counter, which are affected by one of specified tables * * @param string $tables comma separated tables list used in counting sqls * @return void * @access public */ public function resetCounters($tables) { if ( kUtil::constOn('IS_INSTALL') ) { return; } $count_helper = $this->recallObject('CountHelper'); /* @var $count_helper kCountHelper */ $count_helper->resetCounters($tables); } /** * Sends XML header + optionally displays xml heading * * @param string|bool $xml_version * @return string * @access public * @author Alex */ public function XMLHeader($xml_version = false) { $this->setContentType('text/xml'); return $xml_version ? '' : ''; } /** * Returns category tree * * @param int $category_id * @return Array * @access public */ public function getTreeIndex($category_id) { $tree_index = $this->getCategoryCache($category_id, 'category_tree'); if ( $tree_index ) { $ret = Array (); list ($ret['TreeLeft'], $ret['TreeRight']) = explode(';', $tree_index); return $ret; } return false; } /** * Base category of all categories * Usually replaced category, with ID = 0 in category-related operations. * * @return int * @access public */ public function getBaseCategory() { // same, what $this->findModule('Name', 'Core', 'RootCat') does // don't cache while IS_INSTALL, because of kInstallToolkit::createModuleCategory and upgrade return $this->ModuleInfo['Core']['RootCat']; } /** * Deletes all data, that was cached during unit config parsing (excluding unit config locations) * * @param Array $config_variables * @access public */ public function DeleteUnitCache($config_variables = null) { $this->cacheManager->DeleteUnitCache($config_variables); } /** * Deletes cached section tree, used during permission checking and admin console tree display * * @return void * @access public */ public function DeleteSectionCache() { $this->cacheManager->DeleteSectionCache(); } /** * Sets data from cache to object * * @param Array $data * @access public */ public function setFromCache(&$data) { $this->Factory->setFromCache($data); $this->UnitConfigReader->setFromCache($data); $this->EventManager->setFromCache($data); $this->ReplacementTemplates = $data['Application.ReplacementTemplates']; $this->RewriteListeners = $data['Application.RewriteListeners']; $this->ModuleInfo = $data['Application.ModuleInfo']; } /** * Gets object data for caching * The following caches should be reset based on admin interaction (adjusting config, enabling modules etc) * * @access public * @return Array */ public function getToCache() { return array_merge( $this->Factory->getToCache(), $this->UnitConfigReader->getToCache(), $this->EventManager->getToCache(), Array ( 'Application.ReplacementTemplates' => $this->ReplacementTemplates, 'Application.RewriteListeners' => $this->RewriteListeners, 'Application.ModuleInfo' => $this->ModuleInfo, ) ); } public function delayUnitProcessing($method, $params) { $this->cacheManager->delayUnitProcessing($method, $params); } /** * Returns current maintenance mode state * * @param bool $check_ips * @return int * @access public */ public function getMaintenanceMode($check_ips = true) { $exception_ips = defined('MAINTENANCE_MODE_IPS') ? MAINTENANCE_MODE_IPS : ''; $setting_name = $this->isAdmin ? 'MAINTENANCE_MODE_ADMIN' : 'MAINTENANCE_MODE_FRONT'; if ( defined($setting_name) && constant($setting_name) > MaintenanceMode::NONE ) { $exception_ip = $check_ips ? kUtil::ipMatch($exception_ips) : false; if ( !$exception_ip ) { return constant($setting_name); } } return MaintenanceMode::NONE; } /** * Sets content type of the page * * @param string $content_type * @param bool $include_charset * @return void * @access public */ public function setContentType($content_type = 'text/html', $include_charset = null) { static $already_set = false; if ( $already_set ) { return; } $header = 'Content-type: ' . $content_type; if ( !isset($include_charset) ) { $include_charset = $content_type = 'text/html' || $content_type == 'text/plain' || $content_type = 'text/xml'; } if ( $include_charset ) { $header .= '; charset=' . CHARSET; } $already_set = true; header($header); } /** * Posts message to event log * * @param string $message * @param int $code * @param bool $write_now Allows further customization of log record by returning kLog object * @return bool|int|kLogger * @access public */ public function log($message, $code = null, $write_now = false) { $log = $this->_logger->prepare($message, $code)->addSource($this->_logger->createTrace(null, 1)); if ( $write_now ) { return $log->write(); } return $log; } /** * Deletes log with given id from database or disk, when database isn't available * * @param int $unique_id * @param int $storage_medium * @return void * @access public * @throws InvalidArgumentException */ public function deleteLog($unique_id, $storage_medium = kLogger::LS_AUTOMATIC) { $this->_logger->delete($unique_id, $storage_medium); } /** * Returns the client IP address. * * @return string The client IP address * @access public */ public function getClientIp() { return $this->HttpQuery->getClientIp(); } } Index: branches/5.3.x/core/kernel/utility/validator.php =================================================================== --- branches/5.3.x/core/kernel/utility/validator.php (revision 16123) +++ branches/5.3.x/core/kernel/utility/validator.php (revision 16124) @@ -1,504 +1,525 @@ '!la_err_required!', // Field is required 'unique' => '!la_err_unique!', // Field value must be unique 'value_out_of_range' => '!la_err_value_out_of_range!', // Field is out of range, possible values from %s to %s 'length_out_of_range' => '!la_err_length_out_of_range!', // Field is out of range 'bad_type' => '!la_err_bad_type!', // Incorrect data format, please use %s 'invalid_format' => '!la_err_invalid_format!', // Incorrect data format, please use %s 'bad_date_format' => '!la_err_bad_date_format!', // Incorrect date format, please use (%s) ex. (%s) 'primary_lang_required' => '!la_err_primary_lang_required!', // Primary Lang. value Required ); /** * Sets data source for validation * * @param kDBItem $object */ public function setDataSource(&$object) { if ( $object->getFormName() === $this->lastFormName && $object->getPrefixSpecial() === $this->lastPrefixSpecial ) { return ; } $this->reset(); $this->dataSource =& $object; $this->lastFormName = $object->getFormName(); $this->lastPrefixSpecial = $object->getPrefixSpecial(); } /** * Validate all item fields based on * constraints set in each field options * in config * * @return bool * @access private */ public function Validate() { // order is critical - should be called BEFORE checking errors $this->dataSource->UpdateFormattersMasterFields(); $global_res = true; $fields = array_keys( $this->dataSource->getFields() ); foreach ($fields as $field) { // call separately, otherwise 2+ validation errors will be ignored $res = $this->ValidateField($field); $global_res = $global_res && $res; } if ( !$global_res && $this->Application->isDebugMode() ) { $title_info = $this->dataSource->GetTitleField(); $item_info = Array ( $this->dataSource->IDField . ': ' . $this->dataSource->GetID() . '', ); if ( $title_info && reset($title_info) ) { $item_info[] = key($title_info) . ': ' . current($title_info) . ''; } $error_msg = ' Validation failed in prefix - ' . $this->dataSource->Prefix . ' (' . implode('; ', $item_info) . '), FieldErrors follow (look at items with "pseudo" key set)
You may ignore this notice if submitted data really has a validation error'; trigger_error(trim($error_msg), E_USER_NOTICE); $this->Application->Debugger->dumpVars($this->FieldErrors); } return $global_res; } /** * Validates given field * * @param string $field * @return bool * @access public */ public function ValidateField($field) { $options = $this->dataSource->GetFieldOptions($field); $error_field = isset($options['error_field']) ? $options['error_field'] : $field; $res = $this->GetErrorPseudo($error_field) == ''; $res = $res && $this->ValidateRequired($field, $options); $res = $res && $this->ValidateType($field, $options); $res = $res && $this->ValidateRange($field, $options); $res = $res && $this->ValidateUnique($field, $options); $res = $res && $this->CustomValidation($field, $options); return $res; } /** * Check if value is set for required field * * @param string $field field name * @param Array $params field options from config * @return bool * @access public */ public function ValidateRequired($field, $params) { if ( !isset($params['required']) || !$params['required'] ) { return true; } $value = $this->dataSource->GetDBField($field); if ( $this->Application->ConfigValue('TrimRequiredFields') ) { $value = trim($value); } if ( (string)$value == '' ) { $this->SetError($field, 'required'); return false; } return true; } /** * Check if value in field matches field type specified in config * * @param string $field field name * @param Array $params field options from config * @return bool */ protected function ValidateType($field, $params) { $val = $this->dataSource->GetDBField($field); $type_regex = "#int|integer|double|float|real|numeric|string#"; if ( $val == '' || !isset($params['type']) || !preg_match($type_regex, $params['type']) ) { return true; } if ( $params['type'] == 'numeric' ) { trigger_error('Invalid field type ' . $params['type'] . ' (in ValidateType method), please use float instead', E_USER_NOTICE); $params['type'] = 'float'; } $res = is_numeric($val); if ( $params['type'] == 'string' || $res ) { $f = 'is_' . $params['type']; settype($val, $params['type']); $res = $f($val) && ($val == $this->dataSource->GetDBField($field)); } if ( !$res ) { - $this->SetError($field, 'bad_type', null, Array ($params['type'])); + $this->SetError($field, 'bad_type', null, array('type' => $params['type'])); return false; } return true; } /** * Check if field value is in range specified in config * * @param string $field field name * @param Array $params field options from config * @return bool * @access private */ protected function ValidateRange($field, $params) { $res = true; $val = $this->dataSource->GetDBField($field); if ( isset($params['type']) && preg_match("#int|integer|double|float|real#", $params['type']) && strlen($val) > 0 ) { // validate number if ( isset($params['max_value_inc'])) { $res = $res && $val <= $params['max_value_inc']; $max_val = $params['max_value_inc'].' (inclusive)'; } if ( isset($params['min_value_inc'])) { $res = $res && $val >= $params['min_value_inc']; $min_val = $params['min_value_inc'].' (inclusive)'; } if ( isset($params['max_value_exc'])) { $res = $res && $val < $params['max_value_exc']; $max_val = $params['max_value_exc'].' (exclusive)'; } if ( isset($params['min_value_exc'])) { $res = $res && $val > $params['min_value_exc']; $min_val = $params['min_value_exc'].' (exclusive)'; } } if ( !$res ) { if ( !isset($min_val) ) $min_val = '-∞'; if ( !isset($max_val) ) $max_val = '∞'; - $this->SetError($field, 'value_out_of_range', null, Array ($min_val, $max_val)); + $this->SetError($field, 'value_out_of_range', null, array( + 'min_value' => $min_val, + 'max_value' => $max_val + )); return false; } // validate string if ( isset($params['max_len']) ) { $res = $res && mb_strlen($val) <= $params['max_len']; } if ( isset($params['min_len']) ) { $res = $res && mb_strlen($val) >= $params['min_len']; } if ( !$res ) { - $error_params = Array ((int)getArrayValue($params, 'min_len'), (int)getArrayValue($params, 'max_len'), mb_strlen($val)); + $error_params = array( + 'min_length' => (int)getArrayValue($params, 'min_len'), + 'max_length' => (int)getArrayValue($params, 'max_len'), + 'value' => mb_strlen($val) + ); $this->SetError($field, 'length_out_of_range', null, $error_params); return false; } return true; } /** * Validates that current record has unique field combination among other table records * * @param string $field field name * @param Array $params field options from config * @return bool * @access private */ protected function ValidateUnique($field, $params) { $unique_fields = getArrayValue($params, 'unique'); if ( $unique_fields === false ) { return true; } $where = Array (); array_push($unique_fields, $field); foreach ($unique_fields as $unique_field) { // if field is not empty or if it is required - we add where condition $field_value = $this->dataSource->GetDBField($unique_field); if ( (string)$field_value != '' || $this->dataSource->isRequired($unique_field) ) { $where[] = '`' . $unique_field . '` = ' . $this->Conn->qstr($field_value); } else { // not good if we check by less fields than indicated return true; } } // This can ONLY happen if all unique fields are empty and not required. // In such case we return true, because if unique field is not required there may be numerous empty values // if (!$where) return true; $sql = 'SELECT COUNT(*) FROM %s WHERE (' . implode(') AND (', $where) . ') AND (' . $this->dataSource->IDField . ' <> ' . (int)$this->dataSource->GetID() . ')'; $res_temp = $this->Conn->GetOne( str_replace('%s', $this->dataSource->TableName, $sql) ); $current_table_only = getArrayValue($params, 'current_table_only'); // check unique record only in current table $res_live = $current_table_only ? 0 : $this->Conn->GetOne( str_replace('%s', $this->Application->GetLiveName($this->dataSource->TableName), $sql) ); $res = ($res_temp == 0) && ($res_live == 0); if ( !$res ) { $this->SetError($field, 'unique'); return false; } return true; } /** * Check field value by user-defined alghoritm * * @param string $field field name * @param Array $params field options from config * @return bool */ protected function CustomValidation($field, $params) { return true; } /** * Set's field error, if pseudo passed not found then create it with message text supplied. * Don't overwrite existing pseudo translation. * * @param string $field * @param string $pseudo * @param string $error_label * @param Array $error_params * * @return bool * @access public */ public function SetError($field, $pseudo, $error_label = null, $error_params = null) { $error_field = $this->dataSource->GetFieldOption($field, 'error_field', false, $field); if ( $this->GetErrorPseudo($error_field) ) { // don't set more then one error on field return false; } $this->FieldErrors[$error_field]['pseudo'] = $pseudo; if ( isset($error_params) ) { if ( array_key_exists('value', $error_params) ) { $this->FieldErrors[$error_field]['value'] = $error_params['value']; unset($error_params['value']); } // additional params, that helps to determine error sources $this->FieldErrors[$error_field]['params'] = $error_params; } if ( isset($error_label) && !isset($this->ErrorMsgs[$pseudo]) ) { // label for error (only when not already set) $this->ErrorMsgs[$pseudo] = (substr($error_label, 0, 1) == '+') ? substr($error_label, 1) : '!'.$error_label.'!'; } return true; } /** * Return error message for field * * @param string $field * @param bool $force_escape * @return string * @access public */ public function GetErrorMsg($field, $force_escape = null) { $error_pseudo = $this->GetErrorPseudo($field); if ( !$error_pseudo ) { return ''; } // if special error msg defined in config $error_msgs = $this->dataSource->GetFieldOption($field, 'error_msgs', false, Array ()); if ( isset($error_msgs[$error_pseudo]) ) { $msg = $error_msgs[$error_pseudo]; } else { // fallback to defaults if ( !isset($this->ErrorMsgs[$error_pseudo]) ) { trigger_error('No user message is defined for pseudo error ' . $error_pseudo . '', E_USER_WARNING); return $error_pseudo; //return the pseudo itself } $msg = $this->ErrorMsgs[$error_pseudo]; } $msg = $this->Application->ReplaceLanguageTags($msg, $force_escape); if ( isset($this->FieldErrors[$field]['params']) ) { - return vsprintf($msg, $this->FieldErrors[$field]['params']); + $params = $this->FieldErrors[$field]['params']; + } + else { + $params = array(); + } + + $field_phrase = $this->Application->isAdmin ? 'la_fld_' . $field : 'lu_fld_' . $field; + $params['field'] = $this->Application->Phrase($field_phrase); + + foreach ( $params as $param_name => $param_value ) { + $msg = str_replace('{' . $param_name . '}', $param_value, $msg, $replacement_count); + } + + if ( strpos($msg, '%s') !== false ) { + trigger_error('Unexpected "%s" in field "' . $field . '" validation error message (pseudo: "' . $error_pseudo . '") in "' . $this->dataSource->Prefix . '" unit', E_USER_WARNING); } return $msg; } /** * Returns error pseudo * * @param string $field * @return string * @access public * */ public function GetErrorPseudo($field) { if ( !isset($this->FieldErrors[$field]) ) { return ''; } return isset($this->FieldErrors[$field]['pseudo']) ? $this->FieldErrors[$field]['pseudo'] : ''; } /** * Removes error on field * * @param string $field * @access public */ public function RemoveError($field) { unset( $this->FieldErrors[$field] ); } /** * Returns field errors * * @return Array * @access public */ public function GetFieldErrors() { return $this->FieldErrors; } /** * Check if item has errors * * @param Array $skip_fields fields to skip during error checking * @return bool * @access public */ public function HasErrors( $skip_fields = Array () ) { $fields = array_keys( $this->dataSource->getFields() ); $fields = array_diff($fields, $skip_fields); foreach ($fields as $field) { // if Formatter has set some error messages during values parsing if ( $this->GetErrorPseudo($field) ) { return true; } } return false; } /** * Clears all validation errors * * @access public */ public function reset() { $this->FieldErrors = Array(); } -} \ No newline at end of file +} Index: branches/5.3.x/core/units/themes/themes_config.php =================================================================== --- branches/5.3.x/core/units/themes/themes_config.php (revision 16123) +++ branches/5.3.x/core/units/themes/themes_config.php (revision 16124) @@ -1,158 +1,164 @@ 'theme', 'ItemClass' => Array ('class' => 'ThemeItem', 'file' => 'theme_item.php', 'build_event' => 'OnItemBuild'), 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), 'EventHandlerClass' => Array ('class' => 'ThemesEventHandler', 'file' => 'themes_eh.php', 'build_event' => 'OnBuild'), 'TagProcessorClass' => Array ('class' => 'ThemesTagProcessor', 'file' => 'themes_tag_processor.php', 'build_event' => 'OnBuild'), 'AutoLoad' => true, 'QueryString' => Array ( 1 => 'id', 2 => 'Page', 3 => 'PerPage', 4 => 'event', 5 => 'mode', ), 'IDField' => 'ThemeId', 'StatusField' => Array ('Enabled', 'PrimaryTheme'), 'PermSection' => Array ('main' => 'in-portal:configure_themes'), 'Sections' => Array ( 'in-portal:configure_themes' => Array ( 'parent' => 'in-portal:website_setting_folder', 'icon' => 'conf_themes', 'label' => 'la_tab_Themes', 'url' => Array ('t' => 'themes/themes_list', 'pass' => 'm'), 'permissions' => Array ('view', 'add', 'edit', 'delete'), 'priority' => 5, 'type' => stTREE, ), ), 'TitleField' => 'Name', 'TitlePresets' => Array ( 'default' => Array ( 'new_status_labels' => Array ('theme' => '!la_title_Adding_Theme!'), 'edit_status_labels' => Array ('theme' => '!la_title_Editing_Theme!'), 'new_titlefield' => Array ('theme' => '!la_title_NewTheme!'), ), 'themes_list' => Array ( 'prefixes' => Array ('theme_List'), 'format' => "!la_tab_Themes!", 'toolbar_buttons' => Array ('new_item', 'edit', 'delete', 'setprimary', 'refresh', 'view', 'dbl-click'), ), 'themes_edit_general' => Array ( 'prefixes' => Array ('theme'), 'format' => "#theme_status# '#theme_titlefield#' - !la_title_General!", 'toolbar_buttons' => Array ('select', 'cancel', 'prev', 'next'), ), 'themes_edit_files' => Array ( 'prefixes' => Array ('theme', 'theme-file_List'), 'format' => "#theme_status# '#theme_titlefield#' - !la_title_ThemeFiles!", 'toolbar_buttons' => Array ('select', 'cancel', 'prev', 'next', 'edit', 'delete', 'view', 'dbl-click'), ), 'theme_file_edit' => Array ( 'prefixes' => Array ('theme', 'theme-file'), 'new_status_labels' => Array ('theme-file' => '!la_title_AddingThemeFile!'), 'edit_status_labels' => Array ('theme-file' => '!la_title_EditingThemeFile!'), 'new_titlefield' => Array ('theme-file' => '!la_title_NewThemeFile!'), 'format' => "#theme_status# '#theme_titlefield#' - #theme-file_status# '#theme-file_titlefield#'", 'toolbar_buttons' => Array ('select', 'cancel', 'reset_edit', 'prev', 'next'), ), 'block_edit' => Array ('prefixes' => Array ('theme-file'), 'format' => "!la_title_EditingThemeFile! '#theme-file_titlefield#'"), ), 'EditTabPresets' => Array ( 'Default' => Array ( 'general' => Array ('title' => 'la_tab_General', 't' => 'themes/themes_edit', 'priority' => 1), 'files' => Array ('title' => 'la_tab_Files', 't' => 'themes/themes_edit_files', 'priority' => 2), ), ), 'TableName' => TABLE_PREFIX.'Themes', 'SubItems' => Array ('theme-file'), 'AutoDelete' => true, 'AutoClone' => true, 'ListSQLs' => Array ( '' => ' SELECT %1$s.* %2$s FROM %s' ), 'ListSortings' => Array ( '' => Array ( 'Sorting' => Array ('Name' => 'asc'), ) ), 'Fields' => Array ( 'ThemeId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), 'Name' => Array ('type' => 'string', 'not_null' => 1, 'required' => 1, 'default' => ''), 'Enabled' => Array ( 'type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (0 => 'la_Disabled', 1 => 'la_Enabled'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 1, ), 'Description' => Array ('type' => 'string', 'formatter' => 'kFormatter', 'using_fck' => 1, 'default' => null), 'PrimaryTheme' => Array ( 'type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (0 => 'la_No', 1 => 'la_Yes'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0, ), 'CacheTimeout' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), 'StylesheetId' => Array ('type' => 'int', /*'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM '.TABLE_PREFIX.'Stylesheets', 'option_key_field' => 'StylesheetId', 'option_title_field' => 'Name',*/ 'not_null' => 1, 'default' => 0), 'LanguagePackInstalled' => Array ( 'type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0 ), 'TemplateAliases' => Array ('type' => 'string', 'formatter' => 'kSerializedFormatter', 'default' => 'a:0:{}'), + 'StylesheetFile' => array( + 'type' => 'string', 'max_len' => 255, + 'error_msgs' => array('not_found' => '!la_error_FileNotFound!'), + 'not_null' => 1, 'default' => '' + ), 'ImageResizeRules' => Array ('type' => 'string', 'default' => NULL), ), 'Grids' => Array ( 'Default' => Array ( 'Icons' => Array ( 'default' => 'icon16_item.png', '0_0' => 'icon16_disabled.png', '0_1' => 'icon16_disabled.png', '1_0' => 'icon16_item.png', '1_1' => 'icon16_primary.png', ), 'Fields' => Array ( 'ThemeId' => Array ('title' => 'column:la_fld_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', 'width' => 50, ), 'Name' => Array ('filter_block' => 'grid_like_filter', 'width' => 200, ), 'Description' => Array ('filter_block' => 'grid_like_filter', 'width' => 250, ), 'Enabled' => Array ( 'title' => 'column:la_fld_Status', 'filter_block' => 'grid_options_filter', 'width' => 200, ), // 'PrimaryTheme' => Array ( 'title' => 'column:la_fld_Primary', 'filter_block' => 'grid_options_filter'), 'LanguagePackInstalled' => Array ('title' => 'la_col_LanguagePackInstalled', 'filter_block' => 'grid_options_filter', 'width' => 200,), + 'StylesheetFile' => array('filter_block' => 'grid_like_filter', 'width' => 150, 'hidden' => 1), ), ), ), ); \ No newline at end of file Index: branches/5.3.x/core/units/themes/theme_item.php =================================================================== --- branches/5.3.x/core/units/themes/theme_item.php (revision 16123) +++ branches/5.3.x/core/units/themes/theme_item.php (revision 16124) @@ -1,59 +1,87 @@ Application->siteDomainField('PrimaryThemeId'); if (!$id) { $id = 1; $id_field_name = 'PrimaryTheme'; } $default = true; } $res = parent::Load($id, $id_field_name, $cachable); if ($res) { $available_themes = $this->Application->siteDomainField('Themes'); if ($available_themes) { if (strpos($available_themes, '|' . $this->GetID() . '|') === false) { // theme isn't allowed in site domain return $this->Clear(); } } } if ($default) { if (!$res) { if ($this->Application->isAdmin) { $res = parent::Load(1, $id_field_name, false); } } $this->Application->SetVar('theme.current_id', $this->GetID() ); $this->Application->SetVar('m_theme', $this->GetID() ); } return $res; } - } \ No newline at end of file + + /** + * Returns full path to stylesheet file. + * + * @param boolean $as_url Allows to return url to stylesheet file instead of it's path. + * + * @return string|boolean + */ + public function getStylesheetFile($as_url = false) + { + $stylesheet_file = ltrim($this->GetDBField('StylesheetFile') ?: 'inc/style.css', '/'); + + $theme_path = FULL_PATH . '/themes/' . $this->GetDBField('Name'); + $stylesheet_file = $theme_path . '/' . $stylesheet_file; + + if ( !file_exists($stylesheet_file) ) { + return false; + } + + if ( $as_url ) { + /** @var FileHelper $file_helper */ + $file_helper = $this->Application->recallObject('FileHelper'); + + return $file_helper->pathToUrl($stylesheet_file); + } + + return $stylesheet_file; + } + } Index: branches/5.3.x/core/units/themes/themes_eh.php =================================================================== --- branches/5.3.x/core/units/themes/themes_eh.php (revision 16123) +++ branches/5.3.x/core/units/themes/themes_eh.php (revision 16124) @@ -1,199 +1,258 @@ Array('self' => true), ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * Checks user permission to execute given $event * * @param kEvent $event * @return bool * @access public */ public function CheckPermission(kEvent $event) { if ( $event->Name == 'OnItemBuild' ) { // check permission without using $event->getSection(), // so first cache rebuild won't lead to "ldefault_Name" field being used return true; } return parent::CheckPermission($event); } /** + * Ensure, that current object is always taken from live table. + * + * @param kDBBase|kDBItem|kDBList $object Object. + * @param kEvent $event Event. + * + * @return void + */ + protected function dbBuild(&$object, kEvent $event) + { + if ( $event->Special == 'current' ) { + $event->setEventParam('live_table', true); + } + + parent::dbBuild($object, $event); + } + + /** + * Ensures that current theme detection will fallback to primary without extra DB query. + * + * @param kEvent $event Event. + * + * @return integer + */ + public function getPassedID(kEvent $event) + { + if ( $event->Special == 'current' ) { + $theme_id = $this->Application->GetVar('m_theme'); + + if ( !$theme_id ) { + $theme_id = 'default'; + } + + $this->Application->SetVar('m_theme', $theme_id); + $this->Application->SetVar($event->getPrefixSpecial() . '_id', $theme_id); + } + + return parent::getPassedID($event); + } + + /** * Allows to set selected theme as primary * * @param kEvent $event */ function OnSetPrimary($event) { if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { $event->status = kEvent::erFAIL; return; } $ids = $this->StoreSelectedIDs($event); if ($ids) { $id = array_shift($ids); $this->setPrimary($id); $this->Application->HandleEvent(new kEvent('adm:OnRebuildThemes')); } $this->clearSelectedIDs($event); } function setPrimary($id) { $config = $this->getUnitConfig(); $table_name = $config->getTableName(); $sql = 'UPDATE '.$table_name.' SET PrimaryTheme = 0'; $this->Conn->Query($sql); $sql = 'UPDATE '.$table_name.' SET PrimaryTheme = 1, Enabled = 1 WHERE '. $config->getIDField() .' = '.$id; $this->Conn->Query($sql); } /** + * Validate entered stylesheet path. + * + * @param kEvent $event Event. + * + * @return void + */ + protected function OnBeforeItemUpdate(kEvent $event) + { + parent::OnBeforeItemUpdate($event); + + /** @var ThemeItem $object */ + $object = $event->getObject(); + + if ( $object->GetDBField('StylesheetFile') && !$object->getStylesheetFile() ) { + $object->SetError('StylesheetFile', 'not_found'); + } + } + + /** * Set's primary theme (when checkbox used on editing form) * * @param kEvent $event * @return void * @access protected */ protected function OnAfterCopyToLive(kEvent $event) { parent::OnAfterCopyToLive($event); $object = $this->Application->recallObject($event->Prefix . '.-item', null, Array ('skip_autoload' => true, 'live_table' => true)); /* @var $object kDBItem */ $object->Load($event->getEventParam('id')); if ( $object->GetDBField('PrimaryTheme') ) { $this->setPrimary($event->getEventParam('id')); } } /** * Also rebuilds theme files, when enabled theme is saved * * @param kEvent $event * @return void * @access protected */ protected function OnSave(kEvent $event) { parent::OnSave($event); if ( ($event->status != kEvent::erSUCCESS) || !$event->getEventParam('ids') ) { return ; } $config = $event->getUnitConfig(); $ids = $event->getEventParam('ids'); $sql = 'SELECT COUNT(*) FROM ' . $config->getTableName() . ' WHERE ' . $config->getIDField() . ' IN (' . $ids . ') AND (Enabled = 1)'; $enabled_themes = $this->Conn->GetOne($sql); if ( $enabled_themes ) { $this->Application->HandleEvent(new kEvent('adm:OnRebuildThemes')); } } /** * Allows to change the theme * * @param kEvent $event */ function OnChangeTheme($event) { if ($this->Application->isAdminUser) { // for structure theme dropdown $this->Application->StoreVar('theme_id', $this->Application->GetVar('theme')); $this->Application->StoreVar('RefreshStructureTree', 1); return ; } $this->Application->SetVar('t', 'index'); $this->Application->SetVar('m_cat_id', 0); $this->Application->SetVar('m_theme', $this->Application->GetVar('theme')); } /** * Apply system filter to themes list * * @param kEvent $event * @return void * @access protected * @see kDBEventHandler::OnListBuild() */ protected function SetCustomQuery(kEvent $event) { parent::SetCustomQuery($event); $object = $event->getObject(); /* @var $object kDBList */ if ( in_array($event->Special, Array ('enabled', 'selected', 'available')) || !$this->Application->isAdminUser ) { // "enabled" special or Front-End $object->addFilter('enabled_filter', '%1$s.Enabled = ' . STATUS_ACTIVE); } // site domain theme picker if ( $event->Special == 'selected' || $event->Special == 'available' ) { $edit_picker_helper = $this->Application->recallObject('EditPickerHelper'); /* @var $edit_picker_helper EditPickerHelper */ $edit_picker_helper->applyFilter($event, 'Themes'); } // apply domain-based theme filtering $themes = $this->Application->siteDomainField('Themes'); if ( strlen($themes) ) { $themes = explode('|', substr($themes, 1, -1)); $object->addFilter('domain_filter', '%1$s.ThemeId IN (' . implode(',', $themes) . ')'); } } } Index: branches/5.3.x/core/units/helpers/fck_helper.php =================================================================== --- branches/5.3.x/core/units/helpers/fck_helper.php (revision 16123) +++ branches/5.3.x/core/units/helpers/fck_helper.php (revision 16124) @@ -1,621 +1,625 @@ folder = $this->Application->GetVar('folder'); $this->sortField = $this->Application->GetVar('sort_by'); $this->sortDirection = $this->Application->GetVar('order_by'); $this->Config['AllowedExtensions']['Files'] = Array('gif','jpeg','png','swf','fla','jpg','gif','jpeg','png','avi','mpg','mpeg','zip','rar','arj','gz','tar','doc','pdf','ppt','rdp','swf','swt','txt','vsd','xls','csv','odt'); $this->Config['DeniedExtensions']['Files'] = Array('php','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','dll','reg'); $this->Config['AllowedExtensions']['Images'] = Array('jpg','gif','jpeg','png', 'bmp'); $this->Config['DeniedExtensions']['Images'] = Array('php','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','dll','reg'); $this->Config['AllowedExtensions']['Flash'] = Array('swf','fla'); $this->Config['DeniedExtensions']['Flash'] = Array('php','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','dll','reg'); $this->Config['AllowedExtensions']['Media'] = Array('asf','asx','avi','wav','wax','wma','wm','wmv','m3u','mp2v','mpg','mpeg','m1v','mp2','mp3','mpa','mpe','mpv2','mp4','mid','midi','rmi','qt','aif','aifc','aiff','mov','flv','rm','svcd','swf','vcd'); $this->Config['DeniedExtensions']['Media'] = Array('php','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','dll','reg'); $this->Config['AllowedExtensions']['Documents'] = Array('doc','pdf','ppt','rdp','swf','swt','txt','vsd','xls','csv','zip','odt'); $this->Config['DeniedExtensions']['Documents'] = Array('php','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','dll','reg'); $this->Config['ExtensionIcons'] = Array('ai','avi','bmp','cs','dll','doc','exe','fla','gif','htm','html','jpg','js','mdb','mp3','pdf','png','ppt','rdp','swf','swt','txt','vsd','xls','xml','zip'); } function CreateFolder($folder = '') { if ( !$folder ) { return false; } $folderPath = WRITEABLE . '/user_files/' . $folder; if ( file_exists($folderPath) && is_dir($folderPath) ) { return true; } /*$permissions = defined('FCK_FOLDERS_PERMISSIONS') ? FCK_FOLDERS_PERMISSIONS : '0777'; return mkdir($folderPath, $permissions);*/ return mkdir($folderPath); } function IsAllowedExtension($folder, $file_name) { $ext = strtolower( pathinfo($file_name, PATHINFO_EXTENSION) ); if ( isset($this->Config['DeniedExtensions'][$folder]) ) { if ( in_array($ext, $this->Config['DeniedExtensions'][$folder]) ) { return false; } } if ( isset($this->Config['AllowedExtensions'][$folder]) ) { if ( !in_array($ext, $this->Config['AllowedExtensions'][$folder]) ) { return false; } } return true; } /** * Returns list of sub-folders from given folder (automatically excludes system folders) * * @param string $files_dir * @return Array * @access public */ public function ReadFolders($files_dir) { $ret = Array (); $system_folders = defined('KERNEL_SYSTEM_FOLDERS') ? KERNEL_SYSTEM_FOLDERS : Array ('icons', 'CVS', '.svn'); try { $iterator = new DirectoryIterator($files_dir); /* @var $file_info DirectoryIterator */ } catch (UnexpectedValueException $e) { return $ret; } foreach ($iterator as $file_info) { $filename = $file_info->getFilename(); if ( $file_info->isDir() && !$file_info->isDot() ) { $ret[] = $filename; } } return array_diff($ret, $system_folders); } /** * Returns list of files in given folder * * @param string $files_dir * @return Array * @access public */ public function ReadFiles($files_dir) { $ret = Array (); try { $iterator = new DirectoryIterator($files_dir); /* @var $file_info DirectoryIterator */ } catch (UnexpectedValueException $e) { return $ret; } foreach ($iterator as $file_info) { if ( !$file_info->isDir() ) { $ret[] = $file_info->getFilename(); } } return $ret; } /** * Returns xml containing list of folders in current folder * * @return string * @access public */ public function PrintFolders() { $files_dir = WRITEABLE . '/user_files/' . $this->folder . '/'; $sub_folders = $this->ReadFolders($files_dir); natcasesort($sub_folders); $ret = $this->_buildFoldersXML($sub_folders, 'folder2'); if ( $this->sortField == 'name' && $this->sortDirection == '_desc' ) { $sub_folders = array_reverse($sub_folders); } $ret .= $this->_buildFoldersXML($sub_folders, 'folder'); return $ret; } /** * Build XML, that will output folders for FCKEditor * * @param Array $sub_folders * @param string $xml_node * @return string */ protected function _buildFoldersXML($sub_folders, $xml_node) { $ret = ''; foreach ($sub_folders as $sub_folder) { $ret .= '<' . $xml_node . ' path="' . $this->folder . "/" . $sub_folder . '">' . $sub_folder . '' . "\n"; } return $ret; } /** * Transforms filesize in bytes into kilobytes * * @param int $size * @return int * @access protected */ protected function CalculateFileSize($size) { if ( $size > 0 ) { $size = round($size / 1024); $size = ($size < 1) ? 1 : $size; } return $size; } /** * Detects icon for given file extension * * @param string $file * @return string * @access protected */ protected function CheckIconType($file) { $ext = strtolower( pathinfo($file, PATHINFO_EXTENSION) ); return $ext && in_array($ext, $this->Config['ExtensionIcons']) ? $ext : 'default.icon'; } /** * Build one file xml node * * @param int $size * @param string $url * @param string $icon * @param string $date * @param string $file_name * @return string */ protected function _buildFileXml($size,$url,$icon,$date,$file_name) { return '' . $file_name . '' . "\n"; } /** * Returns xml containing list of files in current folder * * @return string * @access public */ public function PrintFiles() { $files_dir = WRITEABLE . '/user_files/' . $this->folder . '/'; $files_url = BASE_PATH . str_replace(DIRECTORY_SEPARATOR, '/', WRITEBALE_BASE) . '/user_files/' . $this->folder . '/'; $aFiles = $this->ReadFiles($files_dir); $ret = ''; $date_format = "m/d/Y h:i A"; natcasesort($aFiles); if ( $this->sortField == 'name' && $this->sortDirection == '_desc' ) { $aFiles = array_reverse($aFiles, TRUE); } $aFilesSize = $aFilesDate = Array (); foreach ($aFiles as $k => $v) { $aFilesSize[$k] = filesize($files_dir . $v); $aFilesDate[$k] = filectime($files_dir . $v); } if ( $this->sortField == 'name' ) { foreach ($aFiles as $k => $file) { $size = $this->CalculateFileSize($aFilesSize[$k]); $date = date($date_format, $aFilesDate[$k]); $icon = $this->CheckIconType($file); $ret .= $this->_buildFileXml($size, $files_url . $file, $icon, $date, $file); } } if ( $this->sortField == 'date' ) { asort($aFilesDate); if ( $this->sortDirection == '_desc' ) { $aFilesDate = array_reverse($aFilesDate, TRUE); } foreach ($aFilesDate as $k => $date) { $size = $this->CalculateFileSize($aFilesSize[$k]); $file = $aFiles[$k]; $date = date($date_format, $date); $icon = $this->CheckIconType($file); $ret .= $this->_buildFileXml($size, $files_url . $file, $icon, $date, $file); } } if ( $this->sortField == 'size' ) { asort($aFilesSize); if ( $this->sortDirection == '_desc' ) { $aFilesSize = array_reverse($aFilesSize, TRUE); } foreach ($aFilesSize as $k => $size) { $size = $this->CalculateFileSize($size); $file = $aFiles[$k]; $date = date($date_format, $aFilesDate[$k]); $icon = $this->CheckIconType($file); $ret .= $this->_buildFileXml($size, $files_url . $file, $icon, $date, $file); } } return $ret; } function UploadFile() { $upload_dir = $this->Application->GetVar('upload_dir'); $type = explode('/', $upload_dir); $type = $type[0]; $sServerDir = WRITEABLE . '/user_files/' . $upload_dir . '/'; $aUpFile = $_FILES['NewFile']; $sFileName = $aUpFile['name']; $sOriginalFileName = $aUpFile['name']; $sExtension = strtolower(substr( $sFileName, ( strrpos($sFileName, '.') + 1 ) ) ); $sErrorNumber = 0; if ( isset( $_FILES['NewFile'] ) && !is_null( $_FILES['NewFile']['tmp_name'] ) ) { if (in_array($sExtension, $this->Config['AllowedExtensions'][$type])) { if (!$aUpFile['error']) { $iCounter = 0 ; while ( true ) { $sFilePath = $sServerDir . $sFileName; if ( is_file( $sFilePath ) ) { $iCounter++ ; $sFileName = $this->RemoveExtension( $sOriginalFileName ) . '(' . $iCounter . ').' . $sExtension; $sErrorNumber = '201'; } else { // Turn off all error reporting. error_reporting( 0 ) ; // Enable error tracking to catch the error. ini_set( 'track_errors', '1' ); move_uploaded_file( $aUpFile['tmp_name'], $sFilePath ); $sErrorMsg = $php_errormsg; // Restore the configurations. ini_restore( 'track_errors' ); ini_restore( 'error_reporting' ); if ( is_file( $sFilePath ) ) { $oldumask = umask(0); chmod( $sFilePath, 0666 ); umask( $oldumask ); } break ; } } } } else { $sErrorNumber = '203'; } } else { $sErrorNumber = '202' ; } echo '' ; } function RemoveExtension( $fileName ) { return substr( $fileName, 0, strrpos( $fileName, '.' ) ) ; } public function CKEditorTag($editor_name, $editor_value, $params) { $editor = $this->prepareConfig($this->getEditor(), $params); $width = $this->normalizeDimension($params['width']); $height = $this->normalizeDimension($params['height']); $editor->textareaAttributes = Array ( 'style' => 'width: ' . $width . '; height: ' . $height . ';' ); $editor->config['height'] = $height; // editor area height $events = Array ( 'configLoaded' => 'function(ev) { CKEDITOR.addCss(ev.editor.config.extraCss); }', ); return $editor->editor($editor_name, $editor_value, Array (), $events); } public function CKEditorInlineTag($editor_name, $params) { $editor = $this->prepareConfig($this->getEditor(), $params); $events = Array ( 'configLoaded' => 'function(ev) { CKEDITOR.addCss(ev.editor.config.extraCss); }', 'focus' => 'function(ev) { $("body").trigger("InlineEditor.Focus", [ev]); }', 'blur' => 'function(ev) { $("body").trigger("InlineEditor.Blur", [ev]); }', ); return $editor->inline($editor_name, Array (), $events); } /** * Adds measurement units to editor dimensions. * * @param string $dimension Dimension. * * @return string */ protected function normalizeDimension($dimension) { if ( preg_match('/^[\d]+$/', $dimension) ) { $dimension .= 'px'; } return $dimension; } /** * Returns editor instance. * * @return CKEditor */ protected function getEditor() { include_once(FULL_PATH . EDITOR_PATH . 'ckeditor.php'); $editor = new CKeditor(BASE_PATH . EDITOR_PATH); $editor->returnOutput = true; return $editor; } /** * Prepares editor config. * * @param CKEditor $editor Editor. * @param array $tag_params Tag params. * * @return CKEditor */ protected function prepareConfig(CKEditor $editor, array $tag_params) { $editor->lateLoad = array_key_exists('late_load', $tag_params) && $tag_params['late_load']; list($styles_css, $styles_js) = $this->getStyles(); if ( isset($tag_params['toolbar']) ) { $toolbar = $tag_params['toolbar']; } elseif ( isset($tag_params['mode']) && $tag_params['mode'] == 'inline' ) { $toolbar = 'Inline'; } else { $toolbar = $this->Application->isDebugMode() ? 'DebugMode' : 'Default'; } $editor->config = Array ( 'toolbar' => $toolbar, 'baseHref' => $this->Application->BaseURL() . trim(EDITOR_PATH, '/') . '/', 'customConfig' => $this->getJavaScriptConfig(), 'stylesSet' => 'portal:' . $styles_js, 'contentsCss' => $styles_css, 'Admin' => 1, // for custom file browser to work 'K4' => 1, // for custom file browser to work 'language' => $this->getLanguage(), ); $this->injectTransitParams($editor, $this->getTransitParams($tag_params)); return $editor; } /** * Transforms transit params into editor config. * * @param CKEditor $editor Editor. * @param array $transit_params Transit params. * * @return void */ protected function injectTransitParams(CKEditor $editor, array $transit_params) { if ( isset($transit_params['bgcolor']) && $transit_params['bgcolor'] ) { $editor->config['extraCss'] = 'body { background-color: ' . $transit_params['bgcolor'] . '; }'; } foreach ($transit_params as $param_name => $param_value) { if ( !$param_value ) { continue; } $param_key = str_replace(' ', '', ucwords(str_replace('_', ' ', $param_name))); $param_key[0] = strtolower($param_key[0]); $editor->config[$param_key] = $param_value; } } /** * Returns url to CSS and JS style configuration. * * @return array */ protected function getStyles() { - $theme_path = ltrim($this->Application->GetFrontThemePath(), '/') . '/inc'; + /** @var ThemeItem $theme */ + $theme = $this->Application->recallObject('theme.current'); + $stylesheet_file = $theme->getStylesheetFile(true); + + if ( $stylesheet_file ) { + $stylesheet_folder_url = dirname($stylesheet_file) . '/'; - if ( file_exists(FULL_PATH . '/' . $theme_path . '/style.css') ) { $url_params = Array ('events[fck]' => 'OnGetsEditorStyles', 'no_pass_through' => 1, 'pass' => 'm'); $styles_css = $this->Application->HREF('index', '_FRONT_END_', $url_params, 'index.php'); } else { - $theme_path = trim(EDITOR_PATH, '/'); - $styles_css = $this->Application->BaseURL() . $theme_path . '/style.css'; + $stylesheet_folder_url = $this->Application->BaseURL(rtrim(EDITOR_PATH, '/')); + $styles_css = $stylesheet_folder_url . 'style.css'; } - $styles_js = $this->Application->BaseURL() . $theme_path . '/styles.js'; + $styles_js = $stylesheet_folder_url . 'styles.js'; return array($styles_css, $styles_js); } /** * Returns url to JavaScript configuration file. * * @return string */ protected function getJavaScriptConfig() { if ( file_exists(SYSTEM_PRESET_PATH . DIRECTORY_SEPARATOR . 'inp_ckconfig.js') ) { $file_helper = $this->Application->recallObject('FileHelper'); /* @var $file_helper FileHelper */ return $file_helper->pathToUrl(SYSTEM_PRESET_PATH . DIRECTORY_SEPARATOR . 'inp_ckconfig.js'); } return $this->Application->BaseURL() . 'core/admin_templates/js/inp_ckconfig.js'; } /** * Returns CKEditor locale, that matches default site language. * * @return string */ protected function getLanguage() { static $language_code = null; if ( !isset($language_code) ) { $language_code = 'en'; // default value if ( $this->Application->isAdmin ) { $language_id = $this->Application->Phrases->LanguageId; } else { $language_id = $this->Application->GetDefaultLanguageId(); // $this->Application->GetVar('m_lang'); } $sql = 'SELECT Locale FROM ' . $this->Application->getUnitConfig('lang')->getTableName() . ' WHERE LanguageId = ' . $language_id; $locale = strtolower($this->Conn->GetOne($sql)); if ( file_exists(FULL_PATH . EDITOR_PATH . 'editor/lang/' . $locale . '.js') ) { // found language file, that exactly matches locale name (e.g. "en") $language_code = $locale; } else { $locale = explode('-', $locale); if ( file_exists(FULL_PATH . EDITOR_PATH . 'editor/lang/' . $locale[0] . '.js') ) { // language file matches first part of locale (e.g. "ru-RU") $language_code = $locale[0]; } } } return $language_code; } /** * Returns transit parameters, that should be passed to every used CKEditor instance * * @param Array $tag_params * @return Array */ public function getTransitParams($tag_params = Array ()) { $ret = Array (); $transit_params = Array ('bgcolor' => '', 'body_class' => '', 'body_id' => ''); foreach ($transit_params as $param_name => $default_value) { $param_value = isset($tag_params[$param_name]) ? $tag_params[$param_name] : $this->Application->GetVar($param_name); if ( $param_value || $default_value ) { $ret[$param_name] = $param_value ? $param_value : $default_value; } } return $ret; } -} \ No newline at end of file +} Index: branches/5.3.x/core/units/helpers/curl_helper.php =================================================================== --- branches/5.3.x/core/units/helpers/curl_helper.php (revision 16123) +++ branches/5.3.x/core/units/helpers/curl_helper.php (revision 16124) @@ -1,569 +1,571 @@ debugMode = kUtil::constOn('DBG_CURL'); } /** * Reset connection settings (not results) after connection was closed * * @access protected */ protected function _resetSettings() { $this->timeout = 90; $this->followLocation = false; $this->requestMethod = self::REQUEST_METHOD_GET; $this->requestData = ''; $this->requestHeaders = Array (); $this->options = Array (); } /** * Resets information in last* properties. * * @return void */ protected function resetLastInfo() { $this->lastErrorCode = 0; $this->lastErrorMsg = ''; $this->lastHTTPCode = 0; $this->lastRedirectCount = 0; } /** * Sets CURL options (adds to options set before) * * @param Array $options_hash * @access public */ public function setOptions($options_hash) { $this->options = kUtil::array_merge_recursive($this->options, $options_hash); } /** * Combines user-defined and default options before setting them to CURL * * @access protected */ protected function prepareOptions() { $default_options = Array ( // customizable options CURLOPT_TIMEOUT => $this->timeout, // hardcoded options CURLOPT_RETURNTRANSFER => 1, CURLOPT_REFERER => PROTOCOL.SERVER_NAME, CURLOPT_MAXREDIRS => 5, // don't verify SSL certificates CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, + + // Prevents CURL from adding "Expect: 100-continue" header for POST requests. CURLOPT_HTTPHEADER => Array ('Expect:'), ); if ( isset($_SERVER['HTTP_USER_AGENT']) ) { $default_options[CURLOPT_USERAGENT] = $_SERVER['HTTP_USER_AGENT']; } if ($this->requestHeaders) { $default_options[CURLOPT_HTTPHEADER] = $this->prepareHeaders(); } // if we have post data, then POST else use GET method instead if ($this->requestMethod == self::REQUEST_METHOD_POST) { $default_options[CURLOPT_POST] = 1; $default_options[CURLOPT_POSTFIELDS] = $this->requestData; } // $default_options[CURLOPT_HEADERFUNCTION] = Array(&$this, 'ParseHeader'); $user_options = $this->options; // backup options, that user set directly $this->setOptions($default_options); $this->setOptions($user_options); $this->applyOptions(); } /** * Sets prepared options to CURL * * @access protected */ protected function applyOptions() { foreach ($this->options as $option_name => $option_value) { curl_setopt($this->connectionID, $option_name, $option_value); } } /** * Parses headers from CURL request * * @param resource $ch * @param string $header * @return int * @access protected */ protected function ParseHeader(&$ch, $header) { $this->responseHeaders[] = $header; return strlen($header); } /** * Sets request data for next query * * @param mixed $data Array or string */ public function SetRequestData($data) { if ( is_array($data) ) { $data = http_build_query($data); } $this->requestData = $data; } /** * Sets request data for next query and switches request method to POST * * @param mixed $data Array or string * @access public */ public function SetPostData($data) { $this->requestMethod = self::REQUEST_METHOD_POST; $this->SetRequestData($data); } /** * Sets request method to be used in next request * * @param int $request_method * * @throws InvalidArgumentException When invalid request method given. */ public function SetRequestMethod($request_method) { if ($request_method != self::REQUEST_METHOD_GET && $request_method != self::REQUEST_METHOD_POST) { throw new InvalidArgumentException('Method "' . __METHOD__ . '": Invalid $request_method parameter value'); } $this->requestMethod = $request_method; } /** * Sets headers to be sent along with next query * * @param Array $headers * @access public */ public function SetHeaders($headers) { $this->requestHeaders = array_merge($this->requestHeaders, $headers); } /** * Returns compiled header to be used by curl * * @return Array * @access protected */ protected function prepareHeaders() { $ret = Array (); foreach ($this->requestHeaders as $header_name => $header_value) { $ret[] = is_numeric($header_name) ? $header_value : $header_name . ': ' . $header_value; } return $ret; } /** * Performs CURL request and returns it's result * * @param string $url * @param bool $close_connection * @param bool $log_status * @param string $log_message * @return string * @access public */ public function Send($url, $close_connection = true, $log_status = NULL, $log_message = '') { if ( isset($log_status) ) { // override debug mode setting $this->debugMode = $log_status; } $request_url = $url; if ( $this->requestMethod == self::REQUEST_METHOD_GET && $this->requestData ) { $request_url .= (strpos($request_url, '?') !== false ? '&' : '?') . $this->requestData; } $this->connectionID = curl_init($request_url); if ( $this->debugMode ) { // collect page data $page_data = Array (); if ( $_GET ) { $page_data[] = '_GET:' . "\n" . print_r($_GET, true); } if ( $_POST ) { $page_data[] = '_POST:' . "\n" . print_r($_POST, true); } if ( $_COOKIE ) { $page_data[] = '_COOKIE:' . "\n" . print_r($_COOKIE, true); } // create log record $fields_hash = Array ( 'Message' => $log_message, 'PageUrl' => $_SERVER['REQUEST_URI'], 'RequestUrl' => $url, 'PortalUserId' => $this->Application->RecallVar('user_id'), 'SessionKey' => $this->Application->GetSID(), 'IsAdmin' => $this->Application->isAdminUser ? 1 : 0, 'PageData' => implode("\n", $page_data), 'RequestData' => $this->requestData, 'RequestDate' => time(), ); $this->Conn->doInsert($fields_hash, TABLE_PREFIX . 'CurlLog'); $this->logId = $this->Conn->getInsertID(); } $this->responseHeaders = Array (); $this->prepareOptions(); $this->lastResponse = $this->_sendRequest(); $this->Finalize($close_connection); return $this->lastResponse; } /** * Reads data from remote url * * @return string * @access protected */ protected function _sendRequest() { $this->resetLastInfo(); curl_setopt($this->connectionID, CURLOPT_RETURNTRANSFER, true); if ( $this->followLocation ) { if ( $this->followLocationLimited() ) { return $this->_followLocationManually(); } else { // no restrictions - let curl do automatic redirects curl_setopt($this->connectionID, CURLOPT_FOLLOWLOCATION, true); } } return curl_exec($this->connectionID); } /** * Fixes curl inability to automatically follow location when safe_mode/open_basedir restriction in effect * * @return string * @access protected */ protected function _followLocationManually() { curl_setopt($this->connectionID, CURLOPT_HEADER, true); $data = curl_exec($this->connectionID); $http_code = $this->getInfo(CURLINFO_HTTP_CODE); if ( $http_code == 301 || $http_code == 302 ) { // safe more or open_basedir restriction - do redirects manually list ($header) = explode("\r\n\r\n", $data, 2); preg_match('/(Location:|URI:)(.*?)\n/', $header, $regs); $url = trim(array_pop($regs)); $url_parsed = parse_url($url); if ( $this->lastRedirectCount == $this->options[CURLOPT_MAXREDIRS] ) { return $this->setError(CURLE_TOO_MANY_REDIRECTS, 'Maximum (' . $this->options[CURLOPT_MAXREDIRS] . ') redirects followed'); } if ( isset($url_parsed) ) { curl_setopt($this->connectionID, CURLOPT_URL, $url); $this->lastRedirectCount++; return $this->_followLocationManually(); } } list(, $body) = explode("\r\n\r\n", $data, 2); return $body; } /** * Sets error manually. * * @param integer $code Code. * @param string $message Message. * * @return boolean */ protected function setError($code, $message) { $this->lastErrorCode = $code; $this->lastErrorMsg = $message; return false; } /** * Returns various info about request made * * @param int $info_type * @return mixed * * @see http://www.php.net/manual/ru/function.curl-getinfo.php * @access public */ public function getInfo($info_type) { if ( $info_type == CURLINFO_REDIRECT_COUNT && $this->followLocationLimited() ) { return $this->lastRedirectCount; } return curl_getinfo($this->connectionID, $info_type); } /** * Detects, that follow location can't be done automatically by curl due safe_mode/open_basedir restrictions * * @return bool * @access protected */ protected function followLocationLimited() { return (defined('SAFE_MODE') && SAFE_MODE) || ini_get('open_basedir'); } /** * Finalizes curl request and saves some data from curl before closing connection * * @param bool $close_connection * @return void * @access public */ public function Finalize($close_connection = true) { if ( $this->lastErrorCode == 0 ) { // error not set manually -> get it from curl $this->lastErrorCode = curl_errno($this->connectionID); $this->lastErrorMsg = curl_error($this->connectionID); } $this->lastHTTPCode = $this->getInfo(CURLINFO_HTTP_CODE); if ( $close_connection ) { $this->CloseConnection(); } $this->_resetSettings(); } /** * Closes connection to server * * @access public */ public function CloseConnection() { curl_close($this->connectionID); if ( $this->debugMode ) { $fields_hash = Array ( 'ResponseData' => $this->lastResponse, 'ResponseDate' => time(), 'ResponseHttpCode' => $this->lastHTTPCode, 'CurlError' => $this->lastErrorCode != 0 ? '#' . $this->lastErrorCode . ' (' . $this->lastErrorMsg . ')' : '', ); $this->Conn->doUpdate($fields_hash, TABLE_PREFIX . 'CurlLog', 'LogId = ' . $this->logId); } // restore debug mode setting $this->debugMode = kUtil::constOn('DBG_CURL'); } /** * Checks, that last curl request was successful * * @return bool * @access public */ public function isGoodResponseCode() { if ( $this->lastErrorCode != 0 ) { return false; } return ($this->lastHTTPCode == 200) || ($this->lastHTTPCode >= 300 && $this->lastHTTPCode < 310); } } Index: branches/5.3.x/core/units/helpers/themes_helper.php =================================================================== --- branches/5.3.x/core/units/helpers/themes_helper.php (revision 16123) +++ branches/5.3.x/core/units/helpers/themes_helper.php (revision 16124) @@ -1,642 +1,677 @@ themesFolder = FULL_PATH.'/themes'; } /** * Updates file system changes to database for selected theme * * @param string $theme_name * * @return mixed returns ID of created/used theme or false, if none created */ function refreshTheme($theme_name) { if (!file_exists($this->themesFolder . '/' . $theme_name)) { // requested theme was not found on hdd return false; } $config = $this->Application->getUnitConfig('theme'); $id_field = $config->getIDField(); $table_name = $config->getTableName(); $sql = 'SELECT * FROM ' . $table_name . ' WHERE Name = ' . $this->Conn->qstr($theme_name); $theme_info = $this->Conn->GetRow($sql); if ($theme_info) { $theme_id = $theme_info[$id_field]; $theme_enabled = $theme_info['Enabled']; } else { $theme_id = $theme_enabled = false; } $this->themeFiles = Array (); + $theme_path = $this->themesFolder . '/' . $theme_name; + if ($theme_id) { if (!$theme_enabled) { // don't process existing theme files, that are disabled return $theme_id; } // reset found mark for every themes file (if theme is not new) $sql = 'UPDATE '.TABLE_PREFIX.'ThemeFiles SET FileFound = 0 WHERE ThemeId = '.$theme_id; $this->Conn->Query($sql); // get all theme files from db $sql = 'SELECT FileId, CONCAT(FilePath, "/", FileName) AS FullPath FROM '.TABLE_PREFIX.'ThemeFiles WHERE ThemeId = '.$theme_id; $this->themeFiles = $this->Conn->GetCol($sql, 'FullPath'); } else { // theme was not found in db, but found on hdd -> create new + $config = $this->getConfiguration($theme_path); + $theme_info = Array ( 'Name' => $theme_name, 'Enabled' => 0, 'Description' => $theme_name, 'PrimaryTheme' => 0, 'CacheTimeout' => 3600, // not in use right now 'StylesheetId' => 0, // not in use right now - 'LanguagePackInstalled' => 0 + 'LanguagePackInstalled' => 0, + 'StylesheetFile' => isset($config['stylesheet_file']) ? $config['stylesheet_file'] : '', ); $this->Conn->doInsert($theme_info, $table_name); $theme_id = $this->Conn->getInsertID(); if (!$theme_enabled) { // don't process newly created theme files, because they are disabled return $theme_id; } } $this->_themeNames[$theme_id] = $theme_name; - $theme_path = $this->themesFolder.'/'.$theme_name; $this->FindThemeFiles('', $theme_path, $theme_id); // search from base theme directory // delete file records from db, that were not found on hdd $sql = 'DELETE FROM '.TABLE_PREFIX.'ThemeFiles WHERE ThemeId = '.$theme_id.' AND FileFound = 0'; $this->Conn->Query($sql); // install language packs, associated with theme (if any found and wasn't aready installed) if (!$theme_info['LanguagePackInstalled']) { $this->installThemeLanguagePack($theme_path); $fields_hash = Array ( 'LanguagePackInstalled' => 1, ); $this->Conn->doUpdate($fields_hash, $table_name, $id_field . ' = ' . $theme_id); } $this->_saveThemeSettings($theme_id, $theme_path); return $theme_id; } /** * Saves information from "/_install/theme.xml" files in theme * * @param int $theme_id * @param string $theme_path * @return void * @access protected */ protected function _saveThemeSettings($theme_id, $theme_path) { $config = $this->Application->getUnitConfig('theme'); $id_field = $config->getIDField(); $table_name = $config->getTableName(); $this->Conn->doUpdate($this->_getThemeSettings($theme_id, $theme_path), $table_name, $id_field . ' = ' . $theme_id); } /** * Installs module(-s) language pack for given theme * * @param string $theme_path * @param string|bool $module_name * @return void */ function installThemeLanguagePack($theme_path, $module_name = false) { if ( $module_name === false ) { $modules = $this->Application->ModuleInfo; } else { $modules = Array ($module_name => $this->Application->ModuleInfo[$module_name]); } $language_import_helper = $this->Application->recallObject('LanguageImportHelper'); /* @var $language_import_helper LanguageImportHelper */ foreach ($modules as $module_name => $module_info) { if ( $module_name == 'In-Portal' ) { continue; } $lang_file = $theme_path . '/' . $module_info['TemplatePath'] . '_install/english.lang'; if ( file_exists($lang_file) ) { $language_import_helper->performImport($lang_file, '|0|', ''); } } } /** * Parses information, discovered from "/_install/theme.xml" files in theme * * @param int $theme_id * @param string $theme_path * @return Array * @access protected */ protected function _getThemeSettings($theme_id, $theme_path) { $setting_mapping = Array ('image_resize_rules' => 'ImageResizeRules'); $ret = Array ('TemplateAliases' => Array (), 'ImageResizeRules' => Array ()); foreach ($this->Application->ModuleInfo as $module_name => $module_info) { $xml_file = $theme_path . '/' . $module_info['TemplatePath'] . '_install/theme.xml'; if ( $module_name == 'In-Portal' || !file_exists($xml_file) ) { continue; } $theme = simplexml_load_file($xml_file); if ( $theme === false ) { // broken xml OR no aliases defined continue; } foreach ($theme as $setting) { /* @var $setting SimpleXMLElement */ $setting_name = $setting->getName(); $setting_value = trim($setting); if ( isset($setting_mapping[$setting_name]) ) { $ret[$setting_mapping[$setting_name]][] = $setting_value; continue; } // this is template alias $module_override = (string)$setting['module']; if ( $module_override ) { // allow to put template mappings form all modules into single theme.xml file $module_folder = $this->Application->findModule('Name', $module_override, 'TemplatePath'); } else { // no module specified -> use module based on theme.xml file location $module_folder = $module_info['TemplatePath']; } // only store alias, when template exists on disk if ( $this->getTemplateId($setting_value, $theme_id) ) { $alias = '#' . $module_folder . strtolower($setting->getName()) . '#'; // remember alias in global theme mapping $ret['TemplateAliases'][$alias] = $setting_value; // store alias in theme file record to use later in design dropdown $this->updateTemplate($setting_value, $theme_id, Array ('TemplateAlias' => $alias)); } } } $ret['TemplateAliases'] = serialize($ret['TemplateAliases']); $ret['ImageResizeRules'] = implode("\n", array_filter($ret['ImageResizeRules'])); return $ret; } /** + * Returns theme configuration. + * + * @param string $theme_path Absolute path to theme. + * + * @return array + */ + protected function getConfiguration($theme_path) + { + $xml_file = $theme_path . '/_install/theme.xml'; + + if ( !file_exists($xml_file) ) { + return array(); + } + + $theme = simplexml_load_file($xml_file); + + if ( $theme === false ) { + // broken xml OR no aliases defined + return array(); + } + + $ret = array(); + + foreach ( $theme->attributes() as $name => $value ) { + $ret[(string)$name] = (string)$value; + } + + return $ret; + } + + /** * Returns ID of given physical template (relative to theme) given from ThemeFiles table * @param string $template_path * @param int $theme_id * @return int * @access public */ public function getTemplateId($template_path, $theme_id) { $template_path = $this->Application->getPhysicalTemplate($template_path); $sql = 'SELECT FileId FROM ' . TABLE_PREFIX . 'ThemeFiles WHERE ' . $this->getTemplateWhereClause($template_path, $theme_id); return $this->Conn->GetOne($sql); } /** * Updates template record with a given data * * @param string $template_path * @param int $theme_id * @param Array $fields_hash * @return void * @access public */ public function updateTemplate($template_path, $theme_id, $fields_hash) { $where_clause = $this->getTemplateWhereClause($template_path, $theme_id); $this->Conn->doUpdate($fields_hash, TABLE_PREFIX . 'ThemeFiles', $where_clause); } /** * Returns where clause to get associated record from ThemeFiles table for given template path * @param string $template_path * @param int $theme_id * @return string * @access protected */ protected function getTemplateWhereClause($template_path, $theme_id) { $folder = dirname($template_path); $where_clause = Array ( 'ThemeId = ' . $theme_id, 'FilePath = ' . $this->Conn->qstr($folder == '.' ? '' : '/' . $folder), 'FileName = ' . $this->Conn->qstr(basename($template_path) . '.tpl'), ); return '(' . implode(') AND (', $where_clause) . ')'; } /** * Installs given module language pack and refreshed it from all themes * * @param string $module_name */ function synchronizeModule($module_name) { $sql = 'SELECT `Name`, ThemeId FROM ' . TABLE_PREFIX . 'Themes'; $themes = $this->Conn->GetCol($sql, 'ThemeId'); if (!$themes) { return ; } foreach ($themes as $theme_id => $theme_name) { $theme_path = $this->themesFolder . '/' . $theme_name; // install language pack $this->installThemeLanguagePack($theme_path, $module_name); // update TemplateAliases mapping $this->_saveThemeSettings($theme_id, $theme_path); } } /** * Searches for new templates (missing in db) in specified folder * * @param string $folder_path subfolder of searchable theme * @param string $theme_path theme path from web server root * @param int $theme_id id of theme we are scanning * @param int $auto_structure_mode */ function FindThemeFiles($folder_path, $theme_path, $theme_id, $auto_structure_mode = 1) { $ignore_regexp = $this->getIgnoreRegexp($theme_path . $folder_path); $iterator = new DirectoryIterator($theme_path . $folder_path . '/'); /* @var $file_info DirectoryIterator */ foreach ($iterator as $file_info) { $filename = $file_info->getFilename(); $auto_structure = preg_match($ignore_regexp, $filename) ? 2 : $auto_structure_mode; $file_path = $folder_path . '/' . $filename; // don't pass path to theme top folder! if ( $file_info->isDir() && !$file_info->isDot() && $filename != 'CVS' && $filename != '.svn' ) { $this->FindThemeFiles($file_path, $theme_path, $theme_id, $auto_structure); } elseif ( pathinfo($filename, PATHINFO_EXTENSION) == 'tpl' ) { $meta_info = $this->_getTemplateMetaInfo(trim($file_path, '/'), $theme_id); $file_id = isset($this->themeFiles[$file_path]) ? $this->themeFiles[$file_path] : false; $file_description = array_key_exists('desc', $meta_info) ? $meta_info['desc'] : ''; if ($file_id) { // file was found in db & on hdd -> mark as existing $fields_hash = Array ( 'FileFound' => 1, 'Description' => $file_description, 'FileType' => $auto_structure, 'FileMetaInfo' => serialize($meta_info), ); $this->Conn->doUpdate($fields_hash, TABLE_PREFIX . 'ThemeFiles', 'FileId = ' . $file_id); } else { // file was found on hdd, but missing in db -> create new file record $fields_hash = Array ( 'ThemeId' => $theme_id, 'FileName' => $filename, 'FilePath' => $folder_path, 'Description' => $file_description, 'FileType' => $auto_structure, // 1 - built-in, 0 - custom (not in use right now), 2 - skipped in structure 'FileMetaInfo' => serialize($meta_info), 'FileFound' => 1, ); $this->Conn->doInsert($fields_hash, TABLE_PREFIX.'ThemeFiles'); $this->themeFiles[$file_path] = $this->Conn->getInsertID(); } // echo 'FilePath: ['.$folder_path.']; FileName: ['.$filename.']; IsNew: ['.($file_id > 0 ? 'NO' : 'YES').']
'; } } } /** * Returns single regular expression to match all ignore patters, that are valid for given folder * * @param string $folder_path * @return string */ protected function getIgnoreRegexp($folder_path) { // always ignore design and element templates $ignore = '\.des\.tpl$|\.elm\.tpl$'; $sms_ignore_file = $folder_path . '/.smsignore'; if ( file_exists($sms_ignore_file) ) { $manual_patterns = array_map('trim', file($sms_ignore_file)); foreach ($manual_patterns as $manual_pattern) { $ignore .= '|' . str_replace('/', '\\/', $manual_pattern); } } return '/' . $ignore . '/'; } /** * Returns template information (name, description, path) from it's header comment * * @param string $template * @param int $theme_id * @return Array */ function _getTemplateMetaInfo($template, $theme_id) { static $init_made = false; if (!$init_made) { $this->Application->InitParser(true); $init_made = true; } $template = 'theme:' . $this->_themeNames[$theme_id] . '/' . $template; $template_file = $this->Application->TemplatesCache->GetRealFilename($template); // ".tpl" was added before return $this->parseTemplateMetaInfo($template_file); } function parseTemplateMetaInfo($template_file) { if (!file_exists($template_file)) { // when template without info it's placed in top category return Array (); } $template_data = file_get_contents($template_file); if (substr($template_data, 0, 6) == '*/ $comment_end = strpos($template_data, '##-->'); if ($comment_end === false) { // badly formatted comment return Array (); } $comment = trim( substr($template_data, 6, $comment_end - 6) ); if (preg_match_all('/<(NAME|DESC|SECTION)>(.*?)<\/(NAME|DESC|SECTION)>/is', $comment, $regs)) { $ret = Array (); foreach ($regs[1] as $param_order => $param_name) { $ret[ strtolower($param_name) ] = trim($regs[2][$param_order]); } if (array_key_exists('section', $ret) && $ret['section']) { $category_path = explode('||', $ret['section']); $category_path = array_map('trim', $category_path); $ret['section'] = implode('||', $category_path); } return $ret; } } return Array (); } /** * Updates file system changes to database for all themes (including new ones) * */ function refreshThemes() { $themes_found = Array (); try { $iterator = new DirectoryIterator($this->themesFolder . '/'); /* @var $file_info DirectoryIterator */ foreach ($iterator as $file_info) { $filename = $file_info->getFilename(); if ( $file_info->isDir() && !$file_info->isDot() && $filename != '.svn' && $filename != 'CVS' ) { $theme_id = $this->refreshTheme($filename); if ( $theme_id ) { $themes_found[] = $theme_id; // increment serial of updated themes $this->Application->incrementCacheSerial('theme', $theme_id); } } } } catch ( UnexpectedValueException $e ) { } $config = $this->Application->getUnitConfig('theme'); $id_field = $config->getIDField(); $table_name = $config->getTableName(); // 1. only one theme found -> enable it and make primary /*if (count($themes_found) == 1) { $sql = 'UPDATE ' . $table_name . ' SET Enabled = 1, PrimaryTheme = 1 WHERE ' . $id_field . ' = ' . current($themes_found); $this->Conn->Query($sql); }*/ // 2. if none themes found -> delete all from db OR delete all except of found themes $sql = 'SELECT ' . $id_field . ' FROM ' . $table_name; if ( $themes_found ) { $sql .= ' WHERE ' . $id_field . ' NOT IN (' . implode(',', $themes_found) . ')'; } $theme_ids = $this->Conn->GetCol($sql); $this->deleteThemes($theme_ids); foreach ($theme_ids as $theme_id) { // increment serial of deleted themes $this->Application->incrementCacheSerial('theme', $theme_id); } $this->Application->incrementCacheSerial('theme'); $this->Application->incrementCacheSerial('theme-file'); $minify_helper = $this->Application->recallObject('MinifyHelper'); /* @var $minify_helper MinifyHelper */ $minify_helper->delete(); } /** * Deletes themes with ids passed from db * * @param Array $theme_ids */ function deleteThemes($theme_ids) { if (!$theme_ids) { return ; } $config = $this->Application->getUnitConfig('theme'); $id_field = $config->getIDField(); $sql = 'DELETE FROM '. $config->getTableName() .' WHERE '.$id_field.' IN ('.implode(',', $theme_ids).')'; $this->Conn->Query($sql); $sql = 'DELETE FROM '.TABLE_PREFIX.'ThemeFiles WHERE '.$id_field.' IN ('.implode(',', $theme_ids).')'; $this->Conn->Query($sql); } /** * Returns current theme (also works in admin) * * @return int */ function getCurrentThemeId() { static $theme_id = null; if (isset($theme_id)) { return $theme_id; } if ($this->Application->isAdmin) { // get theme, that user selected in catalog $theme_id = $this->Application->RecallVar('theme_id'); if ($theme_id === false) { // query, because "m_theme" is always empty in admin $config = $this->Application->getUnitConfig('theme'); $sql = 'SELECT ' . $config->getIDField() . ' FROM ' . $config->getTableName() . ' WHERE (PrimaryTheme = 1) AND (Enabled = 1)'; $theme_id = $this->Conn->GetOne($sql); } return $theme_id; } // use current theme, because it's available on Front-End $theme_id = $this->Application->GetVar('m_theme'); if (!$theme_id) { // happens in mod-rewrite mode, then requested template is not found $theme_id = $this->Application->GetDefaultThemeId(); } return $theme_id; } /** * Returns page id based on given template * * @param string $template * @param int $theme_id * @return int */ function getPageByTemplate($template, $theme_id = null) { if (!isset($theme_id)) { // during mod-rewrite url parsing current theme // is not available to kHTTPQuery class, so don't use it $theme_id = (int)$this->getCurrentThemeId(); } $template_crc = kUtil::crc32(mb_strtolower($template)); $categories_config = $this->Application->getUnitConfig('c'); $sql = 'SELECT ' . $categories_config->getIDField() . ' FROM ' . $categories_config->getTableName() . ' WHERE ( (NamedParentPathHash = ' . $template_crc . ') OR (`Type` = ' . PAGE_TYPE_TEMPLATE . ' AND CachedTemplateHash = ' . $template_crc . ') ) AND (ThemeId = ' . $theme_id . ($theme_id > 0 ? ' OR ThemeId = 0' : '') . ')'; return $this->Conn->GetOne($sql); } - } \ No newline at end of file + } Index: branches/5.3.x/core/units/fck/fck_eh.php =================================================================== --- branches/5.3.x/core/units/fck/fck_eh.php (revision 16123) +++ branches/5.3.x/core/units/fck/fck_eh.php (revision 16124) @@ -1,254 +1,257 @@ Array ('self' => true), ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * Checks user permission to execute given $event * * @param kEvent $event * @return bool * @access public */ public function CheckPermission(kEvent $event) { if ( $this->Application->isAdminUser || $event->Name == 'OnGetsEditorStyles' ) { // this limits all event execution only to logged-in users in admin return true; } return parent::CheckPermission($event); } function CreateXmlHeader() { ob_end_clean() ; // Prevent the browser from caching the result. // Date in the past header('Expires: Mon, 26 Jul 1997 05:00:00 GMT') ; // always modified header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT') ; // HTTP/1.1 header('Cache-Control: no-store, no-cache, must-revalidate') ; header('Cache-Control: post-check=0, pre-check=0', false) ; // HTTP/1.0 header('Pragma: no-cache') ; // Set the response format. $this->Application->setContentType('text/xml'); // Create the XML document header. } function OnLoadCmsTree($event) { $event->status = kEvent::erSTOP; $category_helper = $this->Application->recallObject('CategoryHelper'); /* @var $category_helper CategoryHelper */ $pages = $category_helper->getStructureTreeAsOptions(); $sql = 'SELECT NamedParentPath, CategoryId FROM ' . TABLE_PREFIX . 'Categories WHERE CategoryId IN (' . implode(',', array_keys($pages)) . ')'; $templates = $this->Conn->GetCol($sql, 'CategoryId'); $templates[$this->Application->getBaseCategory()] .= '/Index'; // "Content" category will act as "Home Page" $res = '' . "\n"; $res .= '' . "\n"; foreach ($pages as $id => $title) { $template = $templates[$id]; $page_path = preg_replace('/^Content\//i', '', strtolower($template).'.html'); $title = $title . ' (' . $page_path . ')'; $real_url = $this->Application->HREF($template, '_FRONT_END_', array('pass' => 'm'), 'index.php'); $res .= '' . "\n"; } $res.= ""; $this->CreateXmlHeader(); echo $res; } function OnRenameFile($event) { $event->status = kEvent::erSTOP; if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { return; } $old_name = $this->Application->GetVar('old_name'); $new_name = $this->Application->GetVar('new_name'); $folder = $this->Application->GetVar('folder'); $sServerDir = WRITEABLE . '/user_files/' . $folder . '/'; if (!file_exists($sServerDir.$old_name) || !is_file($sServerDir.$old_name)) { echo 204; return; } $fck_helper = $this->Application->recallObject('FCKHelper'); /* @var $fck_helper fckFCKHelper*/ if ( !$fck_helper->IsAllowedExtension($folder, $new_name) ) { echo 203; return; } if ( !rename($sServerDir . $old_name, $sServerDir . $new_name) ) { // echo $sServerDir.$old_name.' -> '.$sServerDir.$new_name; echo 205; return; } echo '0'; } function OnDeleteFiles($event) { $event->status = kEvent::erSTOP; if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { return; } $files = trim($this->Application->GetVar('files'),'|'); // echo $files; $a_files = explode('|', $files); $folder = $this->Application->GetVar('folder'); $sServerDir = WRITEABLE . '/user_files/' . $folder . '/'; foreach ($a_files AS $file) { @unlink($sServerDir.$file); } // print_r($a_files); } function OnGetFoldersFilesList($event) { $this->CreateXmlHeader(); $fck_helper = $this->Application->recallObject('FCKHelper'); /* @var $fck_helper fckFCKHelper */ $ret = ''."\n" ; $ret .= ""."\n"; $ret .= $fck_helper->PrintFolders(); $ret .= $fck_helper->PrintFiles(); $ret .= ""."\n"; echo $ret; exit; } function OnCreateFolder($event) { $event->status = kEvent::erSTOP; if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { return; } $new_folder = $this->Application->GetVar('new_folder'); $current_folder = $this->Application->GetVar('current_folder'); $folderPath = WRITEABLE . '/user_files' . '/' . $current_folder . "/" . $new_folder; if ( file_exists( $folderPath ) && is_dir($folderPath)) { echo "101"; } if ( !file_exists( $folderPath ) ) { // Turn off all error reporting. error_reporting( 0 ) ; // Enable error tracking to catch the error. ini_set( 'track_errors', '1' ) ; // To create the folder with 0777 permissions, we need to set umask to zero. $oldumask = umask(0) ; mkdir( $folderPath, 0777 ) ; umask( $oldumask ) ; $sErrorMsg = $php_errormsg ; // Restore the configurations. ini_restore( 'track_errors' ) ; ini_restore( 'error_reporting' ) ; if ($sErrorMsg) echo $sErrorMsg ; else echo '0'; } } /** * Uploads a file from FCK file browser * * @param kEvent $event * @return void * @access protected */ protected function OnUploadFile(kEvent $event) { $event->status = kEvent::erSTOP; if ( $this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) ) { return; } $fck_helper = $this->Application->recallObject('FCKHelper'); /* @var $fck_helper fckFCKHelper*/ $fck_helper->UploadFile(); } /** * Returns compressed CSS file * * @param kEvent $event */ function OnGetsEditorStyles($event) { + /** @var ThemeItem $theme */ + $theme = $this->Application->recallObject('theme.current'); + + /** @var MinifyHelper $minify_helper */ $minify_helper = $this->Application->recallObject('MinifyHelper'); - /* @var $minify_helper MinifyHelper */ $this->Application->InitParser(); - $styles_css = $minify_helper->CompressScriptTag( Array ('files' => 'inc/style.css') ); + $styles_css = $minify_helper->CompressScriptTag(array('files' => $theme->getStylesheetFile(true))); $event->redirect = 'external:' . $styles_css; } - } \ No newline at end of file + } Index: branches/5.3.x/core/units/category_items/category_items_event_handler.php =================================================================== --- branches/5.3.x/core/units/category_items/category_items_event_handler.php (revision 16123) +++ branches/5.3.x/core/units/category_items/category_items_event_handler.php (revision 16124) @@ -1,135 +1,135 @@ getObject(); /* @var $object kDBList */ $ml_formatter = $this->Application->recallObject('kMultiLanguage'); /* @var $ml_formatter kMultiLanguage */ $object->addCalculatedField('CategoryName', 'c.' . $ml_formatter->LangFieldName('CachedNavbar')); } /** * Set's new category as primary for product * * @param kEvent $event */ function OnSetPrimary($event) { $object = $event->getObject(Array ('skip_autoload' => true)); /* @var $object kDBItem */ $ids = $this->StoreSelectedIDs($event); if ( $ids ) { $id = array_shift($ids); $table_info = $object->getLinkedInfo(); $this->Conn->Query('UPDATE ' . $object->TableName . ' SET PrimaryCat = 0 WHERE ' . $table_info['ForeignKey'] . ' = ' . $table_info['ParentId']); $this->Conn->Query('UPDATE ' . $object->TableName . ' SET PrimaryCat = 1 WHERE (' . $table_info['ForeignKey'] . ' = ' . $table_info['ParentId'] . ') AND (Id = ' . $id . ')'); } $event->SetRedirectParam('opener', 's'); } /** * Removes primary mark from cloned category items record * * @param kEvent $event * @return void * @access protected */ protected function OnAfterClone(kEvent $event) { parent::OnAfterClone($event); $config = $event->getUnitConfig(); $sql = 'UPDATE ' . $config->getTableName() . ' SET PrimaryCat = 0 WHERE ' . $config->getIDField() . ' = ' . $event->getEventParam('id'); $this->Conn->Query($sql); } /** * Deletes items of requested type from requested categories. * In case if item is deleted from it's last category, then delete item too. * * @param kEvent $event * @return void * @access protected */ protected function OnDeleteFromCategory($event) { $category_ids = $event->getEventParam('category_ids'); if ( !$category_ids ) { return ; } $item_prefix = $event->getEventParam('item_prefix'); $item = $this->Application->recallObject($item_prefix . '.-item', null, Array ('skip_autoload' => true)); /* @var $item kCatDBItem */ $ci_table = $event->getUnitConfig()->getTableName(); $item_table = $this->Application->getUnitConfig($item_prefix)->getTableName(); $sql = 'SELECT ItemResourceId, CategoryId FROM %1$s INNER JOIN %2$s ON (%1$s.ResourceId = %2$s.ItemResourceId) WHERE CategoryId IN (%3$s)'; $category_items = $this->Conn->Query( sprintf($sql, $item_table, $ci_table, implode(',', $category_ids)) ); $item_hash = Array (); foreach ($category_items as $ci_row) { $item_hash[ $ci_row['ItemResourceId'] ][] = $ci_row['CategoryId']; } foreach ($item_hash as $item_resource_id => $delete_category_ids) { $item->Load($item_resource_id, 'ResourceId'); $item->DeleteFromCategories($delete_category_ids); } } /** * Makes sure, that parent category item is loaded when coping back from temp table * * @param kEvent $event * * @return void * @see CategoryItems_DBItem::GetKeyClause() */ protected function OnAfterCopyToLive(kEvent $event) { // don't call parent, because it's unclear how from here we can get parent item's ID here } } \ No newline at end of file Index: branches/5.3.x/core/units/category_items/category_items_config.php =================================================================== --- branches/5.3.x/core/units/category_items/category_items_config.php (revision 16123) +++ branches/5.3.x/core/units/category_items/category_items_config.php (revision 16124) @@ -1,86 +1,86 @@ 'ci', 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), - 'EventHandlerClass' => Array ('class' => 'CategoryItemsEventHander', 'file' => 'category_items_event_handler.php', 'build_event' => 'OnBuild'), + 'EventHandlerClass' => Array ('class' => 'CategoryItemsEventHandler', 'file' => 'category_items_event_handler.php', 'build_event' => 'OnBuild'), 'TagProcessorClass' => Array ('class' => 'CategoryItemsTagProcessor', 'file' => 'category_items_tag_processor.php', 'build_event' => 'OnBuild'), 'AutoLoad' => true, 'QueryString' => Array ( 1 => 'id', 2 => 'Page', 3 => 'PerPage', 4 => 'event', ), 'IDField' => 'Id', 'StatusField' => Array ('PrimaryCat'), // field, that is affected by Approve/Decline events 'TableName' => TABLE_PREFIX.'CategoryItems', 'ParentTableKey'=> 'ResourceId', 'ForeignKey' => 'ItemResourceId', // 'ParentPrefix' => 'p', 'AutoDelete' => true, 'AutoClone' => false, 'CalculatedFields' => Array ( '' => Array ( 'CategoryStatus'=> 'c.Status', ) ), 'ListSQLs' => Array ( '' => ' SELECT %1$s.* %2$s FROM %1$s LEFT JOIN '.TABLE_PREFIX.'Categories AS c ON c.CategoryId = %1$s.CategoryId', ), 'ListSortings' => Array ( '' => Array ( 'Sorting' => Array ('CategoryName' => 'asc'), ) ), 'Fields' => Array ( 'Id' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), 'CategoryId' => Array ('type' => 'int', 'not_null'=>1,'default'=>0), 'ItemResourceId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), 'PrimaryCat' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), 'ItemPrefix' => Array ('type' => 'string', 'not_null'=>1,'default' => ''), 'Filename' => Array ('type' => 'string', 'not_null'=>1,'default' => ''), ), 'VirtualFields' => Array ( 'CategoryName' => Array ('type' => 'string', 'default' => ''), 'CategoryStatus' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Active', 2 => 'la_Pending', 0 => 'la_Disabled' ), 'use_phrases' => 1, 'default' => 1), ), 'Grids' => Array ( 'Default' => Array ( 'Icons' => Array ( 'default' => 'icon16_item.png', 0 => 'icon16_item.png', 1 => 'icon16_primary.png', ), 'Fields' => Array ( 'CategoryName' => Array ( 'title' => 'column:la_fld_Category', 'data_block' => 'grid_checkbox_category_td'), ), ), ), ); \ No newline at end of file Index: branches/5.3.x/core/units/languages/languages_event_handler.php =================================================================== --- branches/5.3.x/core/units/languages/languages_event_handler.php (revision 16123) +++ branches/5.3.x/core/units/languages/languages_event_handler.php (revision 16124) @@ -1,796 +1,823 @@ Array ('self' => true), 'OnSetPrimary' => Array ('self' => 'advanced:set_primary|add|edit'), 'OnImportLanguage' => Array ('self' => 'advanced:import'), 'OnExportLanguage' => Array ('self' => 'advanced:export'), 'OnExportProgress' => Array ('self' => 'advanced:export'), 'OnReflectMultiLingualFields' => Array ('self' => 'view'), 'OnSynchronizeLanguages' => Array ('self' => 'edit'), ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * Checks user permission to execute given $event * * @param kEvent $event * @return bool * @access public */ public function CheckPermission(kEvent $event) { if ( $event->Name == 'OnItemBuild' ) { // check permission without using $event->getSection(), // so first cache rebuild won't lead to "ldefault_Name" field being used return true; } return parent::CheckPermission($event); } /** + * Ensure, that current object is always taken from live table. + * + * @param kDBBase|kDBItem|kDBList $object Object. + * @param kEvent $event Event. + * + * @return void + */ + protected function dbBuild(&$object, kEvent $event) + { + if ( $event->Special == 'current' ) { + $event->setEventParam('live_table', true); + } + + parent::dbBuild($object, $event); + } + + /** * Allows to get primary language object * * @param kEvent $event * @return int * @access public */ public function getPassedID(kEvent $event) { if ( $event->Special == 'primary' ) { return $this->Application->GetDefaultLanguageId(); } + elseif ( $event->Special == 'current' ) { + $language_id = $this->Application->GetVar('m_lang'); + + if ( !$language_id ) { + $language_id = 'default'; + } + + $this->Application->SetVar('m_lang', $language_id); + $this->Application->SetVar($event->getPrefixSpecial() . '_id', $language_id); + } return parent::getPassedID($event); } /** * [HOOK] Updates table structure on new language adding/removing language * * @param kEvent $event */ function OnReflectMultiLingualFields($event) { if ($this->Application->GetVar('ajax') == 'yes') { $event->status = kEvent::erSTOP; } if (is_object($event->MasterEvent)) { if ($event->MasterEvent->status != kEvent::erSUCCESS) { // only rebuild when all fields are validated return ; } if (($event->MasterEvent->Name == 'OnSave') && !$this->Application->GetVar('new_language')) { // only rebuild during new language adding return ; } } $ml_helper = $this->Application->recallObject('kMultiLanguageHelper'); /* @var $ml_helper kMultiLanguageHelper */ $ml_helper->massCreateFields(); $event->SetRedirectParam('action_completed', 1); } /** * Allows to set selected language as primary * * @param kEvent $event */ function OnSetPrimary($event) { if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { $event->status = kEvent::erFAIL; return; } $this->StoreSelectedIDs($event); $ids = $this->getSelectedIDs($event); if ($ids) { $id = array_shift($ids); $object = $event->getObject( Array('skip_autoload' => true) ); /* @var $object LanguagesItem */ $object->Load($id); $object->copyMissingData( $object->setPrimary() ); } } /** * [HOOK] Reset primary status of other languages if we are saving primary language * * @param kEvent $event */ function OnUpdatePrimary($event) { if ($event->MasterEvent->status != kEvent::erSUCCESS) { return ; } $object = $event->getObject( Array('skip_autoload' => true) ); /* @var $object LanguagesItem */ $object->SwitchToLive(); // set primary for each languages, that have this checkbox checked $ids = explode(',', $event->MasterEvent->getEventParam('ids')); foreach ($ids as $id) { $object->Load($id); if ($object->GetDBField('PrimaryLang')) { $object->copyMissingData( $object->setPrimary(true, false) ); } if ($object->GetDBField('AdminInterfaceLang')) { $object->setPrimary(true, true); } } // if no primary language left, then set primary last language (not to load again) from edited list $sql = 'SELECT '.$object->IDField.' FROM '.$object->TableName.' WHERE PrimaryLang = 1'; $primary_language = $this->Conn->GetOne($sql); if (!$primary_language) { $object->setPrimary(false, false); // set primary language } $sql = 'SELECT '.$object->IDField.' FROM '.$object->TableName.' WHERE AdminInterfaceLang = 1'; $primary_language = $this->Conn->GetOne($sql); if (!$primary_language) { $object->setPrimary(false, true); // set admin interface language } } /** * Prefills options with dynamic values * * @param kEvent $event * @return void * @access protected */ protected function OnAfterConfigRead(kEvent $event) { parent::OnAfterConfigRead($event); $this->_evaluateFieldFormats($event, 'InputDateFormat'); $this->_evaluateFieldFormats($event, 'InputTimeFormat'); } /** * Set dynamic hints for options in date format fields * * @param kEvent $event * @param string $field * @return void * @access protected */ protected function _evaluateFieldFormats(kEvent $event, $field) { $config = $event->getUnitConfig(); $field_options = $config->getFieldByName($field); foreach ($field_options['options'] as $option_key => $option_title) { $field_options['options'][$option_key] .= ' (' . date($option_key) . ')'; } $config->addFields($field_options, $field); } /** * Occurs before creating item * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemCreate(kEvent $event) { parent::OnBeforeItemCreate($event); $this->_itemChanged($event); } /** * Occurs before updating item * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemUpdate(kEvent $event) { parent::OnBeforeItemUpdate($event); $object = $event->getObject(); /* @var $object kDBItem */ $status_field = $event->getUnitConfig()->getStatusField(true); if ( $object->GetDBField('PrimaryLang') == 1 && $object->GetDBField($status_field) == 0 ) { $object->SetDBField($status_field, 1); } $this->_itemChanged($event); } /** * Dynamically changes required fields * * @param kEvent $event * @return void * @access protected */ protected function _itemChanged(kEvent $event) { $this->setRequired($event); } /** * Dynamically changes required fields * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemValidate(kEvent $event) { parent::OnBeforeItemValidate($event); $object = $event->getObject(); /* @var $object kDBItem */ $email_template_helper = $this->Application->recallObject('kEmailTemplateHelper'); /* @var $email_template_helper kEmailTemplateHelper */ $email_template_helper->parseField($object, 'HtmlEmailTemplate'); $email_template_helper->parseField($object, 'TextEmailTemplate'); $check_field = $object->GetDBField('TextEmailTemplate') ? 'TextEmailTemplate' : 'HtmlEmailTemplate'; $check_value = $object->GetDBField($check_field); if ( $check_value && strpos($check_value, '$body') === false ) { $object->SetError($check_field, 'body_missing'); } } /** * Dynamically changes required fields * * @param kEvent $event * @return void * @access protected */ protected function setRequired(kEvent $event) { $object = $event->getObject(); /* @var $object kDBItem */ $object->setRequired('HtmlEmailTemplate', !$object->GetDBField('TextEmailTemplate')); $object->setRequired('TextEmailTemplate', !$object->GetDBField('HtmlEmailTemplate')); } /** * Shows only enabled languages on front * * @param kEvent $event * @return void * @access protected * @see kDBEventHandler::OnListBuild() */ protected function SetCustomQuery(kEvent $event) { parent::SetCustomQuery($event); $object = $event->getObject(); /* @var $object kDBList */ if ( in_array($event->Special, Array ('enabled', 'selected', 'available')) ) { $object->addFilter('enabled_filter', '%1$s.Enabled = ' . STATUS_ACTIVE); } // site domain language picker if ( $event->Special == 'selected' || $event->Special == 'available' ) { $edit_picker_helper = $this->Application->recallObject('EditPickerHelper'); /* @var $edit_picker_helper EditPickerHelper */ $edit_picker_helper->applyFilter($event, 'Languages'); } // apply domain-based language filtering $languages = $this->Application->siteDomainField('Languages'); if ( strlen($languages) ) { $languages = explode('|', substr($languages, 1, -1)); $object->addFilter('domain_filter', '%1$s.LanguageId IN (' . implode(',', $languages) . ')'); } } /** * Copy labels from another language * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemCreate(kEvent $event) { parent::OnAfterItemCreate($event); $object = $event->getObject(); /* @var $object kDBItem */ $src_language = $object->GetDBField('CopyFromLanguage'); if ( $object->GetDBField('CopyLabels') && $src_language ) { $dst_language = $object->GetID(); // 1. schedule data copy after OnSave event is executed $var_name = $event->getPrefixSpecial() . '_copy_data' . $this->Application->GetVar('m_wid'); $pending_actions = $this->Application->RecallVar($var_name, Array ()); if ( $pending_actions ) { $pending_actions = unserialize($pending_actions); } $pending_actions[$src_language] = $dst_language; $this->Application->StoreVar($var_name, serialize($pending_actions)); $object->SetDBField('CopyLabels', 0); } } /** * Saves language from temp table to live * * @param kEvent $event * @return void * @access protected */ protected function OnSave(kEvent $event) { parent::OnSave($event); if ( $event->status != kEvent::erSUCCESS ) { return; } $var_name = $event->getPrefixSpecial() . '_copy_data' . $this->Application->GetVar('m_wid'); $pending_actions = $this->Application->RecallVar($var_name, Array ()); if ( $pending_actions ) { $pending_actions = unserialize($pending_actions); } // create multilingual columns for phrases & email events table first (actual for 6+ language) $ml_helper = $this->Application->recallObject('kMultiLanguageHelper'); /* @var $ml_helper kMultiLanguageHelper */ $ml_helper->createFields('phrases'); $ml_helper->createFields('email-template'); foreach ($pending_actions as $src_language => $dst_language) { // phrases import $sql = 'UPDATE ' . $this->Application->getUnitConfig('phrases')->getTableName() . ' SET l' . $dst_language . '_Translation = l' . $src_language . '_Translation'; $this->Conn->Query($sql); // events import $sql = 'UPDATE ' . $this->Application->getUnitConfig('email-template')->getTableName() . ' SET l' . $dst_language . '_Subject = l' . $src_language . '_Subject, l' . $dst_language . '_HtmlBody = l' . $src_language . '_HtmlBody, l' . $dst_language . '_PlainTextBody = l' . $src_language . '_PlainTextBody'; $this->Conn->Query($sql); } $this->Application->RemoveVar($var_name); $event->CallSubEvent('OnReflectMultiLingualFields'); $event->CallSubEvent('OnUpdatePrimary'); } /** * Prepare temp tables for creating new item * but does not create it. Actual create is * done in OnPreSaveCreated * * @param kEvent $event * @return void * @access protected */ protected function OnPreCreate(kEvent $event) { parent::OnPreCreate($event); $object = $event->getObject(); /* @var $object kDBItem */ $object->SetDBField('CopyLabels', 1); $sql = 'SELECT ' . $object->IDField . ' FROM ' . $event->getUnitConfig()->getTableName() . ' WHERE PrimaryLang = 1'; $primary_lang_id = $this->Conn->GetOne($sql); $object->SetDBField('CopyFromLanguage', $primary_lang_id); $object->SetDBField('SynchronizationModes', Language::SYNCHRONIZE_DEFAULT); $this->setRequired($event); } /** * Sets dynamic required fields * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemLoad(kEvent $event) { parent::OnAfterItemLoad($event); $object = $event->getObject(); /* @var $object kDBItem */ $this->setRequired($event); } /** * Sets new language mark * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeDeleteFromLive(kEvent $event) { parent::OnBeforeDeleteFromLive($event); $config = $event->getUnitConfig(); $id_field = $config->getIDField(); $sql = 'SELECT ' . $id_field . ' FROM ' . $config->getTableName() . ' WHERE ' . $id_field . ' = ' . $event->getEventParam('id'); $id = $this->Conn->GetOne($sql); if ( !$id ) { $this->Application->SetVar('new_language', 1); } } function OnChangeLanguage($event) { $language_id = $this->Application->GetVar('language'); $language_field = $this->Application->isAdmin ? 'AdminLanguage' : 'FrontLanguage'; $this->Application->SetVar('m_lang', $language_id); // set new language for this session $this->Application->Session->SetField('Language', $language_id); // remember last user language if ($this->Application->RecallVar('user_id') == USER_ROOT) { $this->Application->StorePersistentVar($language_field, $language_id); } else { $object = $this->Application->recallObject('u.current'); /* @var $object kDBItem */ $object->SetDBField($language_field, $language_id); $object->Update(); } // without this language change in admin will cause erase of last remembered tree section $this->Application->SetVar('skip_last_template', 1); } /** * Parse language XML file into temp tables and redirect to progress bar screen * * @param kEvent $event */ function OnImportLanguage($event) { if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { $event->status = kEvent::erFAIL; return; } $items_info = $this->Application->GetVar('phrases_import'); if ($items_info) { list ($id, $field_values) = each($items_info); $object = $this->Application->recallObject('phrases.import', 'phrases', Array('skip_autoload' => true)); /* @var $object kDBItem */ $object->setID($id); $object->SetFieldsFromHash($field_values); $event->setEventParam('form_data', $field_values); if (!$object->Validate()) { $event->status = kEvent::erFAIL; return ; } $filename = $object->GetField('LangFile', 'full_path'); if (!filesize($filename)) { $object->SetError('LangFile', 'la_empty_file', 'la_EmptyFile'); $event->status = kEvent::erFAIL; } $language_import_helper = $this->Application->recallObject('LanguageImportHelper'); /* @var $language_import_helper LanguageImportHelper */ if ( $object->GetDBField('ImportOverwrite') ) { $language_import_helper->setOption(LanguageImportHelper::OVERWRITE_EXISTING); } if ( $object->GetDBField('ImportSynced') ) { $language_import_helper->setOption(LanguageImportHelper::SYNC_ADDED); } $language_import_helper->performImport($filename, $object->GetDBField('PhraseType'), $object->GetDBField('Module')); // delete uploaded language pack after import is finished unlink($filename); $event->SetRedirectParam('opener', 'u'); } } /** * Stores ids of selected languages and redirects to export language step 1 * * @param kEvent $event */ function OnExportLanguage($event) { if ( $this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) ) { $event->status = kEvent::erFAIL; return; } $this->Application->getUnitConfig('phrases')->setAutoLoad(false); $this->StoreSelectedIDs($event); $this->Application->StoreVar('export_language_ids', implode(',', $this->getSelectedIDs($event))); $event->setRedirectParams( Array ( 'phrases.export_event' => 'OnNew', 'pass' => 'all,phrases.export', 'export_mode' => $event->Prefix, ) ); } /** * Saves selected languages to xml file passed * * @param kEvent $event */ function OnExportProgress($event) { $items_info = $this->Application->GetVar('phrases_export'); if ( $items_info ) { list($id, $field_values) = each($items_info); $object = $this->Application->recallObject('phrases.export', null, Array ('skip_autoload' => true)); /* @var $object kDBItem */ $object->setID($id); $object->SetFieldsFromHash($field_values); $event->setEventParam('form_data', $field_values); if ( !$object->Validate() ) { $event->status = kEvent::erFAIL; return; } $file_helper = $this->Application->recallObject('FileHelper'); /* @var $file_helper FileHelper */ $file_helper->CheckFolder(EXPORT_PATH); if ( !is_writable(EXPORT_PATH) ) { $event->status = kEvent::erFAIL; $object->SetError('LangFile', 'write_error', 'la_ExportFolderNotWritable'); return; } if ( substr($field_values['LangFile'], -5) != '.lang' ) { $field_values['LangFile'] .= '.lang'; } $filename = EXPORT_PATH . '/' . $field_values['LangFile']; $language_import_helper = $this->Application->recallObject('LanguageImportHelper'); /* @var $language_import_helper LanguageImportHelper */ if ( $object->GetDBField('DoNotEncode') ) { $language_import_helper->setExportEncoding('plain'); } $data_types = Array ( 'phrases' => 'ExportPhrases', 'email-template' => 'ExportEmailTemplates', 'country-state' => 'ExportCountries' ); $export_mode = $this->Application->GetVar('export_mode'); $allowed_data_types = explode('|', substr($field_values['ExportDataTypes'], 1, -1)); if ( $export_mode == $event->Prefix ) { foreach ($data_types as $prefix => $export_limit_field) { $export_limit = in_array($prefix, $allowed_data_types) ? $field_values[$export_limit_field] : '-'; $language_import_helper->setExportLimit($prefix, $export_limit); } } else { foreach ($data_types as $prefix => $export_limit_field) { $export_limit = in_array($prefix, $allowed_data_types) ? null : '-'; $language_import_helper->setExportLimit($prefix, $export_limit); } } $lang_ids = explode(',', $this->Application->RecallVar('export_language_ids')); $language_import_helper->performExport($filename, $field_values['PhraseType'], $lang_ids, $field_values['Module']); } $event->redirect = 'regional/languages_export_step2'; $event->SetRedirectParam('export_file', $field_values['LangFile']); } /** * Returns to previous template in opener stack * * @param kEvent $event * @return void * @access protected */ protected function OnGoBack(kEvent $event) { $event->SetRedirectParam('opener', 'u'); } function OnScheduleTopFrameReload($event) { $this->Application->StoreVar('RefreshTopFrame',1); } /** * Do now allow deleting current language * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemDelete(kEvent $event) { parent::OnBeforeItemDelete($event); $object = $event->getObject(); /* @var $object kDBItem */ if ( $object->GetDBField('PrimaryLang') || $object->GetDBField('AdminInterfaceLang') || $object->GetID() == $this->Application->GetVar('m_lang') ) { $event->status = kEvent::erFAIL; } } /** * Deletes phrases and email events on given language * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemDelete(kEvent $event) { parent::OnAfterItemDelete($event); $object = $event->getObject(); /* @var $object kDBItem */ // clean EmailTemplates table $fields_hash = Array ( 'l' . $object->GetID() . '_Subject' => NULL, 'l' . $object->GetID() . '_HtmlBody' => NULL, 'l' . $object->GetID() . '_PlainTextBody' => NULL, ); $this->Conn->doUpdate($fields_hash, $this->Application->getUnitConfig('email-template')->getTableName(), 1); // clean Phrases table $fields_hash = Array ( 'l' . $object->GetID() . '_Translation' => NULL, 'l' . $object->GetID() . '_HintTranslation' => NULL, 'l' . $object->GetID() . '_ColumnTranslation' => NULL, ); $this->Conn->doUpdate($fields_hash, $this->Application->getUnitConfig('phrases')->getTableName(), 1); } /** * Copy missing phrases across all system languages (starting from primary) * * @param kEvent $event * @return void * @access protected */ protected function OnSynchronizeLanguages($event) { if ( $this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) ) { $event->status = kEvent::erFAIL; return; } $source_languages = $target_languages = Array (); // get language list with primary language first $sql = 'SELECT SynchronizationModes, LanguageId FROM ' . TABLE_PREFIX . 'Languages WHERE SynchronizationModes <> "" ORDER BY PrimaryLang DESC'; $languages = $this->Conn->GetCol($sql, 'LanguageId'); foreach ($languages as $language_id => $synchronization_modes) { $synchronization_modes = explode('|', substr($synchronization_modes, 1, -1)); if ( in_array(Language::SYNCHRONIZE_TO_OTHERS, $synchronization_modes) ) { $source_languages[] = $language_id; } if ( in_array(Language::SYNCHRONIZE_FROM_OTHERS, $synchronization_modes) ) { $target_languages[] = $language_id; } } foreach ($source_languages as $source_id) { foreach ($target_languages as $target_id) { if ( $source_id == $target_id ) { continue; } $sql = 'UPDATE ' . TABLE_PREFIX . 'LanguageLabels SET l' . $target_id . '_Translation = l' . $source_id . '_Translation WHERE COALESCE(l' . $target_id . '_Translation, "") = "" AND COALESCE(l' . $source_id . '_Translation, "") <> ""'; $this->Conn->Query($sql); } } } } Index: branches/5.3.x/core/admin_templates/themes/themes_edit.tpl =================================================================== --- branches/5.3.x/core/admin_templates/themes/themes_edit.tpl (revision 16123) +++ branches/5.3.x/core/admin_templates/themes/themes_edit.tpl (revision 16124) @@ -1,73 +1,75 @@
+ +
- \ No newline at end of file + Index: branches/5.3.x/core/install/install_schema.sql =================================================================== --- branches/5.3.x/core/install/install_schema.sql (revision 16123) +++ branches/5.3.x/core/install/install_schema.sql (revision 16124) @@ -1,1467 +1,1468 @@ CREATE TABLE CategoryPermissionsConfig ( PermissionConfigId int(11) NOT NULL auto_increment, PermissionName varchar(255) NOT NULL default '', Description varchar(255) NOT NULL default '', ModuleId varchar(20) NOT NULL default '0', IsSystem tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (PermissionConfigId), KEY PermissionName (PermissionName) ); CREATE TABLE Permissions ( PermissionId int(11) NOT NULL auto_increment, Permission varchar(255) NOT NULL default '', GroupId int(11) default '0', PermissionValue int(11) NOT NULL default '0', `Type` tinyint(4) NOT NULL default '0', CatId int(11) NOT NULL default '0', PRIMARY KEY (PermissionId), UNIQUE KEY PermIndex (Permission,GroupId,CatId,`Type`) ); CREATE TABLE CustomFields ( CustomFieldId int(11) NOT NULL auto_increment, `Type` int(11) NOT NULL default '0', FieldName varchar(255) NOT NULL default '', FieldLabel varchar(40) default NULL, MultiLingual tinyint(3) unsigned NOT NULL default '1', Heading varchar(60) default NULL, Prompt varchar(60) default NULL, ElementType varchar(50) NOT NULL default '', ValueList text, DefaultValue varchar(255) NOT NULL default '', DisplayOrder int(11) NOT NULL default '0', OnGeneralTab tinyint(4) NOT NULL default '0', IsSystem tinyint(3) unsigned NOT NULL default '0', IsRequired tinyint(3) unsigned NOT NULL default '0', PRIMARY KEY (CustomFieldId), KEY `Type` (`Type`), KEY MultiLingual (MultiLingual), KEY DisplayOrder (DisplayOrder), KEY OnGeneralTab (OnGeneralTab), KEY IsSystem (IsSystem), KEY DefaultValue (DefaultValue) ); CREATE TABLE SystemSettings ( VariableId int(11) NOT NULL AUTO_INCREMENT, VariableName varchar(255) NOT NULL DEFAULT '', VariableValue text, ModuleOwner varchar(20) DEFAULT 'In-Portal', Section varchar(255) NOT NULL DEFAULT '', Heading varchar(255) NOT NULL DEFAULT '', Prompt varchar(255) NOT NULL DEFAULT '', ElementType varchar(255) NOT NULL DEFAULT '', Validation text, ValueList text, DisplayOrder double NOT NULL DEFAULT '0', GroupDisplayOrder double NOT NULL DEFAULT '0', `Install` int(11) NOT NULL DEFAULT '1', HintLabel varchar(255) DEFAULT NULL, PRIMARY KEY (VariableId), UNIQUE KEY VariableName (VariableName), KEY DisplayOrder (DisplayOrder), KEY GroupDisplayOrder (GroupDisplayOrder), KEY `Install` (`Install`), KEY HintLabel (HintLabel) ); CREATE TABLE EmailQueue ( EmailQueueId int(10) unsigned NOT NULL AUTO_INCREMENT, ToEmail varchar(255) NOT NULL DEFAULT '', `Subject` varchar(255) NOT NULL DEFAULT '', MessageHeaders text, MessageBody longtext, Queued int(10) unsigned DEFAULT NULL, SendRetries int(10) unsigned NOT NULL DEFAULT '0', LastSendRetry int(10) unsigned DEFAULT NULL, MailingId int(10) unsigned NOT NULL DEFAULT '0', LogData longtext, PRIMARY KEY (EmailQueueId), KEY LastSendRetry (LastSendRetry), KEY SendRetries (SendRetries), KEY MailingId (MailingId) ); CREATE TABLE EmailTemplates ( TemplateId int(11) NOT NULL AUTO_INCREMENT, TemplateName varchar(40) NOT NULL DEFAULT '', ReplacementTags text, AllowChangingSender tinyint(4) NOT NULL DEFAULT '0', CustomSender tinyint(4) NOT NULL DEFAULT '0', SenderName varchar(255) NOT NULL DEFAULT '', SenderAddressType tinyint(4) NOT NULL DEFAULT '0', SenderAddress varchar(255) NOT NULL DEFAULT '', AllowChangingRecipient tinyint(4) NOT NULL DEFAULT '0', CustomRecipient tinyint(4) NOT NULL DEFAULT '0', Recipients text, l1_Subject text, l2_Subject text, l3_Subject text, l4_Subject text, l5_Subject text, l1_HtmlBody longtext, l2_HtmlBody longtext, l3_HtmlBody longtext, l4_HtmlBody longtext, l5_HtmlBody longtext, l1_PlainTextBody longtext, l2_PlainTextBody longtext, l3_PlainTextBody longtext, l4_PlainTextBody longtext, l5_PlainTextBody longtext, l1_TranslateFrom int(11) NOT NULL DEFAULT '0', l2_TranslateFrom int(11) NOT NULL DEFAULT '0', l3_TranslateFrom int(11) NOT NULL DEFAULT '0', l4_TranslateFrom int(11) NOT NULL DEFAULT '0', l5_TranslateFrom int(11) NOT NULL DEFAULT '0', Headers text, Enabled int(11) NOT NULL DEFAULT '1', FrontEndOnly tinyint(3) unsigned NOT NULL DEFAULT '0', Module varchar(40) NOT NULL DEFAULT 'Core', Description text, `Type` int(11) NOT NULL DEFAULT '0', LastChanged int(10) unsigned DEFAULT NULL, BindToSystemEvent varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (TemplateId), KEY `Type` (`Type`), KEY Enabled (Enabled), KEY `Event` (TemplateName), KEY FrontEndOnly (FrontEndOnly), KEY AllowChangingSender (AllowChangingSender), KEY CustomSender (CustomSender), KEY SenderAddressType (SenderAddressType), KEY AllowChangingRecipient (AllowChangingRecipient), KEY CustomRecipient (CustomRecipient), KEY l1_HtmlBody (l1_HtmlBody(5)), KEY l2_HtmlBody (l2_HtmlBody(5)), KEY l3_HtmlBody (l3_HtmlBody(5)), KEY l4_HtmlBody (l4_HtmlBody(5)), KEY l5_HtmlBody (l5_HtmlBody(5)), KEY l1_PlainTextBody (l1_PlainTextBody(5)), KEY l2_PlainTextBody (l2_PlainTextBody(5)), KEY l3_PlainTextBody (l3_PlainTextBody(5)), KEY l4_PlainTextBody (l4_PlainTextBody(5)), KEY l5_PlainTextBody (l5_PlainTextBody(5)), KEY l1_TranslateFrom (l1_TranslateFrom) ); CREATE TABLE SystemEventSubscriptions ( SubscriptionId int(11) NOT NULL AUTO_INCREMENT, EmailTemplateId int(11) DEFAULT NULL, SubscriberEmail varchar(255) NOT NULL DEFAULT '', UserId int(11) DEFAULT NULL, CategoryId int(11) DEFAULT NULL, IncludeSublevels tinyint(4) NOT NULL DEFAULT '1', ItemId int(11) DEFAULT NULL, ParentItemId int(11) DEFAULT NULL, SubscribedOn int(11) DEFAULT NULL, PRIMARY KEY (SubscriptionId), KEY EmailEventId (EmailTemplateId) ); CREATE TABLE IdGenerator ( lastid int(11) default NULL ); CREATE TABLE Languages ( LanguageId int(11) NOT NULL AUTO_INCREMENT, PackName varchar(40) NOT NULL DEFAULT '', LocalName varchar(40) NOT NULL DEFAULT '', Enabled int(11) NOT NULL DEFAULT '1', PrimaryLang int(11) NOT NULL DEFAULT '0', AdminInterfaceLang tinyint(3) unsigned NOT NULL DEFAULT '0', Priority int(11) NOT NULL DEFAULT '0', IconURL varchar(255) DEFAULT NULL, IconDisabledURL varchar(255) DEFAULT NULL, DateFormat varchar(50) NOT NULL DEFAULT 'm/d/Y', ShortDateFormat varchar(255) NOT NULL DEFAULT 'm/d', TimeFormat varchar(50) NOT NULL DEFAULT 'g:i:s A', ShortTimeFormat varchar(255) NOT NULL DEFAULT 'g:i A', InputDateFormat varchar(50) NOT NULL DEFAULT 'm/d/Y', InputTimeFormat varchar(50) NOT NULL DEFAULT 'g:i:s A', DecimalPoint varchar(10) NOT NULL DEFAULT '.', ThousandSep varchar(10) NOT NULL DEFAULT '', `Charset` varchar(20) NOT NULL DEFAULT 'utf-8', UnitSystem tinyint(4) NOT NULL DEFAULT '1', FilenameReplacements text, Locale varchar(10) NOT NULL DEFAULT 'en-US', UserDocsUrl varchar(255) NOT NULL DEFAULT '', SynchronizationModes varchar(255) NOT NULL DEFAULT '', HtmlEmailTemplate text, TextEmailTemplate text, PRIMARY KEY (LanguageId), KEY Enabled (Enabled), KEY PrimaryLang (PrimaryLang), KEY AdminInterfaceLang (AdminInterfaceLang), KEY Priority (Priority) ); CREATE TABLE Modules ( `Name` varchar(255) NOT NULL DEFAULT '', Path varchar(255) NOT NULL DEFAULT '', ClassNamespace varchar(255) NOT NULL DEFAULT '', Var varchar(100) NOT NULL DEFAULT '', Version varchar(10) NOT NULL DEFAULT '0.0.0', Loaded tinyint(4) NOT NULL DEFAULT '1', LoadOrder tinyint(4) NOT NULL DEFAULT '0', TemplatePath varchar(255) NOT NULL DEFAULT '', RootCat int(11) NOT NULL DEFAULT '0', BuildDate int(10) unsigned DEFAULT NULL, PRIMARY KEY (`Name`), KEY Loaded (Loaded), KEY LoadOrder (LoadOrder) ); CREATE TABLE ModuleDeploymentLog ( Id int(11) NOT NULL AUTO_INCREMENT, Module varchar(30) NOT NULL DEFAULT 'In-Portal', RevisionNumber int(11) NOT NULL DEFAULT '0', RevisionTitle varchar(255) NOT NULL DEFAULT '', CreatedOn int(10) unsigned DEFAULT NULL, IPAddress varchar(15) NOT NULL DEFAULT '', Output text, ErrorMessage varchar(255) NOT NULL DEFAULT '', Mode tinyint(1) NOT NULL DEFAULT '1', Status tinyint(1) NOT NULL DEFAULT '1', PRIMARY KEY (Id), KEY CreatedOn (CreatedOn), KEY Mode (Mode), KEY Status (Status) ); CREATE TABLE UserPersistentSessionData ( VariableId bigint(20) NOT NULL AUTO_INCREMENT, PortalUserId int(11) NOT NULL DEFAULT '0', VariableName varchar(255) NOT NULL DEFAULT '', VariableValue text, PRIMARY KEY (VariableId), KEY UserId (PortalUserId), KEY VariableName (VariableName) ); CREATE TABLE LanguageLabels ( PhraseId int(11) NOT NULL AUTO_INCREMENT, Phrase varchar(255) NOT NULL DEFAULT '', PhraseKey varchar(255) NOT NULL DEFAULT '', l1_Translation text, l2_Translation text, l3_Translation text, l4_Translation text, l5_Translation text, l1_HintTranslation text, l2_HintTranslation text, l3_HintTranslation text, l4_HintTranslation text, l5_HintTranslation text, l1_ColumnTranslation text, l2_ColumnTranslation text, l3_ColumnTranslation text, l4_ColumnTranslation text, l5_ColumnTranslation text, l1_TranslateFrom int(11) NOT NULL DEFAULT '0', l2_TranslateFrom int(11) NOT NULL DEFAULT '0', l3_TranslateFrom int(11) NOT NULL DEFAULT '0', l4_TranslateFrom int(11) NOT NULL DEFAULT '0', l5_TranslateFrom int(11) NOT NULL DEFAULT '0', PhraseType int(11) NOT NULL DEFAULT '0', LastChanged int(10) unsigned DEFAULT NULL, LastChangeIP varchar(15) NOT NULL DEFAULT '', Module varchar(30) NOT NULL DEFAULT 'In-Portal', PRIMARY KEY (PhraseId), KEY Phrase_Index (Phrase), KEY PhraseKey (PhraseKey), KEY l1_Translation (l1_Translation(5)), KEY l1_HintTranslation (l1_HintTranslation(5)), KEY l1_ColumnTranslation (l1_ColumnTranslation(5)), KEY l1_TranslateFrom (l1_TranslateFrom) ); CREATE TABLE PhraseCache ( Template varchar(40) NOT NULL DEFAULT '', PhraseList text, CacheDate int(11) NOT NULL DEFAULT '0', ThemeId int(11) NOT NULL DEFAULT '0', StylesheetId int(10) unsigned NOT NULL DEFAULT '0', ConfigVariables text, PRIMARY KEY (Template), KEY CacheDate (CacheDate), KEY ThemeId (ThemeId), KEY StylesheetId (StylesheetId) ); CREATE TABLE UserGroups ( GroupId int(11) NOT NULL AUTO_INCREMENT, `Name` varchar(255) NOT NULL DEFAULT '', Description varchar(255) DEFAULT NULL, CreatedOn int(10) unsigned DEFAULT NULL, System tinyint(4) NOT NULL DEFAULT '0', Personal tinyint(4) NOT NULL DEFAULT '0', Enabled tinyint(4) NOT NULL DEFAULT '1', FrontRegistration tinyint(3) unsigned NOT NULL DEFAULT '0', IPRestrictions text, PRIMARY KEY (GroupId), UNIQUE KEY `Name` (`Name`), KEY Personal (Personal), KEY Enabled (Enabled), KEY CreatedOn (CreatedOn) ); CREATE TABLE Users ( PortalUserId int(11) NOT NULL AUTO_INCREMENT, Username varchar(255) NOT NULL DEFAULT '', `Password` varchar(255) DEFAULT 'd41d8cd98f00b204e9800998ecf8427e', PasswordHashingMethod tinyint(4) NOT NULL DEFAULT '3', FirstName varchar(255) NOT NULL DEFAULT '', LastName varchar(255) NOT NULL DEFAULT '', Company varchar(255) NOT NULL DEFAULT '', Email varchar(255) NOT NULL DEFAULT '', PrevEmails text, CreatedOn int(11) DEFAULT NULL, Phone varchar(255) NOT NULL DEFAULT '', Fax varchar(255) NOT NULL DEFAULT '', Street varchar(255) NOT NULL DEFAULT '', Street2 varchar(255) NOT NULL DEFAULT '', City varchar(255) NOT NULL DEFAULT '', State varchar(20) NOT NULL DEFAULT '', Zip varchar(20) NOT NULL DEFAULT '', Country varchar(20) NOT NULL DEFAULT '', ResourceId int(11) NOT NULL DEFAULT '0', `Status` tinyint(4) NOT NULL DEFAULT '1', EmailVerified tinyint(4) NOT NULL, Modified int(11) DEFAULT NULL, dob int(11) DEFAULT NULL, TimeZone varchar(255) NOT NULL DEFAULT '', IPAddress varchar(15) NOT NULL DEFAULT '', IsBanned tinyint(1) NOT NULL DEFAULT '0', PwResetConfirm varchar(255) NOT NULL DEFAULT '', PwRequestTime int(11) unsigned DEFAULT NULL, FrontLanguage int(11) DEFAULT NULL, AdminLanguage int(11) DEFAULT NULL, DisplayToPublic text, UserType tinyint(4) NOT NULL, PrimaryGroupId int(11) DEFAULT NULL, OldStyleLogin tinyint(4) NOT NULL, IPRestrictions text, PRIMARY KEY (PortalUserId), UNIQUE KEY ResourceId (ResourceId), KEY CreatedOn (CreatedOn), KEY `Status` (`Status`), KEY Modified (Modified), KEY dob (dob), KEY IsBanned (IsBanned), KEY UserType (UserType), KEY Username (Username) ); CREATE TABLE UserCustomData ( CustomDataId int(11) NOT NULL auto_increment, ResourceId int(10) unsigned NOT NULL default '0', KEY ResourceId (ResourceId), PRIMARY KEY (CustomDataId) ); CREATE TABLE UserSessionData ( SessionKey varchar(50) NOT NULL DEFAULT '', VariableName varchar(255) NOT NULL DEFAULT '', VariableValue longtext, PRIMARY KEY (SessionKey,VariableName), KEY SessionKey (SessionKey), KEY VariableName (VariableName) ); CREATE TABLE Themes ( ThemeId int(11) NOT NULL AUTO_INCREMENT, `Name` varchar(40) NOT NULL DEFAULT '', Enabled int(11) NOT NULL DEFAULT '1', Description varchar(255) DEFAULT NULL, PrimaryTheme int(11) NOT NULL DEFAULT '0', CacheTimeout int(11) NOT NULL DEFAULT '0', StylesheetId int(10) unsigned NOT NULL DEFAULT '0', LanguagePackInstalled tinyint(3) unsigned NOT NULL DEFAULT '0', TemplateAliases text, + StylesheetFile varchar(255) NOT NULL DEFAULT '', ImageResizeRules text, PRIMARY KEY (ThemeId), KEY Enabled (Enabled), KEY StylesheetId (StylesheetId), KEY PrimaryTheme (PrimaryTheme), KEY LanguagePackInstalled (LanguagePackInstalled) ); CREATE TABLE ThemeFiles ( FileId int(11) NOT NULL AUTO_INCREMENT, ThemeId int(11) NOT NULL DEFAULT '0', FileName varchar(255) NOT NULL DEFAULT '', FilePath varchar(255) NOT NULL DEFAULT '', TemplateAlias varchar(255) NOT NULL DEFAULT '', Description varchar(255) DEFAULT NULL, FileType int(11) NOT NULL DEFAULT '0', FileFound tinyint(3) unsigned NOT NULL DEFAULT '0', FileMetaInfo text, PRIMARY KEY (FileId), KEY theme (ThemeId), KEY FileName (FileName), KEY FilePath (FilePath), KEY FileFound (FileFound), KEY TemplateAlias (TemplateAlias) ); CREATE TABLE UserGroupRelations ( Id int(11) NOT NULL auto_increment, PortalUserId int(11) NOT NULL DEFAULT '0', GroupId int(11) NOT NULL DEFAULT '0', MembershipExpires int(10) unsigned DEFAULT NULL, ExpirationReminderSent tinyint(4) NOT NULL DEFAULT '0', PRIMARY KEY (Id), UNIQUE KEY UserGroup (PortalUserId,GroupId), KEY GroupId (GroupId), KEY MembershipExpires (MembershipExpires), KEY ExpirationReminderSent (ExpirationReminderSent) ); CREATE TABLE UserSessions ( SessionKey int(10) unsigned NOT NULL DEFAULT '0', LastAccessed int(10) unsigned NOT NULL DEFAULT '0', PortalUserId int(11) NOT NULL DEFAULT '-2', `Language` int(11) NOT NULL DEFAULT '1', Theme int(11) NOT NULL DEFAULT '1', GroupId int(11) NOT NULL DEFAULT '0', IpAddress varchar(20) NOT NULL DEFAULT '0.0.0.0', `Status` int(11) NOT NULL DEFAULT '1', GroupList varchar(255) DEFAULT NULL, TimeZone varchar(255) NOT NULL DEFAULT '', BrowserSignature varchar(32) NOT NULL DEFAULT '', PRIMARY KEY (SessionKey), KEY UserId (PortalUserId), KEY LastAccessed (LastAccessed), KEY BrowserSignature (BrowserSignature) ); CREATE TABLE EmailLog ( EmailLogId int(11) NOT NULL AUTO_INCREMENT, `From` varchar(255) NOT NULL DEFAULT '', `To` varchar(255) NOT NULL DEFAULT '', OtherRecipients text, `Subject` varchar(255) NOT NULL DEFAULT '', HtmlBody longtext, TextBody longtext, `Status` tinyint(4) NOT NULL DEFAULT '1', ErrorMessage varchar(255) NOT NULL DEFAULT '', SentOn int(11) DEFAULT NULL, TemplateName varchar(255) NOT NULL DEFAULT '', EventType tinyint(4) DEFAULT NULL, EventParams text, AccessKey varchar(32) NOT NULL DEFAULT '', ToUserId int(11) DEFAULT NULL, ItemPrefix varchar(50) NOT NULL DEFAULT '', ItemId int(11) DEFAULT NULL, PRIMARY KEY (EmailLogId), KEY `timestamp` (SentOn) ); CREATE TABLE SystemLog ( LogId int(11) NOT NULL AUTO_INCREMENT, LogUniqueId int(11) DEFAULT NULL, LogLevel tinyint(4) NOT NULL DEFAULT '7', LogType tinyint(4) NOT NULL DEFAULT '3', LogCode int(11) DEFAULT NULL, LogMessage longtext, LogTimestamp int(11) DEFAULT NULL, LogDate datetime DEFAULT NULL, LogEventName varchar(100) NOT NULL DEFAULT '', LogHostname varchar(255) NOT NULL DEFAULT '', LogRequestSource tinyint(4) DEFAULT NULL, LogRequestURI varchar(255) NOT NULL DEFAULT '', LogRequestData longtext, LogUserId int(11) DEFAULT NULL, LogInterface tinyint(4) DEFAULT NULL, IpAddress varchar(15) NOT NULL DEFAULT '', LogSessionKey int(11) DEFAULT NULL, LogSessionData longtext, LogBacktrace longtext, LogSourceFilename varchar(255) NOT NULL DEFAULT '', LogSourceFileLine int(11) DEFAULT NULL, LogProcessId bigint(20) unsigned DEFAULT NULL, LogMemoryUsed bigint(20) unsigned NOT NULL, LogUserData longtext NOT NULL, LogNotificationStatus tinyint(4) NOT NULL DEFAULT '0', PRIMARY KEY (LogId), KEY LogLevel (LogLevel), KEY LogType (LogType), KEY LogNotificationStatus (LogNotificationStatus) ); CREATE TABLE SystemCache ( VarName varchar(255) NOT NULL default '', Data longtext, Cached int(11) default NULL, LifeTime int(11) NOT NULL default '-1', PRIMARY KEY (VarName), KEY Cached (Cached) ); CREATE TABLE CountryStates ( CountryStateId int(11) NOT NULL AUTO_INCREMENT, `Type` int(11) NOT NULL DEFAULT '1', StateCountryId int(11) DEFAULT NULL, l1_Name varchar(255) NOT NULL DEFAULT '', l2_Name varchar(255) NOT NULL DEFAULT '', l3_Name varchar(255) NOT NULL DEFAULT '', l4_Name varchar(255) NOT NULL DEFAULT '', l5_Name varchar(255) NOT NULL DEFAULT '', IsoCode char(3) NOT NULL DEFAULT '', ShortIsoCode char(2) DEFAULT NULL, PRIMARY KEY (CountryStateId), KEY `Type` (`Type`), KEY StateCountryId (StateCountryId), KEY l1_Name (l1_Name(5)) ); CREATE TABLE Categories ( CategoryId int(11) NOT NULL AUTO_INCREMENT, `Type` int(11) NOT NULL DEFAULT '1', SymLinkCategoryId int(10) unsigned DEFAULT NULL, ParentId int(11) NOT NULL DEFAULT '0', `Name` varchar(255) NOT NULL DEFAULT '', l1_Name varchar(255) NOT NULL DEFAULT '', l2_Name varchar(255) NOT NULL DEFAULT '', l3_Name varchar(255) NOT NULL DEFAULT '', l4_Name varchar(255) NOT NULL DEFAULT '', l5_Name varchar(255) NOT NULL DEFAULT '', Filename varchar(255) NOT NULL DEFAULT '', AutomaticFilename tinyint(3) unsigned NOT NULL DEFAULT '1', Description text, l1_Description text, l2_Description text, l3_Description text, l4_Description text, l5_Description text, CreatedOn int(11) DEFAULT NULL, EditorsPick tinyint(4) NOT NULL DEFAULT '0', `Status` tinyint(4) NOT NULL DEFAULT '1', Priority int(11) NOT NULL DEFAULT '0', MetaKeywords text, CachedDescendantCatsQty int(11) NOT NULL DEFAULT '0', CachedNavbar text, l1_CachedNavbar text, l2_CachedNavbar text, l3_CachedNavbar text, l4_CachedNavbar text, l5_CachedNavbar text, CreatedById int(11) DEFAULT NULL, ResourceId int(11) DEFAULT NULL, ParentPath text, TreeLeft bigint(20) NOT NULL DEFAULT '0', TreeRight bigint(20) NOT NULL DEFAULT '0', NamedParentPath text, NamedParentPathHash int(10) unsigned NOT NULL DEFAULT '0', MetaDescription text, HotItem int(11) NOT NULL DEFAULT '2', NewItem int(11) NOT NULL DEFAULT '2', PopItem int(11) NOT NULL DEFAULT '2', Modified int(11) DEFAULT NULL, ModifiedById int(11) DEFAULT NULL, CachedTemplate varchar(255) NOT NULL DEFAULT '', CachedTemplateHash int(10) unsigned NOT NULL DEFAULT '0', Template varchar(255) NOT NULL DEFAULT '#inherit#', UseExternalUrl tinyint(3) unsigned NOT NULL DEFAULT '0', ExternalUrl varchar(255) NOT NULL DEFAULT '', UseMenuIconUrl tinyint(3) unsigned NOT NULL DEFAULT '0', MenuIconUrl varchar(255) NOT NULL DEFAULT '', l1_Title varchar(255) DEFAULT '', l2_Title varchar(255) DEFAULT '', l3_Title varchar(255) DEFAULT '', l4_Title varchar(255) DEFAULT '', l5_Title varchar(255) DEFAULT '', l1_MenuTitle varchar(255) NOT NULL DEFAULT '', l2_MenuTitle varchar(255) NOT NULL DEFAULT '', l3_MenuTitle varchar(255) NOT NULL DEFAULT '', l4_MenuTitle varchar(255) NOT NULL DEFAULT '', l5_MenuTitle varchar(255) NOT NULL DEFAULT '', MetaTitle text, IndexTools text, IsMenu tinyint(4) NOT NULL DEFAULT '1', Protected tinyint(4) NOT NULL DEFAULT '0', FormId int(11) DEFAULT NULL, FormSubmittedTemplate varchar(255) DEFAULT NULL, FriendlyURL varchar(255) NOT NULL DEFAULT '', ThemeId int(10) unsigned NOT NULL DEFAULT '0', EnablePageCache tinyint(4) NOT NULL DEFAULT '0', OverridePageCacheKey tinyint(4) NOT NULL DEFAULT '0', PageCacheKey varchar(255) NOT NULL DEFAULT '', PageExpiration int(11) DEFAULT NULL, LiveRevisionNumber int(11) NOT NULL DEFAULT '1', DirectLinkEnabled tinyint(4) NOT NULL DEFAULT '1', DirectLinkAuthKey varchar(20) NOT NULL DEFAULT '', PromoBlockGroupId int(10) unsigned NOT NULL DEFAULT '0', RequireSSL tinyint(4) NOT NULL DEFAULT '0', RequireLogin tinyint(4) NOT NULL DEFAULT '0', PRIMARY KEY (CategoryId), UNIQUE KEY ResourceId (ResourceId), KEY ParentId (ParentId), KEY Modified (Modified), KEY Priority (Priority), KEY sorting (`Name`,Priority), KEY Filename (Filename(5)), KEY l1_Name (l1_Name(5)), KEY l2_Name (l2_Name(5)), KEY l3_Name (l3_Name(5)), KEY l4_Name (l4_Name(5)), KEY l5_Name (l5_Name(5)), KEY l1_Description (l1_Description(5)), KEY l2_Description (l2_Description(5)), KEY l3_Description (l3_Description(5)), KEY l4_Description (l4_Description(5)), KEY l5_Description (l5_Description(5)), KEY TreeLeft (TreeLeft), KEY TreeRight (TreeRight), KEY SymLinkCategoryId (SymLinkCategoryId), KEY `Status` (`Status`), KEY CreatedOn (CreatedOn), KEY EditorsPick (EditorsPick), KEY ThemeId (ThemeId), KEY EnablePageCache (EnablePageCache), KEY OverridePageCacheKey (OverridePageCacheKey), KEY PageExpiration (PageExpiration), KEY Protected (Protected), KEY LiveRevisionNumber (LiveRevisionNumber), KEY PromoBlockGroupId (PromoBlockGroupId), KEY NamedParentPathHash (NamedParentPathHash), KEY CachedTemplateHash (CachedTemplateHash) ); CREATE TABLE CategoryCustomData ( CustomDataId int(11) NOT NULL auto_increment, ResourceId int(10) unsigned NOT NULL default '0', KEY ResourceId (ResourceId), PRIMARY KEY (CustomDataId) ); CREATE TABLE CategoryItems ( Id int(11) NOT NULL auto_increment, CategoryId int(11) NOT NULL default '0', ItemResourceId int(11) NOT NULL default '0', PrimaryCat tinyint(4) NOT NULL default '0', ItemPrefix varchar(50) NOT NULL default '', Filename varchar(255) NOT NULL default '', PRIMARY KEY (Id), UNIQUE KEY CategoryId (CategoryId,ItemResourceId), KEY PrimaryCat (PrimaryCat), KEY ItemPrefix (ItemPrefix), KEY ItemResourceId (ItemResourceId), KEY Filename (Filename) ); CREATE TABLE CategoryPermissionsCache ( PermCacheId int(11) NOT NULL auto_increment, CategoryId int(11) NOT NULL default '0', PermId int(11) NOT NULL default '0', ACL varchar(255) NOT NULL default '', PRIMARY KEY (PermCacheId), KEY CategoryId (CategoryId), KEY PermId (PermId), KEY ACL (ACL) ); CREATE TABLE PopupSizes ( PopupId int(10) unsigned NOT NULL auto_increment, TemplateName varchar(255) NOT NULL default '', PopupWidth int(11) NOT NULL default '0', PopupHeight int(11) NOT NULL default '0', PRIMARY KEY (PopupId), KEY TemplateName (TemplateName) ); CREATE TABLE Counters ( CounterId int(10) unsigned NOT NULL auto_increment, Name varchar(100) NOT NULL default '', CountQuery text, CountValue text, LastCounted int(10) unsigned default NULL, LifeTime int(10) unsigned NOT NULL default '3600', IsClone tinyint(3) unsigned NOT NULL default '0', TablesAffected text, PRIMARY KEY (CounterId), UNIQUE KEY Name (Name), KEY IsClone (IsClone), KEY LifeTime (LifeTime), KEY LastCounted (LastCounted) ); CREATE TABLE AdminSkins ( SkinId int(11) NOT NULL AUTO_INCREMENT, `Name` varchar(255) DEFAULT NULL, CSS text, Logo varchar(255) DEFAULT NULL, LogoBottom varchar(255) NOT NULL DEFAULT '', LogoLogin varchar(255) NOT NULL DEFAULT '', `Options` text, LastCompiled int(11) NOT NULL DEFAULT '0', IsPrimary int(1) NOT NULL DEFAULT '0', DisplaySiteNameInHeader tinyint(1) NOT NULL DEFAULT '1', PRIMARY KEY (SkinId), KEY IsPrimary (IsPrimary), KEY LastCompiled (LastCompiled) ); CREATE TABLE ChangeLogs ( ChangeLogId bigint(20) NOT NULL AUTO_INCREMENT, PortalUserId int(11) NOT NULL DEFAULT '0', SessionLogId int(11) NOT NULL DEFAULT '0', `Action` tinyint(4) NOT NULL DEFAULT '0', OccuredOn int(11) DEFAULT NULL, Prefix varchar(255) NOT NULL DEFAULT '', ItemId bigint(20) NOT NULL DEFAULT '0', Changes text, MasterPrefix varchar(255) NOT NULL DEFAULT '', MasterId bigint(20) NOT NULL DEFAULT '0', PRIMARY KEY (ChangeLogId), KEY PortalUserId (PortalUserId), KEY SessionLogId (SessionLogId), KEY `Action` (`Action`), KEY OccuredOn (OccuredOn), KEY Prefix (Prefix), KEY MasterPrefix (MasterPrefix) ); CREATE TABLE UserSessionLogs ( SessionLogId bigint(20) NOT NULL AUTO_INCREMENT, PortalUserId int(11) NOT NULL DEFAULT '0', SessionId int(10) NOT NULL DEFAULT '0', `Status` tinyint(4) NOT NULL DEFAULT '1', SessionStart int(11) DEFAULT NULL, SessionEnd int(11) DEFAULT NULL, IP varchar(15) NOT NULL DEFAULT '', AffectedItems int(11) NOT NULL DEFAULT '0', PRIMARY KEY (SessionLogId), KEY SessionId (SessionId), KEY `Status` (`Status`), KEY PortalUserId (PortalUserId) ); CREATE TABLE StatisticsCapture ( StatisticsId int(10) unsigned NOT NULL auto_increment, TemplateName varchar(255) NOT NULL default '', Hits int(10) unsigned NOT NULL default '0', LastHit int(11) NOT NULL default '0', ScriptTimeMin decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', ScriptTimeAvg decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', ScriptTimeMax decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', SqlTimeMin decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', SqlTimeAvg decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', SqlTimeMax decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', SqlCountMin decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', SqlCountAvg decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', SqlCountMax decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', PRIMARY KEY (StatisticsId), KEY TemplateName (TemplateName), KEY Hits (Hits), KEY LastHit (LastHit), KEY ScriptTimeMin (ScriptTimeMin), KEY ScriptTimeAvg (ScriptTimeAvg), KEY ScriptTimeMax (ScriptTimeMax), KEY SqlTimeMin (SqlTimeMin), KEY SqlTimeAvg (SqlTimeAvg), KEY SqlTimeMax (SqlTimeMax), KEY SqlCountMin (SqlCountMin), KEY SqlCountAvg (SqlCountAvg), KEY SqlCountMax (SqlCountMax) ); CREATE TABLE SlowSqlCapture ( CaptureId int(10) unsigned NOT NULL AUTO_INCREMENT, TemplateNames text, Hits int(10) unsigned NOT NULL DEFAULT '0', LastHit int(11) NOT NULL DEFAULT '0', SqlQuery text, TimeMin decimal(40,20) unsigned NOT NULL DEFAULT '0.00000000000000000000', TimeAvg decimal(40,20) unsigned NOT NULL DEFAULT '0.00000000000000000000', TimeMax decimal(40,20) unsigned NOT NULL DEFAULT '0.00000000000000000000', QueryCrc bigint(11) NOT NULL DEFAULT '0', PRIMARY KEY (CaptureId), KEY Hits (Hits), KEY LastHit (LastHit), KEY TimeMin (TimeMin), KEY TimeAvg (TimeAvg), KEY TimeMax (TimeMax), KEY QueryCrc (QueryCrc) ); CREATE TABLE ScheduledTasks ( ScheduledTaskId int(11) NOT NULL AUTO_INCREMENT, `Name` varchar(255) NOT NULL DEFAULT '', `Type` tinyint(3) unsigned NOT NULL DEFAULT '1', `Status` tinyint(3) unsigned NOT NULL DEFAULT '1', `Event` varchar(255) NOT NULL DEFAULT '', RunSchedule varchar(255) NOT NULL DEFAULT '* * * * *', LastRunOn int(10) unsigned DEFAULT NULL, LastRunStatus tinyint(3) unsigned NOT NULL DEFAULT '1', NextRunOn int(11) DEFAULT NULL, RunTime int(10) unsigned NOT NULL DEFAULT '0', Timeout int(10) unsigned DEFAULT NULL, LastTimeoutOn int(10) unsigned DEFAULT NULL, SiteDomainLimitation varchar(255) NOT NULL DEFAULT '', Settings text, Module varchar(30) NOT NULL DEFAULT 'Core', PRIMARY KEY (ScheduledTaskId), KEY `Status` (`Status`), KEY LastRunOn (LastRunOn), KEY LastRunStatus (LastRunStatus), KEY RunTime (RunTime), KEY NextRunOn (NextRunOn), KEY SiteDomainLimitation (SiteDomainLimitation), KEY Timeout (Timeout), KEY `Type` (`Type`) ); CREATE TABLE SpellingDictionary ( SpellingDictionaryId int(11) NOT NULL auto_increment, MisspelledWord varchar(255) NOT NULL default '', SuggestedCorrection varchar(255) NOT NULL default '', PRIMARY KEY (SpellingDictionaryId), KEY MisspelledWord (MisspelledWord), KEY SuggestedCorrection (SuggestedCorrection) ); CREATE TABLE Thesaurus ( ThesaurusId int(11) NOT NULL auto_increment, SearchTerm varchar(255) NOT NULL default '', ThesaurusTerm varchar(255) NOT NULL default '', ThesaurusType tinyint(3) unsigned NOT NULL default '0', PRIMARY KEY (ThesaurusId), KEY ThesaurusType (ThesaurusType), KEY SearchTerm (SearchTerm) ); CREATE TABLE LocalesList ( LocaleId int(11) NOT NULL auto_increment, LocaleIdentifier varchar(6) NOT NULL default '', LocaleName varchar(255) NOT NULL default '', Locale varchar(20) NOT NULL default '', ScriptTag varchar(255) NOT NULL default '', ANSICodePage varchar(10) NOT NULL default '', PRIMARY KEY (LocaleId) ); CREATE TABLE UserBanRules ( RuleId int(11) NOT NULL auto_increment, RuleType tinyint(4) NOT NULL default '0', ItemField varchar(255) default NULL, ItemVerb tinyint(4) NOT NULL default '0', ItemValue varchar(255) NOT NULL default '', ItemType int(11) NOT NULL default '0', Priority int(11) NOT NULL default '0', Status tinyint(4) NOT NULL default '1', ErrorTag varchar(255) default NULL, PRIMARY KEY (RuleId), KEY Status (Status), KEY Priority (Priority), KEY ItemType (ItemType) ); CREATE TABLE CountCache ( ListType int(11) NOT NULL default '0', ItemType int(11) NOT NULL default '-1', Value int(11) NOT NULL default '0', CountCacheId int(11) NOT NULL auto_increment, LastUpdate int(11) NOT NULL default '0', ExtraId varchar(50) default NULL, TodayOnly tinyint(4) NOT NULL default '0', PRIMARY KEY (CountCacheId) ); CREATE TABLE UserFavorites ( FavoriteId int(11) NOT NULL auto_increment, PortalUserId int(11) NOT NULL default '0', ResourceId int(11) NOT NULL default '0', ItemTypeId int(11) NOT NULL default '0', Modified int(11) NOT NULL default '0', PRIMARY KEY (FavoriteId), UNIQUE KEY main (PortalUserId,ResourceId), KEY Modified (Modified), KEY ItemTypeId (ItemTypeId) ); CREATE TABLE CatalogImages ( ImageId int(11) NOT NULL auto_increment, ResourceId int(11) NOT NULL default '0', Url varchar(255) NOT NULL default '', Name varchar(255) NOT NULL default '', AltName VARCHAR(255) NOT NULL DEFAULT '', ImageIndex int(11) NOT NULL default '0', LocalImage tinyint(4) NOT NULL default '1', LocalPath varchar(240) NOT NULL default '', Enabled int(11) NOT NULL default '1', DefaultImg int(11) NOT NULL default '0', ThumbUrl varchar(255) default NULL, Priority int(11) NOT NULL default '0', ThumbPath varchar(255) default NULL, LocalThumb tinyint(4) NOT NULL default '1', SameImages tinyint(4) NOT NULL default '1', PRIMARY KEY (ImageId), KEY ResourceId (ResourceId), KEY Enabled (Enabled), KEY Priority (Priority) ); CREATE TABLE CatalogRatings ( RatingId int(11) NOT NULL auto_increment, IPAddress varchar(255) NOT NULL default '', CreatedOn INT UNSIGNED NULL DEFAULT NULL, RatingValue int(11) NOT NULL default '0', ItemId int(11) NOT NULL default '0', PRIMARY KEY (RatingId), KEY CreatedOn (CreatedOn), KEY ItemId (ItemId), KEY RatingValue (RatingValue) ); CREATE TABLE CatalogReviews ( ReviewId int(11) NOT NULL AUTO_INCREMENT, CreatedOn int(10) unsigned DEFAULT NULL, ReviewText longtext, Rating tinyint(3) unsigned NOT NULL DEFAULT '0', IPAddress varchar(255) NOT NULL DEFAULT '', ItemId int(11) NOT NULL DEFAULT '0', CreatedById int(11) DEFAULT NULL, ItemType tinyint(4) NOT NULL DEFAULT '0', Priority int(11) NOT NULL DEFAULT '0', `Status` tinyint(4) NOT NULL DEFAULT '2', TextFormat int(11) NOT NULL DEFAULT '0', Module varchar(255) NOT NULL DEFAULT '', HelpfulCount int(11) NOT NULL, NotHelpfulCount int(11) NOT NULL, PRIMARY KEY (ReviewId), KEY CreatedOn (CreatedOn), KEY ItemId (ItemId), KEY ItemType (ItemType), KEY Priority (Priority), KEY `Status` (`Status`) ); CREATE TABLE ItemFilters ( FilterId int(11) NOT NULL AUTO_INCREMENT, ItemPrefix varchar(255) NOT NULL DEFAULT '', FilterField varchar(255) NOT NULL DEFAULT '', FilterType varchar(100) NOT NULL DEFAULT '', Enabled tinyint(4) NOT NULL DEFAULT '1', RangeCount int(11) DEFAULT NULL, PRIMARY KEY (FilterId), KEY ItemPrefix (ItemPrefix), KEY Enabled (Enabled) ); CREATE TABLE SpamReports ( ReportId int(11) NOT NULL AUTO_INCREMENT, ItemPrefix varchar(255) NOT NULL DEFAULT '', ItemId int(11) NOT NULL, MessageText text, ReportedOn int(11) DEFAULT NULL, ReportedById int(11) DEFAULT NULL, PRIMARY KEY (ReportId), KEY ItemPrefix (ItemPrefix), KEY ItemId (ItemId), KEY ReportedById (ReportedById) ); CREATE TABLE ItemTypes ( ItemType int(11) NOT NULL default '0', Module varchar(50) NOT NULL default '', Prefix varchar(20) NOT NULL default '', SourceTable varchar(100) NOT NULL default '', TitleField varchar(50) default NULL, CreatorField varchar(255) NOT NULL default '', PopField varchar(255) default NULL, RateField varchar(255) default NULL, LangVar varchar(255) NOT NULL default '', PrimaryItem int(11) NOT NULL default '0', EditUrl varchar(255) NOT NULL default '', ClassName varchar(40) NOT NULL default '', ItemName varchar(50) NOT NULL default '', PRIMARY KEY (ItemType), KEY Module (Module) ); CREATE TABLE CatalogFiles ( FileId int(11) NOT NULL AUTO_INCREMENT, ResourceId int(11) unsigned NOT NULL DEFAULT '0', FileName varchar(255) NOT NULL DEFAULT '', FilePath varchar(255) NOT NULL DEFAULT '', Size int(11) NOT NULL DEFAULT '0', `Status` tinyint(4) NOT NULL DEFAULT '1', CreatedOn int(11) unsigned DEFAULT NULL, CreatedById int(11) DEFAULT NULL, MimeType varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (FileId), KEY ResourceId (ResourceId), KEY CreatedOn (CreatedOn), KEY `Status` (`Status`) ); CREATE TABLE CatalogRelationships ( RelationshipId int(11) NOT NULL auto_increment, SourceId int(11) default NULL, TargetId int(11) default NULL, SourceType tinyint(4) NOT NULL default '0', TargetType tinyint(4) NOT NULL default '0', Type int(11) NOT NULL default '0', Enabled int(11) NOT NULL default '1', Priority int(11) NOT NULL default '0', PRIMARY KEY (RelationshipId), KEY RelSource (SourceId), KEY RelTarget (TargetId), KEY `Type` (`Type`), KEY Enabled (Enabled), KEY Priority (Priority), KEY SourceType (SourceType), KEY TargetType (TargetType) ); CREATE TABLE SearchConfig ( TableName varchar(40) NOT NULL default '', FieldName varchar(40) NOT NULL default '', SimpleSearch tinyint(4) NOT NULL default '1', AdvancedSearch tinyint(4) NOT NULL default '1', Description varchar(255) default NULL, DisplayName varchar(80) default NULL, ModuleName VARCHAR(20) NOT NULL DEFAULT 'In-Portal', ConfigHeader varchar(255) default NULL, DisplayOrder int(11) NOT NULL default '0', SearchConfigId int(11) NOT NULL auto_increment, Priority int(11) NOT NULL default '0', FieldType varchar(20) NOT NULL default 'text', ForeignField TEXT, JoinClause TEXT, IsWhere text, IsNotWhere text, ContainsWhere text, NotContainsWhere text, CustomFieldId int(11) default NULL, PRIMARY KEY (SearchConfigId), KEY SimpleSearch (SimpleSearch), KEY AdvancedSearch (AdvancedSearch), KEY DisplayOrder (DisplayOrder), KEY Priority (Priority), KEY CustomFieldId (CustomFieldId) ); CREATE TABLE SearchLogs ( SearchLogId int(11) NOT NULL auto_increment, Keyword varchar(255) NOT NULL default '', Indices bigint(20) NOT NULL default '0', SearchType int(11) NOT NULL default '0', PRIMARY KEY (SearchLogId), KEY Keyword (Keyword), KEY SearchType (SearchType) ); CREATE TABLE SpamControl ( Id int(11) NOT NULL auto_increment, ItemResourceId int(11) NOT NULL default '0', IPaddress varchar(20) NOT NULL default '', Expire INT UNSIGNED NULL DEFAULT NULL, PortalUserId int(11) NOT NULL default '0', DataType varchar(20) default NULL, PRIMARY KEY (Id), KEY PortalUserId (PortalUserId), KEY Expire (Expire), KEY DataType (DataType), KEY ItemResourceId (ItemResourceId) ); CREATE TABLE StatItem ( StatItemId int(11) NOT NULL auto_increment, Module varchar(20) NOT NULL default '', ValueSQL varchar(255) default NULL, ResetSQL varchar(255) default NULL, ListLabel varchar(255) NOT NULL default '', Priority int(11) NOT NULL default '0', AdminSummary int(11) NOT NULL default '0', PRIMARY KEY (StatItemId), KEY AdminSummary (AdminSummary), KEY Priority (Priority) ); CREATE TABLE ImportScripts ( ImportId int(11) NOT NULL AUTO_INCREMENT, `Name` varchar(255) NOT NULL DEFAULT '', Description text, Prefix varchar(10) NOT NULL DEFAULT '', Module varchar(50) NOT NULL DEFAULT '', ExtraFields varchar(255) NOT NULL DEFAULT '', `Type` varchar(10) NOT NULL DEFAULT '', `Status` tinyint(4) NOT NULL DEFAULT '1', PRIMARY KEY (ImportId), KEY Module (Module), KEY `Status` (`Status`) ); CREATE TABLE UserVisits ( VisitId int(11) NOT NULL AUTO_INCREMENT, VisitDate int(10) unsigned DEFAULT NULL, Referer varchar(255) NOT NULL DEFAULT '', IPAddress varchar(15) NOT NULL DEFAULT '', AffiliateId int(10) unsigned NOT NULL DEFAULT '0', PortalUserId int(11) NOT NULL DEFAULT '-2', PRIMARY KEY (VisitId), KEY PortalUserId (PortalUserId), KEY AffiliateId (AffiliateId), KEY VisitDate (VisitDate) ); CREATE TABLE ImportCache ( CacheId int(11) NOT NULL AUTO_INCREMENT, CacheName varchar(255) NOT NULL DEFAULT '', VarName bigint(11) NOT NULL DEFAULT '0', VarValue text, PRIMARY KEY (CacheId), KEY CacheName (CacheName), KEY VarName (VarName) ); CREATE TABLE CategoryRelatedSearches ( RelatedSearchId int(11) NOT NULL auto_increment, ResourceId int(11) NOT NULL default '0', Keyword varchar(255) NOT NULL default '', ItemType tinyint(4) NOT NULL default '0', Enabled tinyint(4) NOT NULL default '1', Priority int(11) NOT NULL default '0', PRIMARY KEY (RelatedSearchId), KEY Enabled (Enabled), KEY ItemType (ItemType), KEY ResourceId (ResourceId) ); CREATE TABLE StopWords ( StopWordId int(11) NOT NULL auto_increment, StopWord varchar(255) NOT NULL default '', PRIMARY KEY (StopWordId), KEY StopWord (StopWord) ); CREATE TABLE MailingLists ( MailingId int(10) unsigned NOT NULL AUTO_INCREMENT, PortalUserId int(11) NOT NULL DEFAULT '-1', `To` longtext, ToParsed longtext, Attachments text, `Subject` varchar(255) NOT NULL DEFAULT '', MessageText longtext, MessageHtml longtext, `Status` tinyint(3) unsigned NOT NULL DEFAULT '1', EmailsQueuedTotal int(10) unsigned NOT NULL DEFAULT '0', EmailsSent int(10) unsigned NOT NULL DEFAULT '0', EmailsTotal int(10) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (MailingId), KEY EmailsTotal (EmailsTotal), KEY EmailsSent (EmailsSent), KEY EmailsQueued (EmailsQueuedTotal), KEY `Status` (`Status`), KEY PortalUserId (PortalUserId) ); CREATE TABLE PageContent ( PageContentId int(11) NOT NULL AUTO_INCREMENT, ContentNum bigint(11) NOT NULL DEFAULT '0', PageId int(11) NOT NULL DEFAULT '0', RevisionId int(11) NOT NULL, l1_Content text, l2_Content text, l3_Content text, l4_Content text, l5_Content text, PRIMARY KEY (PageContentId), KEY ContentNum (ContentNum,PageId), KEY RevisionId (RevisionId) ); CREATE TABLE PageRevisions ( RevisionId int(11) NOT NULL AUTO_INCREMENT, PageId int(11) NOT NULL, RevisionNumber int(11) NOT NULL, IsDraft tinyint(4) NOT NULL, FromRevisionId int(11) NOT NULL, CreatedById int(11) DEFAULT NULL, CreatedOn int(11) DEFAULT NULL, AutoSavedOn int(11) DEFAULT NULL, `Status` tinyint(4) NOT NULL DEFAULT '2', PRIMARY KEY (RevisionId), KEY PageId (PageId), KEY RevisionNumber (RevisionNumber), KEY IsDraft (IsDraft), KEY `Status` (`Status`) ); CREATE TABLE FormFields ( FormFieldId int(11) NOT NULL AUTO_INCREMENT, FormId int(11) NOT NULL DEFAULT '0', `Type` int(11) NOT NULL DEFAULT '0', FieldName varchar(255) NOT NULL DEFAULT '', FieldLabel varchar(255) DEFAULT NULL, Heading varchar(255) DEFAULT NULL, Prompt varchar(255) DEFAULT NULL, ElementType varchar(50) NOT NULL DEFAULT '', ValueList varchar(255) DEFAULT NULL, Priority int(11) NOT NULL DEFAULT '0', IsSystem tinyint(3) unsigned NOT NULL DEFAULT '0', Required tinyint(1) NOT NULL DEFAULT '0', DisplayInGrid tinyint(1) NOT NULL DEFAULT '1', DefaultValue text, Validation tinyint(4) NOT NULL DEFAULT '0', UploadExtensions varchar(255) NOT NULL DEFAULT '', UploadMaxSize int(11) DEFAULT NULL, Visibility tinyint(4) NOT NULL DEFAULT '1', EmailCommunicationRole tinyint(4) NOT NULL DEFAULT '0', PRIMARY KEY (FormFieldId), KEY `Type` (`Type`), KEY FormId (FormId), KEY Priority (Priority), KEY IsSystem (IsSystem), KEY DisplayInGrid (DisplayInGrid), KEY Visibility (Visibility), KEY EmailCommunicationRole (EmailCommunicationRole) ); CREATE TABLE FormSubmissions ( FormSubmissionId int(11) NOT NULL AUTO_INCREMENT, FormId int(11) NOT NULL DEFAULT '0', SubmissionTime int(11) DEFAULT NULL, IPAddress varchar(15) NOT NULL DEFAULT '', ReferrerURL text NULL, LogStatus tinyint(3) unsigned NOT NULL DEFAULT '2', LastUpdatedOn int(10) unsigned DEFAULT NULL, Notes text, MessageId varchar(255) DEFAULT NULL, PRIMARY KEY (FormSubmissionId), KEY FormId (FormId), KEY SubmissionTime (SubmissionTime), KEY LogStatus (LogStatus), KEY LastUpdatedOn (LastUpdatedOn), KEY MessageId (MessageId) ); CREATE TABLE FormSubmissionReplies ( SubmissionLogId int(11) NOT NULL AUTO_INCREMENT, FormSubmissionId int(10) unsigned NOT NULL, FromEmail varchar(255) NOT NULL DEFAULT '', ToEmail varchar(255) NOT NULL DEFAULT '', Cc text, Bcc text, `Subject` varchar(255) NOT NULL DEFAULT '', Message text, Attachment text, ReplyStatus tinyint(3) unsigned NOT NULL DEFAULT '0', SentStatus tinyint(3) unsigned NOT NULL DEFAULT '0', SentOn int(10) unsigned DEFAULT NULL, RepliedOn int(10) unsigned DEFAULT NULL, VerifyCode varchar(32) NOT NULL DEFAULT '', DraftId int(10) unsigned NOT NULL DEFAULT '0', MessageId varchar(255) NOT NULL DEFAULT '', BounceInfo text, BounceDate int(11) DEFAULT NULL, PRIMARY KEY (SubmissionLogId), KEY FormSubmissionId (FormSubmissionId), KEY ReplyStatus (ReplyStatus), KEY SentStatus (SentStatus), KEY SentOn (SentOn), KEY RepliedOn (RepliedOn), KEY VerifyCode (VerifyCode), KEY DraftId (DraftId), KEY BounceDate (BounceDate), KEY MessageId (MessageId) ); CREATE TABLE FormSubmissionReplyDrafts ( DraftId int(11) NOT NULL AUTO_INCREMENT, FormSubmissionId int(10) unsigned NOT NULL DEFAULT '0', CreatedOn int(10) unsigned DEFAULT NULL, CreatedById int(11) DEFAULT NULL, Message text, PRIMARY KEY (DraftId), KEY FormSubmissionId (FormSubmissionId), KEY CreatedOn (CreatedOn), KEY CreatedById (CreatedById) ); CREATE TABLE Forms ( FormId int(11) NOT NULL AUTO_INCREMENT, Title varchar(255) NOT NULL DEFAULT '', Description text, RequireLogin tinyint(4) NOT NULL DEFAULT '0', UseSecurityImage tinyint(4) NOT NULL DEFAULT '0', SubmitNotifyEmail varchar(255) NOT NULL DEFAULT '', EnableEmailCommunication tinyint(4) NOT NULL DEFAULT '0', ProcessUnmatchedEmails tinyint(4) NOT NULL DEFAULT '0', ReplyFromName varchar(255) NOT NULL DEFAULT '', ReplyFromEmail varchar(255) NOT NULL DEFAULT '', ReplyCc varchar(255) NOT NULL DEFAULT '', ReplyBcc varchar(255) NOT NULL DEFAULT '', ReplyMessageSignature text, ReplyServer varchar(255) NOT NULL DEFAULT '', ReplyPort int(11) NOT NULL DEFAULT '110', ReplyUsername varchar(255) NOT NULL DEFAULT '', ReplyPassword varchar(255) NOT NULL DEFAULT '', BounceEmail varchar(255) NOT NULL DEFAULT '', BounceServer varchar(255) NOT NULL DEFAULT '', BouncePort int(11) NOT NULL DEFAULT '110', BounceUsername varchar(255) NOT NULL DEFAULT '', BouncePassword varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (FormId), KEY UseSecurityImage (UseSecurityImage), KEY RequireLogin (RequireLogin), KEY EnableEmailCommunication (EnableEmailCommunication), KEY ProcessUnmatchedEmails (ProcessUnmatchedEmails) ); CREATE TABLE Semaphores ( SemaphoreId int(11) NOT NULL AUTO_INCREMENT, SessionKey int(10) unsigned NOT NULL DEFAULT '0', `Timestamp` int(10) unsigned NOT NULL DEFAULT '0', MainPrefix varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (SemaphoreId), KEY SessionKey (SessionKey), KEY `Timestamp` (`Timestamp`), KEY MainPrefix (MainPrefix) ); CREATE TABLE CachedUrls ( UrlId int(11) NOT NULL AUTO_INCREMENT, Url varchar(255) NOT NULL DEFAULT '', DomainId int(11) NOT NULL DEFAULT '0', `Hash` bigint(11) NOT NULL DEFAULT '0', Prefixes varchar(255) NOT NULL DEFAULT '', ParsedVars text, Cached int(10) unsigned DEFAULT NULL, LifeTime int(11) NOT NULL DEFAULT '-1', PRIMARY KEY (UrlId), KEY Url (Url), KEY `Hash` (`Hash`), KEY Prefixes (Prefixes), KEY Cached (Cached), KEY LifeTime (LifeTime), KEY DomainId (DomainId) ); CREATE TABLE SiteDomains ( DomainId int(11) NOT NULL AUTO_INCREMENT, DomainName varchar(255) NOT NULL DEFAULT '', DomainNameUsesRegExp tinyint(4) NOT NULL DEFAULT '0', SSLDomainName varchar(255) NOT NULL DEFAULT '', SSLDomainNameUsesRegExp tinyint(4) NOT NULL DEFAULT '0', AdminEmail varchar(255) NOT NULL DEFAULT '', DefaultEmailRecipients text, Country varchar(3) NOT NULL DEFAULT '', PrimaryLanguageId int(11) NOT NULL DEFAULT '0', Languages varchar(255) NOT NULL DEFAULT '', PrimaryThemeId int(11) NOT NULL DEFAULT '0', Themes varchar(255) NOT NULL DEFAULT '', DomainIPRange text, ExternalUrl varchar(255) NOT NULL DEFAULT '', RedirectOnIPMatch tinyint(4) NOT NULL DEFAULT '0', Priority int(11) NOT NULL DEFAULT '0', PRIMARY KEY (DomainId), KEY DomainName (DomainName), KEY DomainNameUsesRegExp (DomainNameUsesRegExp), KEY SSLDomainName (SSLDomainName), KEY SSLDomainNameUsesRegExp (SSLDomainNameUsesRegExp), KEY AdminEmail (AdminEmail), KEY Country (Country), KEY PrimaryLanguageId (PrimaryLanguageId), KEY Languages (Languages), KEY PrimaryThemeId (PrimaryThemeId), KEY Themes (Themes), KEY ExternalUrl (ExternalUrl), KEY RedirectOnIPMatch (RedirectOnIPMatch), KEY Priority (Priority) ); CREATE TABLE CurlLog ( LogId int(11) NOT NULL AUTO_INCREMENT, Message varchar(255) NOT NULL DEFAULT '', PageUrl varchar(255) NOT NULL DEFAULT '', RequestUrl varchar(255) NOT NULL DEFAULT '', PortalUserId int(11) NOT NULL, SessionKey int(11) NOT NULL, IsAdmin tinyint(4) NOT NULL, PageData text, RequestData text, ResponseData text, RequestDate int(11) DEFAULT NULL, ResponseDate int(11) DEFAULT NULL, ResponseHttpCode int(11) NOT NULL, CurlError varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (LogId), KEY Message (Message), KEY PageUrl (PageUrl), KEY RequestUrl (RequestUrl), KEY PortalUserId (PortalUserId), KEY SessionKey (SessionKey), KEY IsAdmin (IsAdmin), KEY RequestDate (RequestDate), KEY ResponseDate (ResponseDate), KEY ResponseHttpCode (ResponseHttpCode), KEY CurlError (CurlError) ); CREATE TABLE PromoBlocks ( BlockId int(11) NOT NULL AUTO_INCREMENT, l1_Title varchar(50) NOT NULL DEFAULT '', l2_Title varchar(50) NOT NULL DEFAULT '', l3_Title varchar(50) NOT NULL DEFAULT '', l4_Title varchar(50) NOT NULL DEFAULT '', l5_Title varchar(50) NOT NULL DEFAULT '', l1_ButtonText varchar(255) NOT NULL DEFAULT '', l2_ButtonText varchar(255) NOT NULL DEFAULT '', l3_ButtonText varchar(255) NOT NULL DEFAULT '', l4_ButtonText varchar(255) NOT NULL DEFAULT '', l5_ButtonText varchar(255) NOT NULL DEFAULT '', Priority int(11) NOT NULL DEFAULT '0', `Status` tinyint(1) NOT NULL DEFAULT '1', l1_Image varchar(255) NOT NULL DEFAULT '', l2_Image varchar(255) NOT NULL DEFAULT '', l3_Image varchar(255) NOT NULL DEFAULT '', l4_Image varchar(255) NOT NULL DEFAULT '', l5_Image varchar(255) NOT NULL DEFAULT '', CSSClassName varchar(255) NOT NULL DEFAULT '', LinkType tinyint(1) NOT NULL DEFAULT '1', CategoryId int(11) DEFAULT NULL, ExternalLink varchar(255) NOT NULL DEFAULT '', OpenInNewWindow tinyint(3) unsigned NOT NULL DEFAULT '0', ScheduleFromDate int(11) DEFAULT NULL, ScheduleToDate int(11) DEFAULT NULL, NumberOfClicks int(11) NOT NULL DEFAULT '0', NumberOfViews int(11) NOT NULL DEFAULT '0', Sticky tinyint(1) NOT NULL DEFAULT '0', l1_Html text, l2_Html text, l3_Html text, l4_Html text, l5_Html text, PromoBlockGroupId int(10) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (BlockId), KEY OpenInNewWindow (OpenInNewWindow), KEY PromoBlockGroupId (PromoBlockGroupId), KEY l1_Title (l1_Title(5)), KEY l2_Title (l2_Title(5)), KEY l3_Title (l3_Title(5)), KEY l4_Title (l4_Title(5)), KEY l5_Title (l5_Title(5)), KEY l1_ButtonText (l1_ButtonText(5)), KEY l2_ButtonText (l2_ButtonText(5)), KEY l3_ButtonText (l3_ButtonText(5)), KEY l4_ButtonText (l4_ButtonText(5)), KEY l5_ButtonText (l5_ButtonText(5)) ); CREATE TABLE PromoBlockGroups ( PromoBlockGroupId int(11) NOT NULL AUTO_INCREMENT, Title varchar(255) NOT NULL DEFAULT '', CreatedOn int(10) unsigned DEFAULT NULL, `Status` tinyint(1) NOT NULL DEFAULT '1', RotationDelay decimal(9,2) DEFAULT NULL, TransitionTime decimal(9,2) DEFAULT NULL, TransitionControls tinyint(1) NOT NULL DEFAULT '1', TransitionEffect varchar(255) NOT NULL DEFAULT '', TransitionEffectCustom varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (PromoBlockGroupId) -); \ No newline at end of file +); Index: branches/5.3.x/core/install/step_templates/sys_requirements.tpl =================================================================== --- branches/5.3.x/core/install/step_templates/sys_requirements.tpl (revision 16123) +++ branches/5.3.x/core/install/step_templates/sys_requirements.tpl (revision 16124) @@ -1,78 +1,72 @@ %s '; $error_tpl = ' %s %s '; $check_titles = Array ( - 'php_version' => 'PHP version 5.2.0 or above*', + 'php_version' => 'PHP version 5.3.2 or above*', 'url_rewriting' => 'URL rewriting support', 'java' => 'Java template compression', + 'composer' => 'Dependencies via Composer*', 'sep1' => 'PHP extensions:', 'memcache' => '- Memory caching support', 'curl' => '- Accessing remote resources (via cURL)*', 'simplexml' => '- XML document processing (via SimpleXML)*', 'spl' => '- Standard PHP Library (SPL)*', 'freetype' => '- TrueType font support (via Freetype)*', 'gd_version' => '- GD Graphics Library 1.8 or above*', 'jpeg' => '- JPEG images support*', 'mysql' => '- Database connectivity (via MySQL)*', 'json' => '- JSON processing support*', 'sep2' => 'PHP settings:', 'memory_limit' => "- Memory requirements changing on the fly", 'display_errors' => "- Prevent script errors in production environment", 'error_reporting' => "- Change error detalization level", 'date.timezone' => "- Web server timezone is explicitly set*", 'variables_order' => '- Needed super-global arrays registered', 'output_buffering' => "- Script output buffering enabled*", ); $output = sprintf($heading_tpl, 'Server-side requirements'); $check_results = $this->toolkit->CallPrerequisitesMethod('core/', 'CheckSystemRequirements'); - /*$required_checks = Array ( - 'php_version', 'simplexml', 'curl', 'freetype', 'gd_version', - 'jpeg', 'mysql', 'date.timezone', 'output_buffering', - ); - - $required_checks = array_diff($required_checks, array_keys( array_filter($check_results) ));*/ - foreach ($check_titles AS $key => $title) { if ( substr($key, 0, 3) == 'sep' ) { $check_result = ''; } else { $check_result = $check_results[$key] ? '[PASSED]' : '[FAILED]'; } $output .= sprintf($error_tpl, $title, $check_result); } $output .= sprintf($heading_tpl, 'Client-side requirements', 'text'); $output .= sprintf($error_tpl, 'Cookies enabled', '[FAILED]'); $output .= sprintf($error_tpl, 'JavaScript enabled', '[FAILED]'); $output .= ''; $output .= ''; $output .= ""; echo $output; ?> Index: branches/5.3.x/core/install/prerequisites.php =================================================================== --- branches/5.3.x/core/install/prerequisites.php (revision 16123) +++ branches/5.3.x/core/install/prerequisites.php (revision 16124) @@ -1,241 +1,243 @@ Array ('from' => '5.0.0-B1', 'to' => '5.1.0-B1'), '5.1.0' => Array ('from' => '5.1.0-B1', 'to' => '5.2.0-B1'), '5.2.0' => Array ('from' => '5.2.0-B1', 'to' => '5.3.0-B1'), ); /** * Sets common instance of installator toolkit * * @param kInstallToolkit $instance */ function setToolkit(&$instance) { $this->_toolkit =& $instance; } /** * Checks minimal version, that could be upgradeable * * @return IDBConnection */ function getConnection() { return $this->_toolkit->Conn; } /** * Checks minimal version, that could be upgradeable * * @param Array $versions * @param string $mode when called mode {install, upgrade, standalone) * @return Array */ function CheckPrerequisites($versions, $mode) { $errors = Array (); if ( $mode == 'upgrade' ) { $sql = 'SELECT Version FROM ' . TABLE_PREFIX . 'Modules WHERE Name = "In-Portal"'; $inportal_version = $this->getConnection()->GetOne($sql); if ( $inportal_version === false ) { // only, when In-Portal was installed (below 4.3.x) return $errors; } $min_version = '4.3.1'; // K4-based installator was created, that no longer maintained old upgrade scripts if ( version_compare($inportal_version, $min_version, '<') ) { $errors[] = 'Please upgrade "In-Portal" to version ' . $min_version . ' first'; } // example: to upgrade to 5.1.0-B1 or more you at least need to have 5.0.0 installed foreach ($this->upgradeRules as $min_version => $version_rules) { if ( version_compare($versions[0], $version_rules['from'], '<') && version_compare($versions[1], $version_rules['to'], '>=') ) { $errors[] = 'Please upgrade "In-Portal" to version ' . $min_version . ' first'; break; } } } return $errors; } /** * Returns information about system requirements * * @return array */ function CheckSystemRequirements() { $ret = Array (); - $ret['php_version'] = version_compare(PHP_VERSION, '5.2.0', '>='); + $ret['php_version'] = version_compare(PHP_VERSION, '5.3.2', '>='); if ( function_exists('apache_get_modules') ) { $mod_rewrite = in_array('mod_rewrite', apache_get_modules()); } else { $mod_rewrite = getenv('HTTP_MOD_REWRITE') == 'On'; } $ret['url_rewriting'] = $mod_rewrite; $ret['memcache'] = class_exists('Memcache'); $ret['curl'] = function_exists('curl_init'); $ret['simplexml'] = function_exists('simplexml_load_string'); $ret['spl'] = function_exists('spl_autoload_register'); $ret['freetype'] = function_exists('imagettfbbox'); $ret['gd_version'] = false; if ( function_exists('gd_info') ) { $gd_info = gd_info(); $gd_version = preg_replace('/[^\d.]/', '', $gd_info['GD Version']); $ret['gd_version'] = version_compare($gd_version, '1.8', '>='); } $ret['jpeg'] = function_exists('imagecreatefromjpeg'); $ret['mysql'] = function_exists('mysqli_connect'); $ret['json'] = function_exists('json_encode'); $output = shell_exec('java -version 2>&1'); $ret['java'] = stripos($output, 'java version') !== false; + $ret['composer'] = file_exists(FULL_PATH . '/vendor/autoload.php'); + $ret['memory_limit'] = $this->isPhpSettingChangeable('memory_limit', '33M'); $ret['display_errors'] = $this->isPhpSettingChangeable('display_errors', '1'); $ret['error_reporting'] = $this->canChangeErrorReporting(); $ret['date.timezone'] = ini_get('date.timezone') != ''; $ret['variables_order'] = $this->_hasLetters(ini_get('variables_order'), Array ('G', 'P', 'C', 'S')); $output_buffering = strtolower(ini_get('output_buffering')); $ret['output_buffering'] = $output_buffering == 'on' || $output_buffering > 0; return $ret; } /** * Determines of a setting string has all given letters (ignoring order) in it * * @param string $setting * @param Array $search_letters * @return bool * @access protected */ protected function _hasLetters($setting, $search_letters) { $setting = preg_replace('/(' . implode('|', $search_letters) . ')/', '*', $setting); return substr_count($setting, '*') == count($search_letters); } /** * Detects if error reporting can be changed at runtime * * @return bool * @access protected */ protected function canChangeErrorReporting() { $old_value = error_reporting(E_PARSE); $new_value = error_reporting(); if ( $new_value == E_PARSE ) { error_reporting($old_value); return true; } return false; } /** * Detects if setting of php.ini can be changed * * @param string $setting_name * @param string $new_value * @return bool */ protected function isPhpSettingChangeable($setting_name, $new_value) { $old_value = ini_get($setting_name); if ( ini_set($setting_name, $new_value) === false ) { return false; } ini_set($setting_name, $old_value); return true; } /** * Returns information about DB requirements * * @return array */ function CheckDBRequirements() { // check PHP version 5.2+ $ret = Array(); $sql = 'SELECT VERSION()'; $conn = $this->getConnection(); $db_version = preg_replace('/[^\d.]/', '', $conn->GetOne($sql)); $ret['version'] = version_compare($db_version, '5.0', '>='); $sql = 'SHOW VARIABLES LIKE "max_allowed_packet"'; $db_variables = $conn->Query($sql, 'Variable_name'); $ret['packet_size'] = $db_variables['max_allowed_packet']['Value'] >= 1048576; return $ret; } - } \ No newline at end of file + } Index: branches/5.3.x/core/install/incs/style.css =================================================================== --- branches/5.3.x/core/install/incs/style.css (revision 16123) +++ branches/5.3.x/core/install/incs/style.css (revision 16124) @@ -1,226 +1,230 @@ html, body { margin: 0; padding: 0; background: #FFFFFF; color: #333333; } ol.install-steps { font: bold 12px verdana, sans-serif; color: #fff; line-height: 20px; } .install-steps li { padding-bottom: 3px; } .install-steps li.current-step { color: #FF0000; } .footer { background-color: #FFFFFF; color: #006; border-top: 1px solid #006; font-size: 11px; text-align: right; padding: 2px 10px 0 0; clear: both; } p { padding: 0; margin-top: 0px; font-family: 'Lucida Grande', Verdana, Geneva, Lucida, Helvetica, Arial, sans-serif; } +ol li { + font-family: 'Lucida Grande', Verdana, Geneva, Lucida, Helvetica, Arial, sans-serif; +} + .head_version { padding-right: 5px; font-weight: normal; font-size: 10px; color: white; font-family: verdana, arial; text-decoration: none; } .admintitle, .admintitle-white { font-weight: bold; font-size: 20px; color: #009FF0; font-family: verdana, arial; text-decoration: none; } .admintitle-white { color: #fff } .subsectiontitle { font-weight: bold; font-size: 14px; color: white; font-family: verdana, arial; background-color: #999999; text-decoration: none; height: 24px; } .subsectiontitle:hover { font-weight: bold; font-size: 14px; color: #ffcc00; font-family: verdana, arial; background-color: #999999; text-decoration: none; } .text { font-weight: normal; font-size: 12px; font-family: verdana, arial; text-decoration: none; } /* Toolbar */ .toolbar { font-size: 8pt; border: 1px solid #000000; border-width: 0px 1px 1px 1px; background-color: #F0F1EB; border-collapse: collapse; } .toolbar td { height: 100%; } .toolbar-button, .toolbar-button-disabled, .toolbar-button-over { float: left; text-align: center; font-size: 8pt; padding: 5px 5px 5px 5px; vertical-align: middle; color: #006F99; } .toolbar-button-over { color: #000; } .toolbar-button-disabled { color: #444; } .tableborder { border-right: #000000 1px solid; border-top: #000000 0px solid; font-size: 10pt; border-left: #000000 1px solid; border-bottom: #000000 1px solid; font-family: Arial, Helvetica, sans-serif; } .tableborder_full { border-right: #000000 1px solid; border-top: #000000 1px solid; font-size: 10pt; border-left: #000000 1px solid; border-bottom: #000000 1px solid; font-family: Arial, Helvetica, sans-serif; background-image: url(img/tab_middle.gif); background-repeat: repeat-x; } .tablenav { font-weight: bold; font-size: 14px; color: white; font-family: verdana, arial; background-color: #73C4F5; text-decoration: none; } .tablenav_link { font-weight: bold; font-size: 14px; color: white; font-family: verdana, arial; text-decoration: none; } .tablenav_link:hover { font-weight: bold; font-size: 14px; color: #FFCC00; font-family: verdana, arial; text-decoration: none; } /*.table-color1 { font-weight: normal; font-size: 14px; color: black; font-family: verdana, arial; background-color: #F6F6F6; text-decoration: none; }*/ .table-color2 { font-weight: normal; font-size: 14px; color: black; font-family: verdana, arial; background-color: #EBEBEB; text-decoration: none; } .error { font-weight: bold; font-size: 9pt; color: #ff0000; font-family: Arial, Helvetica, sans-serif; } .button { font-weight: normal; font-size: 12px; background: url(img/button_back.gif) #F9EEAE repeat-x; color: black; font-family: Arial, Verdana; text-decoration: none; } td { font-size: 10pt; font-family: Verdana, Helvetica; text-decoration: none; } .link { cursor: pointer; } .hint { font-size: 12px; color: #666666; font-style: normal; font-family: Arial, Helvetica, sans-serif; } /* === Copy from "toolbar-sprite.css" === */ .core-toolbar-sprite { background: url("../../admin_templates/img/toolbar/toolbar-sprite.png") repeat-x scroll 0 0 transparent; border: 0 none; cursor: pointer; padding: 0; } #core-tb-refresh { background-position: -0px -896px; } #core-tb-refresh.hover { background-position: -32px -896px; } #core-tb-refresh.disabled { background-position: -64px -896px; } #core-tb-prev { background-position: -0px -704px; } #core-tb-prev.hover { background-position: -32px -704px; } #core-tb-prev.disabled { background-position: -64px -704px; } #core-tb-next { background-position: -0px -640px; } #core-tb-next.hover { background-position: -32px -640px; } -#core-tb-next.disabled { background-position: -64px -640px; } \ No newline at end of file +#core-tb-next.disabled { background-position: -64px -640px; } Index: branches/5.3.x/core/install/steps_db.xml =================================================================== --- branches/5.3.x/core/install/steps_db.xml (revision 16123) +++ branches/5.3.x/core/install/steps_db.xml (revision 16124) @@ -1,330 +1,339 @@ Database Hostname - IP or hostname of your database server (normally "localhost").

Database Name - name of the database where In-Portal will be installed.

Database User Name - name of the user for selected database.

Database User Password - password for selected username.

Database Collation - character set used to store data in text fields (normally "utf8_general_ci").

Prefix for Table Names - specified when multiple scripts will be run in the same database. Prefix can be any text string allowed in table naming by your database engine (normally "inp_").

Use existing In-Portal installation setup in this Database - select "Yes" if you already have In-Portal installed in this database and want to use it. Select "No" in all other cases.

]]>
In-Portal is an Open Source object-oriented framework that is developed in PHP and provides a quick and easy way to build websites and web applications.

In-Portal is copyrighted and distributed under GPLv2 license.

GPL / Open Source License - by downloading and installing In-Portal under GPLv2 license you understand and agree to all terms of the GPLv2 license.

Upload License File - if you have obtained Commercial Modules or Support from Intechnic you will be provided with a license file, upload it here.

Use Existing License - if a valid license has been detected on your server, you can choose this option and continue the installation process.

]]>
In-Portal is an Open Source object-oriented framework that is developed in PHP and provides a quick and easy way to build websites and web applications.

In-Portal is copyrighted and distributed under GPLv2 license.

GPL / Open Source License - by downloading and installing In-Portal under GPLv2 license you understand and agree to all terms of GPLv2 license.

Download from Intechnic Servers - if you have obtained Commercial Modules or Support from Intechnic you will be provided with a license, specify your Username and Password in order to download the license.

]]>
Select the domain you wish to install In-Portal on.

The Other option can be used to install In-Portal other custom domains. Note that your web server should match entered domain name.

]]>
The Root Password is initially required to access the Admin Console of In-Portal. The root user can NOT be used to access the Front-end of your In-Portal website.

Once installation is completed it's highly recommented to create additional users with admin privlidges.

]]>
Current step lists all In-Portal Modules that were found on your server and can be installed now.

Additional In-Portal Modules can be found and downloaded here.

While In-Portal Community constantly works on improving In-Portal by creating new functionality and releasing new modules we are always looking for new ideas and Your help so we can make In-Portal even better software!

]]>
In-Portal Installer checks through the system folders and files that require write permissions (777) to be set in order to run successfully In-Portal on your website.

In case if you see a Failure notice saying that In-Portal Installation cannot continue until all permissions are set correctly please continue reading below.

Permissions can be set by using FTP program or directly in shell running "chmod" command. Please refer to the following guide to learn how to set permissions using your FTP program. In case if you have access to shell in your account you can simply run fix_perms.sh files located in /tools folder or do

   # chmod -R 777 ../system ../themes ../system/config.php

Security reasons you will be asked to change permissions back to 755 on /system/config.php file and root / folder of In-Portal on the last step of this installation process!

]]>
Adjust Basic Configuration settings on this step.

Once your In-Portal is installed you can login into Admin Console to change these and other settings. The Configuration section is located in main navigation menu.


Additional Recommendations:

1. Use Cron (UNIX/BSD/Linux) or Task Scheduler (Windows) to run Regular Events in your In-Portal.
It's highly recommended to setup your cron to run every minute so all system events that are enabled will run in the background based on their schedule. These events can be managed in Admin Console via Configuration -> Website -> Scheduled Tasks section.

In-Portal cron file is located in /tools/cron.php folder and can be setup using hosting Control Panel or manually. In Plesk or CPanel interfaces use dialog to add a new cron job and specify the following (use correct paths)
   /absolute/path/to/bin/php -f /absolute/path/to/in-portal/tools/cron.php

2. Adjust Scheduled Tasks
As was explained in the previous recommendation there is a Configuration -> Website -> Scheduled Tasks section where you can control Events triggered by the system. These events do their job to cleanup the data, old image files, check the data integrity, RSS feeds and other processes required for your In-Portal to run efficiently. We do recommend to review and enable/disable these events based on your website needs.

3. Set Mail Server
It's recommended to review and adjust your mail server settings once your In-Portal is up and running. This can be done in Admin Console under Configuration -> Website -> Advanced section.

We strongly recommend carefully reviewing and adjusting all settings under Configuration -> Website section!

]]>
These are system advanced settings and must be changed with caution. It's not recommended to change these settings unless you exactly know what you are doing. These settings will be stored in system/config.php file and can be changed manually if needed.


Web Path to Installation - web path to the root of your In-Portal installation. For example, if your In-Portal will be running at http://www.your-website.com, then Web Path to Installation should be left empty since In-Portal is setup in the root of the domain. In case if your In-Portal will be running under http://www.your-website.com/in-portal/, then it should be set to /in-portal (no trailing slash). This setting is auto-detected during the initial installation step, but can be adjusted at Installation Maintenance step.

Path to Writable folder - path to a folder inside your In-Portal installation which can be accessed from the Web and has writable permissions for the web server. This folder will be used to store dynamic content such as uploaded and resized images, cached templates and other types of user files. The default value is /system.

Path to Restricted folder - path to a folder inside or outside your In-Portal installation which will used to store debug files, system logs and other non-public information. This folder must be writable by the web-server and can be located outside of your In-Portal installation if needed. The default value is /system/.restricted .

Path to Admin folder - web path to your In-Portal Admin Console folder. The default value is set to /admin and your Admin Console will be accessible at http://www.your-website.com/admin. In case if you want your Admin Console to be under http://www.your-website.com/secure-admin (or anything else) you'll need to rename original admin folder to secure-admin on your filesystem and then set this path to /secure-admin .

Path to Admin Interface Presets folder - path to a folder inside your In-Portal installation contains Admin Interface Presets. The default value is /admin .

Name of Base Application Class - default value is kApplication and can change very rarely.

Path to Base Application Class file - default value is /core/kernel/application.php and can change very rarely.

Output Caching Engine - provides ability to cache HTML output or other data using various caching engines to lower the database load. The default value is set to None if no available engines detected. Available options are: None (Fake), Memcached (Memcache), XCache (XCache) and Alternative PHP Cache (Apc). Note that only auto-detected caching engines will be available for selection.

Location of Memcache Servers - host or IP address with port where Memcached Server is running. Multiple locations of can be listed separated by semi-colon (;). For example, 192.168.1.1:1121;192.168.1.2:1121;192.168.1.3:1121 .

CSS/JS Compression Engine - provides minification functionality for CSS / Javascript files. The default value is set to PHP-based if no Java is auto-detected on server-side. Available options are: None (empty), YUICompressor (Java) (yui) and PHP-based (php) .

Website Charset - character encoding that will be used across the website. By default this should be set to UTF-8, but can set to other encoding also (see wikipedia.org options). It's highly recommended to have Website Encoding match the Database Encoding (specified on DB step).

Enable "System Log" - "System Log" has capability to record PHP Exceptions, Errors, Warnings, Notices, Database/SQL Errors and Warnings, and User defined messages that happened on your website. It has 3 modes - Enabled (logs everything, including user defined messages), User-only (user defined messages only), and Disabled (don't log anything at all - default setting).

Trust Proxy - whatever to trust information provided by provided by proxy server (if any) located between web server and client browser.


]]>
Selected theme will be used as a default in your In-Portal website.

You can manage your themes in Admin Console under Configuration -> Website -> Themes section.

Additional themes are available on Support & Downloads section on In-Portal.com website

]]>
In-Portal Installer performs final security checks on this step.

1. Write Permissions Check - checks whether critical In-Portal files are open for the outside world and can be used by hackers to attack your websites. You won't be able to continue until you correctly set these permissions!

2. Ability to Execute PHP in Writable Folders - checks if hackers can save and execute PHP files in your /system folder used for the uploads.While it's recommended to adjust these settings you can continue In-Portal Installation without changing them.

3. Webserver PHP Configuration - additional suggestions how to make your website even more secure. While it's recommended to adjust these settings you can continue In-Portal Installation without changing them.

]]>
Thank you for downloading and installing In-Portal Content Management System!

Feel free to visit www.in-portal.com for support, latest news and module updates.

Please make sure to clean your Browser's Cache if you were performing the upgrade.

]]>
A Configuration file has been detected on your system and it appears In-Portal is correctly installed. In order to work with the maintenance functions provided to the left you must enter your admin Root password. (Use Username 'root' if using your root password)

Upgrade In-Portal - available when you upload files from new In-Portal release into your current installation. Upgrade scripts will run and upgrade your current In-Portal database to the uploaded version.

Reinstall In-Portal - cleans out your existing In-Portal database and starts with a fresh installation. Note that this operation cannot be undone and no backups are made! Use at your own risk.

Install In-Portal to a New Database - keeps the existing installation and installs In-Portal to a new database. If this option is selected you will be prompted for new database configuration information.

Update License Information - used to update your In-Portal license data. Select this option if you have modified your licensing status with Intechnic (obtained commercial support or module), or you have received new license data via email.

Update Database Configuration - allows you to update your current database configuration variables such as database server host, username, password and others.

Update Installation Paths - should be used when the location of your In-Portal files has changed. For example, if you moved them from one folder to another. It will update all settings and ensure In-Portal is operational at the new location.

]]>
Select modules from the list, you need to update to the last downloaded version of In-Portal

]]>
Review Administrative Console skin upgrade log.

]]>
In-Portal needs to connect to your Database Server. Please provide the database server type*, host name (normally "localhost"), Database user name, and database Password. These fields are required to connect to the database.

If you would like In-Portal to use a table prefix, enter it in the field provided. This prefix can be any text which can be used in the names of tables on your system. The characters entered in this field are placed before the names of the tables used by In-Portal. For example, if you enter "inp_" into the prefix field, the table named Categories will be named inp_Categories.

]]>
The System Requirements Check option should be used to ensure proper system behavior in the current environment.

- PHP version 5.2.0 or above*
+ PHP version 5.3.2 or above*
Use this PHP version or better to ensure normal website operation on every day basis.

URL rewriting support
Allows to build nice looking SEO urls without specifying "/index.php" in each of them.

Java template compression
When Java is installed on web server, then it's possible to use YUI Compressor to minify HTML, CSS and JavaScript output of website. This allows to make websites, which opens even faster, then before.

+ Dependencies via Composer
+ In-Portal uses Composer to install required 3rd-party libraries. + Please ensure, that:
+

    +
  1. Composer is installed (instructions)
  2. +
  3. Dependencies are installed (instructions)
  4. +
+

+

Memory caching support
When available use Memcached memory object caching system for data caching. Will severely improve website performance under heavy load and page loading speed in general.

Accessing remote resources (via cURL)
Allows to perform data retrieval from other websites (e.g. rss feeds) in background. Data retrieval internally is done using cURL library, that must be installed on web server.

XML document processing (via SimpleXML)*
In-Portal uses XML files to store module/theme meta data. This library is used keep In-Portal code clean as fast even, when processing XML files.

Standard PHP Library (SPL)*
Usage of this library guarantees memory efficient way to manage files and data structures across In-Portal.

TrueType font support (via Freetype)*
This library allows to use TrueType fonts inside produced images. In particular it's used for Captcha code generation.

GD Graphics Library 1.8 or above*
This library is used to perform various manipulations (e.g. resize, crop, etc.) on user-uploaded images.

JPEG images support*
Support image manipulations on user-uploaded images *.jpg and *.jpeg file extensions.

Database connectivity (via MySQL)*
In-Portal uses MySQL database as it's persistent data storage.

JSON processing support*
JSON data format is used to implement AJAX approach and perform complete page reload only, when necessary.

Memory requirements changing on the fly
In-Portal requires at least 16 megabytes of memory to operate normally. However some resource consuming operations (like link validation) might consume more memory, then usual. To ensure, that such operations never fail In-Portal changes maximally allowed memory limit on the fly. See memory_limit setting for more info.

Prevent script errors in production environment
Prevents any errors to be shown on website, that might happen due incorrect web server configuration. See display_errors setting for more info.

Change error detalization level
Ensures, that all error types are shown in development environment and none in production environment. See error_reporting setting for more info.

Web server timezone is explicitly set*
Web server timezone must be set explicitly to ensure correct date/time calculations and display across the website. See date.timezone setting for more info.

Needed super-global arrays registered
Internally In-Portal relies on super-global array (e.g. $_SERVER, $_POST, etc.) presense inside a script. To make that happen variables_order setting must contain following letters: "G", "P", "C", "S".

Script output buffering enabled*
Output buffering is needed to allow usage of GZIP compression of page output. See output_buffering setting for more info.

Cookies enabled
However In-Portal can work without cookies (by adding ?sid=XXXXXXXX into each page url), but it's strongly advised to use cookies-enabled web browser for better user expirience.

JavaScript enabled
JavaScript might not be required on Front-End (depends on used theme), but it must be enabled in web browser during installation and Admin Console usage.

]]>
-
\ No newline at end of file + Index: branches/5.3.x/core/install/upgrades.sql =================================================================== --- branches/5.3.x/core/install/upgrades.sql (revision 16123) +++ branches/5.3.x/core/install/upgrades.sql (revision 16124) @@ -1,3008 +1,3024 @@ # ===== v 4.0.1 ===== ALTER TABLE EmailLog ADD EventParams TEXT NOT NULL; INSERT INTO ConfigurationAdmin VALUES ('MailFunctionHeaderSeparator', 'la_Text_smtp_server', 'la_config_MailFunctionHeaderSeparator', 'radio', NULL, '1=la_Linux,2=la_Windows', 30.08, 0, 0); INSERT INTO ConfigurationValues VALUES (0, 'MailFunctionHeaderSeparator', 1, 'In-Portal', 'in-portal:configure_general'); ALTER TABLE PersistantSessionData DROP PRIMARY KEY ; ALTER TABLE PersistantSessionData ADD INDEX ( `PortalUserId` ) ; # ===== v 4.1.0 ===== ALTER TABLE EmailMessage ADD ReplacementTags TEXT AFTER Template; ALTER TABLE Phrase CHANGE Translation Translation TEXT NOT NULL, CHANGE Module Module VARCHAR(30) NOT NULL DEFAULT 'In-Portal'; ALTER TABLE Category CHANGE Description Description TEXT, CHANGE l1_Description l1_Description TEXT, CHANGE l2_Description l2_Description TEXT, CHANGE l3_Description l3_Description TEXT, CHANGE l4_Description l4_Description TEXT, CHANGE l5_Description l5_Description TEXT, CHANGE CachedNavbar CachedNavbar text, CHANGE l1_CachedNavbar l1_CachedNavbar text, CHANGE l2_CachedNavbar l2_CachedNavbar text, CHANGE l3_CachedNavbar l3_CachedNavbar text, CHANGE l4_CachedNavbar l4_CachedNavbar text, CHANGE l5_CachedNavbar l5_CachedNavbar text, CHANGE ParentPath ParentPath TEXT NULL DEFAULT NULL, CHANGE NamedParentPath NamedParentPath TEXT NULL DEFAULT NULL; ALTER TABLE ConfigurationAdmin CHANGE ValueList ValueList TEXT; ALTER TABLE EmailQueue CHANGE `Subject` `Subject` TEXT, CHANGE toaddr toaddr TEXT, CHANGE fromaddr fromaddr TEXT; ALTER TABLE Category DROP Pop; ALTER TABLE PortalUser CHANGE CreatedOn CreatedOn INT DEFAULT NULL, CHANGE dob dob INT(11) NULL DEFAULT NULL, CHANGE PassResetTime PassResetTime INT(11) UNSIGNED NULL DEFAULT NULL, CHANGE PwRequestTime PwRequestTime INT(11) UNSIGNED NULL DEFAULT NULL, CHANGE `Password` `Password` VARCHAR(255) NULL DEFAULT 'd41d8cd98f00b204e9800998ecf8427e'; ALTER TABLE Modules CHANGE BuildDate BuildDate INT UNSIGNED NULL DEFAULT NULL, CHANGE Version Version VARCHAR(10) NOT NULL DEFAULT '0.0.0', CHANGE `Var` `Var` VARCHAR(100) NOT NULL DEFAULT ''; ALTER TABLE Language CHANGE Enabled Enabled INT(11) NOT NULL DEFAULT '1', CHANGE InputDateFormat InputDateFormat VARCHAR(50) NOT NULL DEFAULT 'm/d/Y', CHANGE InputTimeFormat InputTimeFormat VARCHAR(50) NOT NULL DEFAULT 'g:i:s A', CHANGE DecimalPoint DecimalPoint VARCHAR(10) NOT NULL DEFAULT '', CHANGE ThousandSep ThousandSep VARCHAR(10) NOT NULL DEFAULT ''; ALTER TABLE Events CHANGE FromUserId FromUserId INT(11) NOT NULL DEFAULT '-1'; ALTER TABLE StdDestinations CHANGE DestAbbr2 DestAbbr2 CHAR(2) NULL DEFAULT NULL; ALTER TABLE PermCache DROP DACL; ALTER TABLE PortalGroup CHANGE CreatedOn CreatedOn INT UNSIGNED NULL DEFAULT NULL; ALTER TABLE UserSession CHANGE SessionKey SessionKey INT UNSIGNED NULL DEFAULT NULL , CHANGE CurrentTempKey CurrentTempKey INT UNSIGNED NULL DEFAULT NULL , CHANGE PrevTempKey PrevTempKey INT UNSIGNED NULL DEFAULT NULL , CHANGE LastAccessed LastAccessed INT UNSIGNED NOT NULL DEFAULT '0', CHANGE PortalUserId PortalUserId INT(11) NOT NULL DEFAULT '-2', CHANGE Language Language INT(11) NOT NULL DEFAULT '1', CHANGE Theme Theme INT(11) NOT NULL DEFAULT '1'; CREATE TABLE Counters ( CounterId int(10) unsigned NOT NULL auto_increment, Name varchar(100) NOT NULL default '', CountQuery text, CountValue text, LastCounted int(10) unsigned default NULL, LifeTime int(10) unsigned NOT NULL default '3600', IsClone tinyint(3) unsigned NOT NULL default '0', TablesAffected text, PRIMARY KEY (CounterId), UNIQUE KEY Name (Name) ); CREATE TABLE Skins ( `SkinId` int(11) NOT NULL auto_increment, `Name` varchar(255) default NULL, `CSS` text, `Logo` varchar(255) default NULL, `Options` text, `LastCompiled` int(11) NOT NULL default '0', `IsPrimary` int(1) NOT NULL default '0', PRIMARY KEY (`SkinId`) ); INSERT INTO Skins VALUES (DEFAULT, 'Default', '/* General elements */\r\n\r\nhtml {\r\n height: 100%;\r\n}\r\n\r\nbody {\r\n font-family: verdana,arial,helvetica,sans-serif;\r\n font-size: 9pt;\r\n color: #000000;\r\n overflow-x: auto; overflow-y: auto;\r\n margin: 0px 0px 0px 0px;\r\n text-decoration: none;\r\n}\r\n\r\na {\r\n color: #006699;\r\n text-decoration: none;\r\n}\r\n\r\na:hover {\r\n color: #009ff0;\r\n text-decoration: none;\r\n}\r\n\r\nform {\r\n display: inline;\r\n}\r\n\r\nimg { border: 0px; }\r\n\r\nbody.height-100 {\r\n height: 100%;\r\n}\r\n\r\nbody.regular-body {\r\n margin: 0px 10px 5px 10px;\r\n color: #000000;\r\n background-color: @@SectionBgColor@@;\r\n}\r\n\r\nbody.edit-popup {\r\n margin: 0px 0px 0px 0px;\r\n}\r\n\r\ntable.collapsed {\r\n border-collapse: collapse;\r\n}\r\n\r\n.bordered, table.bordered, .bordered-no-bottom {\r\n border: 1px solid #000000;\r\n border-collapse: collapse;\r\n}\r\n\r\n.bordered-no-bottom {\r\n border-bottom: none;\r\n}\r\n\r\n.login-table td {\r\n padding: 1px;\r\n}\r\n\r\n.disabled {\r\n background-color: #ebebeb;\r\n}\r\n\r\n/* Head frame */\r\n.head-table tr td {\r\n background-color: @@HeadBgColor@@;\r\n color: @@HeadColor@@\r\n}\r\n\r\ntd.kx-block-header, .head-table tr td.kx-block-header{\r\n color: @@HeadBarColor@@;\r\n background-color: @@HeadBarBgColor@@;\r\n padding-left: 7px;\r\n padding-right: 7px;\r\n}\r\n\r\na.kx-header-link {\r\n text-decoration: underline;\r\n color: #FFFFFF;\r\n}\r\n\r\na.kx-header-link:hover {\r\n color: #FFCB05;\r\n text-decoration: none;\r\n}\r\n\r\n.kx-secondary-foreground {\r\n color: @@HeadBarColor@@;\r\n background-color: @@HeadBarBgColor@@;\r\n}\r\n\r\n.kx-login-button {\r\n background-color: #2D79D6;\r\n color: #FFFFFF;\r\n}\r\n\r\n/* General form button (yellow) */\r\n.button {\r\n font-size: 12px;\r\n font-weight: normal;\r\n color: #000000;\r\n background: url(@@base_url@@/proj-base/admin_templates/img/button_back.gif) #f9eeae repeat-x;\r\n text-decoration: none;\r\n}\r\n\r\n/* Disabled (grayed-out) form button */\r\n.button-disabled {\r\n font-size: 12px;\r\n font-weight: normal;\r\n color: #676767;\r\n background: url(@@base_url@@/proj-base/admin_templates/img/button_back_disabled.gif) #f9eeae repeat-x;\r\n text-decoration: none;\r\n}\r\n\r\n/* Tabs bar */\r\n\r\n.tab, .tab-active {\r\n background-color: #F0F1EB;\r\n padding: 3px 7px 2px 7px;\r\n border-top: 1px solid black;\r\n border-left: 1px solid black;\r\n border-right: 1px solid black;\r\n}\r\n\r\n.tab-active {\r\n background-color: #2D79D6;\r\n border-bottom: 1px solid #2D79D6;\r\n}\r\n\r\n.tab a {\r\n color: #00659C;\r\n font-weight: bold;\r\n}\r\n\r\n.tab-active a {\r\n color: #fff;\r\n font-weight: bold;\r\n}\r\n\r\n\r\n/* Toolbar */\r\n\r\n.toolbar {\r\n font-size: 8pt;\r\n border: 1px solid #000000;\r\n border-width: 0px 1px 1px 1px;\r\n background-color: @@ToolbarBgColor@@;\r\n border-collapse: collapse;\r\n}\r\n\r\n.toolbar td {\r\n height: 100%;\r\n}\r\n\r\n.toolbar-button, .toolbar-button-disabled, .toolbar-button-over {\r\n float: left;\r\n text-align: center;\r\n font-size: 8pt;\r\n padding: 5px 5px 5px 5px;\r\n vertical-align: middle;\r\n color: #006F99;\r\n}\r\n\r\n.toolbar-button-over {\r\n color: #000;\r\n}\r\n\r\n.toolbar-button-disabled {\r\n color: #444;\r\n}\r\n\r\n/* Scrollable Grids */\r\n\r\n\r\n/* Main Grid class */\r\n.grid-scrollable {\r\n padding: 0px;\r\n border: 1px solid black !important;\r\n border-top: none !important;\r\n}\r\n\r\n/* Div generated by js, which contains all the scrollable grid elements, affects the style of scrollable area without data (if there are too few rows) */\r\n.grid-container {\r\n background-color: #fff;\r\n}\r\n\r\n.grid-container table {\r\n border-collapse: collapse;\r\n}\r\n\r\n/* Inner div generated in each data-cell */\r\n.grid-cell-div {\r\n overflow: hidden;\r\n height: auto;\r\n}\r\n\r\n/* Main row definition */\r\n.grid-data-row td, .grid-data-row-selected td, .grid-data-row-even-selected td, .grid-data-row-mouseover td, .table-color1, .table-color2 {\r\n font-weight: normal;\r\n color: @@OddColor@@;\r\n background-color: @@OddBgColor@@;\r\n padding: 3px 5px 3px 5px;\r\n height: 30px;\r\n overflow: hidden;\r\n /* border-right: 1px solid black; */\r\n}\r\n.grid-data-row-even td, .table-color2 {\r\n background-color: @@EvenBgColor@@;\r\n color: @@EvenColor@@;\r\n}\r\n.grid-data-row td a, .grid-data-row-selected td a, .grid-data-row-mouseover td a {\r\n text-decoration: underline;\r\n}\r\n\r\n/* mouse-over rows */\r\n.grid-data-row-mouseover td {\r\n background: #FFFDF4;\r\n}\r\n\r\n/* Selected row, applies to both checkbox and data areas */\r\n.grid-data-row-selected td {\r\n background: #FEF2D6;\r\n}\r\n\r\n.grid-data-row-even-selected td {\r\n background: #FFF7E0;\r\n}\r\n\r\n/* General header cell definition */\r\n.grid-header-row td {\r\n font-weight: bold;\r\n background-color: @@ColumnTitlesBgColor@@;\r\n text-decoration: none;\r\n padding: 3px 5px 3px 5px;\r\n color: @@ColumnTitlesColor@@;\r\n border-right: none;\r\n text-align: left;\r\n vertical-align: middle !important;\r\n white-space: nowrap;\r\n /* border-right: 1px solid black; */\r\n}\r\n\r\n/* Filters row */\r\ntr.grid-header-row-0 td {\r\n background-color: @@FiltersBgColor@@;\r\n border-bottom: 1px solid black;\r\n}\r\n\r\n/* Grid Filters */\r\ntable.range-filter {\r\n width: 100%;\r\n}\r\n\r\n.range-filter td {\r\n padding: 0px 0px 2px 2px !important;\r\n border: none !important;\r\n font-size: 8pt !important;\r\n font-weight: normal !important;\r\n text-align: left;\r\n color: #000000 !important;\r\n}\r\n\r\ninput.filter, select.filter {\r\n margin-bottom: 0px;\r\n width: 85%;\r\n}\r\n\r\ninput.filter-active {\r\n background-color: #FFFF00;\r\n}\r\n\r\nselect.filter-active {\r\n background-color: #FFFF00;\r\n}\r\n\r\n/* Column titles row */\r\ntr.grid-header-row-1 td {\r\n height: 25px;\r\n font-weight: bold;\r\n background-color: @@ColumnTitlesBgColor@@;\r\n color: @@ColumnTitlesColor@@;\r\n}\r\n\r\ntr.grid-header-row-1 td a {\r\n color: @@ColumnTitlesColor@@;\r\n}\r\n\r\ntr.grid-header-row-1 td a:hover {\r\n color: #FFCC00;\r\n}\r\n\r\n\r\n.grid-footer-row td {\r\n background-color: #D7D7D7;\r\n font-weight: bold;\r\n border-right: none;\r\n padding: 3px 5px 3px 5px;\r\n}\r\n\r\ntd.grid-header-last-cell, td.grid-data-last-cell, td.grid-footer-last-cell {\r\n border-right: none !important;\r\n}\r\n\r\ntd.grid-data-col-0, td.grid-data-col-0 div {\r\n text-align: center;\r\n vertical-align: middle !important;\r\n}\r\n\r\ntr.grid-header-row-0 td.grid-header-col-0 {\r\n text-align: center;\r\n vertical-align: middle !important;\r\n}\r\n\r\ntr.grid-header-row-0 td.grid-header-col-0 div {\r\n display: table-cell;\r\n vertical-align: middle;\r\n}\r\n\r\n.grid-status-bar {\r\n border: 1px solid black;\r\n border-top: none;\r\n padding: 0px;\r\n width: 100%;\r\n border-collapse: collapse;\r\n height: 30px;\r\n}\r\n\r\n.grid-status-bar td {\r\n background-color: @@TitleBarBgColor@@;\r\n color: @@TitleBarColor@@;\r\n font-size: 11pt;\r\n font-weight: normal;\r\n padding: 2px 8px 2px 8px;\r\n}\r\n\r\n/* /Scrollable Grids */\r\n\r\n\r\n/* Forms */\r\ntable.edit-form {\r\n border: none;\r\n border-top-width: 0px;\r\n border-collapse: collapse;\r\n width: 100%;\r\n}\r\n\r\n.edit-form-odd, .edit-form-even {\r\n padding: 0px;\r\n}\r\n\r\n.subsectiontitle {\r\n font-size: 10pt;\r\n font-weight: bold;\r\n background-color: #4A92CE;\r\n color: #fff;\r\n height: 25px;\r\n border-top: 1px solid black;\r\n}\r\n\r\n.label-cell {\r\n background: #DEE7F6 url(@@base_url@@/proj-base/admin_templates/img/bgr_input_name_line.gif) no-repeat right bottom;\r\n font: 12px arial, sans-serif;\r\n padding: 4px 20px;\r\n width: 150px;\r\n}\r\n\r\n.control-mid {\r\n width: 13px;\r\n border-left: 1px solid #7A95C2;\r\n background: #fff url(@@base_url@@/proj-base/admin_templates/img/bgr_mid.gif) repeat-x left bottom;\r\n}\r\n\r\n.control-cell {\r\n font: 11px arial, sans-serif;\r\n padding: 4px 10px 5px 5px;\r\n background: #fff url(@@base_url@@/proj-base/admin_templates/img/bgr_input_line.gif) no-repeat left bottom;\r\n width: auto;\r\n vertical-align: middle;\r\n}\r\n\r\n.label-cell-filler {\r\n background: #DEE7F6 none;\r\n}\r\n.control-mid-filler {\r\n background: #fff none;\r\n border-left: 1px solid #7A95C2;\r\n}\r\n.control-cell-filler {\r\n background: #fff none;\r\n}\r\n\r\n\r\n.error-cell {\r\n background-color: #fff;\r\n color: red;\r\n}\r\n\r\n.form-warning {\r\n color: red;\r\n}\r\n\r\n.req-note {\r\n font-style: italic;\r\n color: #333;\r\n}\r\n\r\n#scroll_container table.tableborder {\r\n border-collapse: separate\r\n}\r\n\r\n\r\n/* Uploader */\r\n\r\n.uploader-main {\r\n position: absolute;\r\n display: none;\r\n z-index: 10;\r\n border: 1px solid #777;\r\n padding: 10px;\r\n width: 350px;\r\n height: 120px;\r\n overflow: hidden;\r\n background-color: #fff;\r\n}\r\n\r\n.uploader-percent {\r\n width: 100%;\r\n padding-top: 3px;\r\n text-align: center;\r\n position: relative;\r\n z-index: 20;\r\n float: left;\r\n font-weight: bold;\r\n}\r\n\r\n.uploader-left {\r\n width: 100%;\r\n border: 1px solid black;\r\n height: 20px;\r\n background: #fff url(@@base_url@@/core/admin_templates/img/progress_left.gif);\r\n}\r\n\r\n.uploader-done {\r\n width: 0%;\r\n background-color: green;\r\n height: 20px;\r\n background: #4A92CE url(@@base_url@@/core/admin_templates/img/progress_done.gif);\r\n}\r\n\r\n\r\n/* To be sorted */\r\n\r\n\r\n/* Section title, right to the big icon */\r\n.admintitle {\r\n font-size: 16pt;\r\n font-weight: bold;\r\n color: @@SectionColor@@;\r\n text-decoration: none;\r\n}\r\n\r\n/* Left sid of bluebar */\r\n.header_left_bg {\r\n background-color: @@TitleBarBgColor@@;\r\n background-image: none;\r\n padding-left: 5px;\r\n}\r\n\r\n/* Right side of bluebar */\r\n.tablenav, tablenav a {\r\n font-size: 11pt;\r\n font-weight: bold;\r\n color: @@TitleBarColor@@;\r\n\r\n text-decoration: none;\r\n background-color: @@TitleBarBgColor@@;\r\n background-image: none;\r\n}\r\n\r\n/* Section title in the bluebar * -- why ''link''? :S */\r\n.tablenav_link {\r\n font-size: 11pt;\r\n font-weight: bold;\r\n color: @@TitleBarColor@@;\r\n text-decoration: none;\r\n}\r\n\r\n/* Active page in top and bottom bluebars pagination */\r\n.current_page {\r\n font-size: 10pt;\r\n font-weight: bold;\r\n background-color: #fff;\r\n color: #2D79D6;\r\n padding: 3px 2px 3px 3px;\r\n}\r\n\r\n/* Other pages and arrows in pagination on blue */\r\n.nav_url {\r\n font-size: 10pt;\r\n font-weight: bold;\r\n color: #fff;\r\n padding: 3px 2px 3px 3px;\r\n}\r\n\r\n/* Tree */\r\n.tree-body {\r\n background-color: @@TreeBgColor@@;\r\n height: 100%\r\n}\r\n\r\n.tree_head.td, .tree_head, .tree_head:hover {\r\n font-weight: bold;\r\n font-size: 10px;\r\n color: #FFFFFF;\r\n font-family: Verdana, Arial;\r\n text-decoration: none;\r\n}\r\n\r\n.tree {\r\n padding: 0px;\r\n border: none;\r\n border-collapse: collapse;\r\n}\r\n\r\n.tree tr td {\r\n padding: 0px;\r\n margin: 0px;\r\n font-family: helvetica, arial, verdana,;\r\n font-size: 11px;\r\n white-space: nowrap;\r\n}\r\n\r\n.tree tr td a {\r\n font-size: 11px;\r\n color: @@TreeColor@@;\r\n font-family: Helvetica, Arial, Verdana;\r\n text-decoration: none;\r\n padding: 2px 0px 2px 2px;\r\n}\r\n\r\n.tree tr.highlighted td a {\r\n background-color: @@TreeHighBgColor@@;\r\n color: @@TreeHighColor@@;\r\n}\r\n\r\n.tree tr.highlighted td a:hover {\r\n color: #fff;\r\n}\r\n\r\n.tree tr td a:hover {\r\n color: #000000;\r\n}', 'just_logo.gif', 'a:20:{s:11:"HeadBgColor";a:2:{s:11:"Description";s:27:"Head frame background color";s:5:"Value";s:7:"#1961B8";}s:9:"HeadColor";a:2:{s:11:"Description";s:21:"Head frame text color";s:5:"Value";s:7:"#CCFF00";}s:14:"SectionBgColor";a:2:{s:11:"Description";s:28:"Section bar background color";s:5:"Value";s:7:"#FFFFFF";}s:12:"SectionColor";a:2:{s:11:"Description";s:22:"Section bar text color";s:5:"Value";s:7:"#2D79D6";}s:12:"HeadBarColor";a:1:{s:5:"Value";s:7:"#FFFFFF";}s:14:"HeadBarBgColor";a:1:{s:5:"Value";s:7:"#1961B8";}s:13:"TitleBarColor";a:1:{s:5:"Value";s:7:"#FFFFFF";}s:15:"TitleBarBgColor";a:1:{s:5:"Value";s:7:"#2D79D6";}s:14:"ToolbarBgColor";a:1:{s:5:"Value";s:7:"#F0F1EB";}s:14:"FiltersBgColor";a:1:{s:5:"Value";s:7:"#D7D7D7";}s:17:"ColumnTitlesColor";a:1:{s:5:"Value";s:7:"#FFFFFF";}s:19:"ColumnTitlesBgColor";a:1:{s:5:"Value";s:7:"#999999";}s:8:"OddColor";a:1:{s:5:"Value";s:7:"#000000";}s:10:"OddBgColor";a:1:{s:5:"Value";s:7:"#F6F6F6";}s:9:"EvenColor";a:1:{s:5:"Value";s:7:"#000000";}s:11:"EvenBgColor";a:1:{s:5:"Value";s:7:"#EBEBEB";}s:9:"TreeColor";a:1:{s:5:"Value";s:7:"#006F99";}s:11:"TreeBgColor";a:1:{s:5:"Value";s:7:"#FFFFFF";}s:13:"TreeHighColor";a:1:{s:5:"Value";s:7:"#FFFFFF";}s:15:"TreeHighBgColor";a:1:{s:5:"Value";s:7:"#4A92CE";}}', 1178706881, 1); INSERT INTO Permissions VALUES (0, 'in-portal:skins.view', 11, 1, 1, 0), (0, 'in-portal:skins.add', 11, 1, 1, 0), (0, 'in-portal:skins.edit', 11, 1, 1, 0), (0, 'in-portal:skins.delete', 11, 1, 1, 0); # ===== v 4.1.1 ===== DROP TABLE EmailQueue; CREATE TABLE EmailQueue ( EmailQueueId int(10) unsigned NOT NULL auto_increment, ToEmail varchar(255) NOT NULL default '', `Subject` varchar(255) NOT NULL default '', MessageHeaders text, MessageBody longtext, Queued int(10) unsigned NOT NULL default '0', SendRetries int(10) unsigned NOT NULL default '0', LastSendRetry int(10) unsigned NOT NULL default '0', PRIMARY KEY (EmailQueueId), KEY LastSendRetry (LastSendRetry), KEY SendRetries (SendRetries) ); ALTER TABLE Events ADD ReplacementTags TEXT AFTER Event; # ===== v 4.2.0 ===== ALTER TABLE CustomField ADD MultiLingual TINYINT UNSIGNED NOT NULL DEFAULT '1' AFTER FieldLabel; ALTER TABLE Category ADD TreeLeft BIGINT NOT NULL AFTER ParentPath, ADD TreeRight BIGINT NOT NULL AFTER TreeLeft; ALTER TABLE Category ADD INDEX (TreeLeft); ALTER TABLE Category ADD INDEX (TreeRight); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CategoriesRebuildSerial', '0', 'In-Portal', ''); UPDATE ConfigurationAdmin SET `element_type` = 'textarea' WHERE `VariableName` IN ('Category_MetaKey', 'Category_MetaDesc'); ALTER TABLE PortalUser CHANGE FirstName FirstName VARCHAR(255) NOT NULL DEFAULT '', CHANGE LastName LastName VARCHAR(255) NOT NULL DEFAULT ''; # ===== v 4.2.1 ===== INSERT INTO ConfigurationAdmin VALUES ('UseSmallHeader', 'la_Text_Website', 'la_config_UseSmallHeader', 'checkbox', '', '', 10.21, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'UseSmallHeader', '0', 'In-Portal', 'in-portal:configure_general'); INSERT INTO ConfigurationAdmin VALUES ('User_Default_Registration_Country', 'la_Text_General', 'la_config_DefaultRegistrationCountry', 'select', NULL , '=+,SELECT DestName AS OptionName, DestId AS OptionValue FROM StdDestinations WHERE DestParentId IS NULL Order BY OptionName', 10.111, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'User_Default_Registration_Country', '', 'In-Portal:Users', 'in-portal:configure_users'); ALTER TABLE Category ADD SymLinkCategoryId INT UNSIGNED NULL DEFAULT NULL AFTER `Type`, ADD INDEX (SymLinkCategoryId); ALTER TABLE ConfigurationValues CHANGE VariableValue VariableValue TEXT NULL DEFAULT NULL; ALTER TABLE Language ADD AdminInterfaceLang TINYINT UNSIGNED NOT NULL AFTER PrimaryLang, ADD Priority INT NOT NULL AFTER AdminInterfaceLang; UPDATE Language SET AdminInterfaceLang = 1 WHERE PrimaryLang = 1; DELETE FROM PersistantSessionData WHERE VariableName = 'lang_columns_.'; ALTER TABLE SessionData CHANGE VariableValue VariableValue longtext NOT NULL; INSERT INTO ConfigurationAdmin VALUES ('CSVExportDelimiter', 'la_Text_CSV_Export', 'la_config_CSVExportDelimiter', 'select', NULL, '0=la_Tab,1=la_Comma,2=la_Semicolon,3=la_Space,4=la_Colon', 40.1, 0, 1); INSERT INTO ConfigurationAdmin VALUES ('CSVExportEnclosure', 'la_Text_CSV_Export', 'la_config_CSVExportEnclosure', 'radio', NULL, '0=la_Doublequotes,1=la_Quotes', 40.2, 0, 1); INSERT INTO ConfigurationAdmin VALUES ('CSVExportSeparator', 'la_Text_CSV_Export', 'la_config_CSVExportSeparator', 'radio', NULL, '0=la_Linux,1=la_Windows', 40.3, 0, 1); INSERT INTO ConfigurationAdmin VALUES ('CSVExportEncoding', 'la_Text_CSV_Export', 'la_config_CSVExportEncoding', 'radio', NULL, '0=la_Unicode,1=la_Regular', 40.4, 0, 1); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CSVExportDelimiter', '0', 'In-Portal', 'in-portal:configure_general'); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CSVExportEnclosure', '0', 'In-Portal', 'in-portal:configure_general'); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CSVExportSeparator', '0', 'In-Portal', 'in-portal:configure_general'); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CSVExportEncoding', '0', 'In-Portal', 'in-portal:configure_general'); # ===== v 4.2.2 ===== INSERT INTO ConfigurationAdmin VALUES ('UseColumnFreezer', 'la_Text_Website', 'la_config_UseColumnFreezer', 'checkbox', '', '', 10.22, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'UseColumnFreezer', '0', 'In-Portal', 'in-portal:configure_general'); INSERT INTO ConfigurationAdmin VALUES ('TrimRequiredFields', 'la_Text_Website', 'la_config_TrimRequiredFields', 'checkbox', '', '', 10.23, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'TrimRequiredFields', '0', 'In-Portal', 'in-portal:configure_general'); INSERT INTO ConfigurationAdmin VALUES ('MenuFrameWidth', 'la_title_General', 'la_prompt_MenuFrameWidth', 'text', NULL, NULL, '11', '0', '0'); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'MenuFrameWidth', 200, 'In-Portal', 'in-portal:configure_general'); INSERT INTO ConfigurationAdmin VALUES ('DefaultSettingsUserId', 'la_title_General', 'la_prompt_DefaultUserId', 'text', NULL, NULL, '12', '0', '0'); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'DefaultSettingsUserId', -1, 'In-Portal', 'in-portal:configure_general'); INSERT INTO ConfigurationAdmin VALUES ('KeepSessionOnBrowserClose', 'la_title_General', 'la_prompt_KeepSessionOnBrowserClose', 'checkbox', NULL, NULL, '13', '0', '0'); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'KeepSessionOnBrowserClose', 0, 'In-Portal', 'in-portal:configure_general'); ALTER TABLE PersistantSessionData ADD VariableId BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST; # ===== v 4.3.0 ===== INSERT INTO ConfigurationAdmin VALUES ('u_MaxImageCount', 'la_section_ImageSettings', 'la_config_MaxImageCount', 'text', '', '', 30.01, 0, 0); INSERT INTO ConfigurationAdmin VALUES ('u_ThumbnailImageWidth', 'la_section_ImageSettings', 'la_config_ThumbnailImageWidth', 'text', '', '', 30.02, 0, 0); INSERT INTO ConfigurationAdmin VALUES ('u_ThumbnailImageHeight', 'la_section_ImageSettings', 'la_config_ThumbnailImageHeight', 'text', '', '', 30.03, 0, 0); INSERT INTO ConfigurationAdmin VALUES ('u_FullImageWidth', 'la_section_ImageSettings', 'la_config_FullImageWidth', 'text', '', '', 30.04, 0, 0); INSERT INTO ConfigurationAdmin VALUES ('u_FullImageHeight', 'la_section_ImageSettings', 'la_config_FullImageHeight', 'text', '', '', 30.05, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'u_MaxImageCount', 5, 'In-Portal:Users', 'in-portal:configure_users'); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'u_ThumbnailImageWidth', 120, 'In-Portal:Users', 'in-portal:configure_users'); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'u_ThumbnailImageHeight', 120, 'In-Portal:Users', 'in-portal:configure_users'); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'u_FullImageWidth', 450, 'In-Portal:Users', 'in-portal:configure_users'); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'u_FullImageHeight', 450, 'In-Portal:Users', 'in-portal:configure_users'); CREATE TABLE ChangeLogs ( ChangeLogId bigint(20) NOT NULL auto_increment, PortalUserId int(11) NOT NULL default '0', SessionLogId int(11) NOT NULL default '0', `Action` tinyint(4) NOT NULL default '0', OccuredOn int(11) NOT NULL default '0', Prefix varchar(255) NOT NULL default '', ItemId bigint(20) NOT NULL default '0', Changes text NOT NULL, MasterPrefix varchar(255) NOT NULL default '', MasterId bigint(20) NOT NULL default '0', PRIMARY KEY (ChangeLogId), KEY PortalUserId (PortalUserId), KEY SessionLogId (SessionLogId), KEY `Action` (`Action`), KEY OccuredOn (OccuredOn), KEY Prefix (Prefix), KEY MasterPrefix (MasterPrefix) ); CREATE TABLE SessionLogs ( SessionLogId bigint(20) NOT NULL auto_increment, PortalUserId int(11) NOT NULL default '0', SessionId int(10) NOT NULL default '0', `Status` tinyint(4) NOT NULL default '1', SessionStart int(11) NOT NULL default '0', SessionEnd int(11) default NULL, IP varchar(15) NOT NULL default '', AffectedItems int(11) NOT NULL default '0', PRIMARY KEY (SessionLogId), KEY SessionId (SessionId), KEY `Status` (`Status`), KEY PortalUserId (PortalUserId) ); ALTER TABLE CustomField ADD INDEX (MultiLingual), ADD INDEX (DisplayOrder), ADD INDEX (OnGeneralTab), ADD INDEX (IsSystem); ALTER TABLE ConfigurationAdmin ADD INDEX (DisplayOrder), ADD INDEX (GroupDisplayOrder), ADD INDEX (Install); ALTER TABLE EmailSubscribers ADD INDEX (EmailMessageId), ADD INDEX (PortalUserId); ALTER TABLE Events ADD INDEX (`Type`), ADD INDEX (Enabled); ALTER TABLE Language ADD INDEX (Enabled), ADD INDEX (PrimaryLang), ADD INDEX (AdminInterfaceLang), ADD INDEX (Priority); ALTER TABLE Modules ADD INDEX (Loaded), ADD INDEX (LoadOrder); ALTER TABLE PhraseCache ADD INDEX (CacheDate), ADD INDEX (ThemeId), ADD INDEX (StylesheetId); ALTER TABLE PortalGroup ADD INDEX (CreatedOn); ALTER TABLE PortalUser ADD INDEX (Status), ADD INDEX (Modified), ADD INDEX (dob), ADD INDEX (IsBanned); ALTER TABLE Theme ADD INDEX (Enabled), ADD INDEX (StylesheetId), ADD INDEX (PrimaryTheme); ALTER TABLE UserGroup ADD INDEX (MembershipExpires), ADD INDEX (ExpirationReminderSent); ALTER TABLE EmailLog ADD INDEX (`timestamp`); ALTER TABLE StdDestinations ADD INDEX (DestType), ADD INDEX (DestParentId); ALTER TABLE Category ADD INDEX (Status), ADD INDEX (CreatedOn), ADD INDEX (EditorsPick); ALTER TABLE Stylesheets ADD INDEX (Enabled), ADD INDEX (LastCompiled); ALTER TABLE Counters ADD INDEX (IsClone), ADD INDEX (LifeTime), ADD INDEX (LastCounted); ALTER TABLE Skins ADD INDEX (IsPrimary), ADD INDEX (LastCompiled); INSERT INTO ConfigurationAdmin VALUES ('UseChangeLog', 'la_Text_Website', 'la_config_UseChangeLog', 'checkbox', '', '', 10.25, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'UseChangeLog', '0', 'In-Portal', 'in-portal:configure_general'); INSERT INTO ConfigurationAdmin VALUES ('AutoRefreshIntervals', 'la_Text_Website', 'la_config_AutoRefreshIntervals', 'text', '', '', 10.26, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'AutoRefreshIntervals', '1,5,15,30,60,120,240', 'In-Portal', 'in-portal:configure_general'); DELETE FROM Cache WHERE SUBSTRING(VarName, 1, 7) = 'mod_rw_'; ALTER TABLE Category CHANGE `Status` `Status` TINYINT(4) NOT NULL DEFAULT '2'; # ===== v 4.3.1 ===== INSERT INTO ConfigurationAdmin VALUES ('RememberLastAdminTemplate', 'la_Text_General', 'la_config_RememberLastAdminTemplate', 'checkbox', '', '', 10.13, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'RememberLastAdminTemplate', '', 'In-Portal:Users', 'in-portal:configure_users'); INSERT INTO ConfigurationAdmin VALUES ('AllowSelectGroupOnFront', 'la_Text_General', 'la_config_AllowSelectGroupOnFront', 'checkbox', NULL, NULL, 10.13, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'AllowSelectGroupOnFront', '0', 'In-Portal:Users', 'in-portal:configure_users'); CREATE TABLE StatisticsCapture ( StatisticsId int(10) unsigned NOT NULL auto_increment, TemplateName varchar(255) NOT NULL default '', Hits int(10) unsigned NOT NULL default '0', LastHit int(11) NOT NULL default '0', ScriptTimeMin decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', ScriptTimeAvg decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', ScriptTimeMax decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', SqlTimeMin decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', SqlTimeAvg decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', SqlTimeMax decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', SqlCountMin decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', SqlCountAvg decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', SqlCountMax decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', PRIMARY KEY (StatisticsId), KEY TemplateName (TemplateName), KEY Hits (Hits), KEY LastHit (LastHit), KEY ScriptTimeMin (ScriptTimeMin), KEY ScriptTimeAvg (ScriptTimeAvg), KEY ScriptTimeMax (ScriptTimeMax), KEY SqlTimeMin (SqlTimeMin), KEY SqlTimeAvg (SqlTimeAvg), KEY SqlTimeMax (SqlTimeMax), KEY SqlCountMin (SqlCountMin), KEY SqlCountAvg (SqlCountAvg), KEY SqlCountMax (SqlCountMax) ); CREATE TABLE SlowSqlCapture ( CaptureId int(10) unsigned NOT NULL auto_increment, TemplateNames text, Hits int(10) unsigned NOT NULL default '0', LastHit int(11) NOT NULL default '0', SqlQuery text, TimeMin decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', TimeAvg decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', TimeMax decimal(40,20) unsigned NOT NULL default '0.00000000000000000000', QueryCrc int(11) NOT NULL default '0', PRIMARY KEY (CaptureId), KEY Hits (Hits), KEY LastHit (LastHit), KEY TimeMin (TimeMin), KEY TimeAvg (TimeAvg), KEY TimeMax (TimeMax), KEY QueryCrc (QueryCrc) ); ALTER TABLE PortalGroup ADD FrontRegistration TINYINT UNSIGNED NOT NULL; UPDATE PortalGroup SET FrontRegistration = 1 WHERE GroupId = 13; INSERT INTO ConfigurationAdmin VALUES ('ForceImageMagickResize', 'la_Text_Website', 'la_config_ForceImageMagickResize', 'checkbox', '', '', 10.28, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'ForceImageMagickResize', '0', 'In-Portal', 'in-portal:configure_general'); INSERT INTO ConfigurationAdmin VALUES ('AdminSSL_URL', 'la_Text_Website', 'la_config_AdminSSL_URL', 'text', '', '', 10.091, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'AdminSSL_URL', '', 'In-Portal', 'in-portal:configure_general'); # ===== v 4.3.9 ===== ALTER TABLE CustomField CHANGE ValueList ValueList TEXT NULL DEFAULT NULL, ADD DefaultValue VARCHAR(255) NOT NULL AFTER ValueList, ADD INDEX (DefaultValue); UPDATE CustomField SET ValueList = REPLACE(ValueList, ',', '||'); CREATE TABLE Agents ( AgentId int(11) NOT NULL auto_increment, AgentName varchar(255) NOT NULL default '', AgentType tinyint(3) unsigned NOT NULL default '1', Status tinyint(3) unsigned NOT NULL default '1', Event varchar(255) NOT NULL default '', RunInterval int(10) unsigned NOT NULL default '0', RunMode tinyint(3) unsigned NOT NULL default '2', LastRunOn int(10) unsigned default NULL, LastRunStatus tinyint(3) unsigned NOT NULL default '1', NextRunOn int(11) default NULL, RunTime int(10) unsigned NOT NULL default '0', PRIMARY KEY (AgentId), KEY Status (Status), KEY RunInterval (RunInterval), KEY RunMode (RunMode), KEY AgentType (AgentType), KEY LastRunOn (LastRunOn), KEY LastRunStatus (LastRunStatus), KEY RunTime (RunTime), KEY NextRunOn (NextRunOn) ); INSERT INTO Permissions VALUES(DEFAULT, 'in-portal:agents.delete', 11, 1, 1, 0); INSERT INTO Permissions VALUES(DEFAULT, 'in-portal:agents.edit', 11, 1, 1, 0); INSERT INTO Permissions VALUES(DEFAULT, 'in-portal:agents.add', 11, 1, 1, 0); INSERT INTO Permissions VALUES(DEFAULT, 'in-portal:agents.view', 11, 1, 1, 0); INSERT INTO ConfigurationAdmin VALUES ('FilenameSpecialCharReplacement', 'la_Text_General', 'la_config_FilenameSpecialCharReplacement', 'select', NULL, '_=+_,-=+-', 10.16, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'FilenameSpecialCharReplacement', '_', 'In-Portal', 'in-portal:configure_categories'); CREATE TABLE SpellingDictionary ( SpellingDictionaryId int(11) NOT NULL auto_increment, MisspelledWord varchar(255) NOT NULL default '', SuggestedCorrection varchar(255) NOT NULL default '', PRIMARY KEY (SpellingDictionaryId), KEY MisspelledWord (MisspelledWord), KEY SuggestedCorrection (SuggestedCorrection) ); INSERT INTO ConfigurationValues VALUES(NULL, 'YahooApplicationId', '', 'In-Portal', 'in-portal:configure_categories'); INSERT INTO ConfigurationAdmin VALUES('YahooApplicationId', 'la_Text_General', 'la_config_YahooApplicationId', 'text', NULL, NULL, 10.15, 0, 0); CREATE TABLE Thesaurus ( ThesaurusId int(11) NOT NULL auto_increment, SearchTerm varchar(255) NOT NULL default '', ThesaurusTerm varchar(255) NOT NULL default '', ThesaurusType tinyint(3) unsigned NOT NULL default '0', PRIMARY KEY (ThesaurusId), KEY ThesaurusType (ThesaurusType), KEY SearchTerm (SearchTerm) ); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:ban_rulelist.delete', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:ban_rulelist.edit', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:ban_rulelist.add', 11, 1, 1, 0); ALTER TABLE Language ADD FilenameReplacements TEXT NULL AFTER UnitSystem; ALTER TABLE Language ADD Locale varchar(10) NOT NULL default 'en-US' AFTER FilenameReplacements; CREATE TABLE LocalesList ( LocaleId int(11) NOT NULL auto_increment, LocaleIdentifier varchar(6) NOT NULL default '', LocaleName varchar(255) NOT NULL default '', Locale varchar(20) NOT NULL default '', ScriptTag varchar(255) NOT NULL default '', ANSICodePage varchar(10) NOT NULL default '', PRIMARY KEY (LocaleId) ); INSERT INTO LocalesList VALUES (1, '0x0436', 'Afrikaans (South Africa)', 'af-ZA', 'Latn', '1252'), (2, '0x041c', 'Albanian (Albania)', 'sq-AL', 'Latn', '1252'), (3, '0x0484', 'Alsatian (France)', 'gsw-FR', '', ''), (4, '0x045e', 'Amharic (Ethiopia)', 'am-ET', '', 'UTF-8'), (5, '0x1401', 'Arabic (Algeria)', 'ar-DZ', 'Arab', '1256'), (6, '0x3c01', 'Arabic (Bahrain)', 'ar-BH', 'Arab', '1256'), (7, '0x0c01', 'Arabic (Egypt)', 'ar-EG', 'Arab', '1256'), (8, '0x0801', 'Arabic (Iraq)', 'ar-IQ', 'Arab', '1256'), (9, '0x2c01', 'Arabic (Jordan)', 'ar-JO', 'Arab', '1256'), (10, '0x3401', 'Arabic (Kuwait)', 'ar-KW', 'Arab', '1256'), (11, '0x3001', 'Arabic (Lebanon)', 'ar-LB', 'Arab', '1256'), (12, '0x1001', 'Arabic (Libya)', 'ar-LY', 'Arab', '1256'), (13, '0x1801', 'Arabic (Morocco)', 'ar-MA', 'Arab', '1256'), (14, '0x2001', 'Arabic (Oman)', 'ar-OM', 'Arab', '1256'), (15, '0x4001', 'Arabic (Qatar)', 'ar-QA', 'Arab', '1256'), (16, '0x0401', 'Arabic (Saudi Arabia)', 'ar-SA', 'Arab', '1256'), (17, '0x2801', 'Arabic (Syria)', 'ar-SY', 'Arab', '1256'), (18, '0x1c01', 'Arabic (Tunisia)', 'ar-TN', 'Arab', '1256'), (19, '0x3801', 'Arabic (U.A.E.)', 'ar-AE', 'Arab', '1256'), (20, '0x2401', 'Arabic (Yemen)', 'ar-YE', 'Arab', '1256'), (21, '0x042b', 'Armenian (Armenia)', 'hy-AM', 'Armn', 'UTF-8'), (22, '0x044d', 'Assamese (India)', 'as-IN', '', 'UTF-8'), (23, '0x082c', 'Azeri (Azerbaijan, Cyrillic)', 'az-Cyrl-AZ', 'Cyrl', '1251'), (24, '0x042c', 'Azeri (Azerbaijan, Latin)', 'az-Latn-AZ', 'Latn', '1254'), (25, '0x046d', 'Bashkir (Russia)', 'ba-RU', '', ''), (26, '0x042d', 'Basque (Basque)', 'eu-ES', 'Latn', '1252'), (27, '0x0423', 'Belarusian (Belarus)', 'be-BY', 'Cyrl', '1251'), (28, '0x0445', 'Bengali (India)', 'bn-IN', 'Beng', 'UTF-8'), (29, '0x201a', 'Bosnian (Bosnia and Herzegovina, Cyrillic)', 'bs-Cyrl-BA', 'Cyrl', '1251'), (30, '0x141a', 'Bosnian (Bosnia and Herzegovina, Latin)', 'bs-Latn-BA', 'Latn', '1250'), (31, '0x047e', 'Breton (France)', 'br-FR', 'Latn', '1252'), (32, '0x0402', 'Bulgarian (Bulgaria)', 'bg-BG', 'Cyrl', '1251'), (33, '0x0403', 'Catalan (Catalan)', 'ca-ES', 'Latn', '1252'), (34, '0x0c04', 'Chinese (Hong Kong SAR, PRC)', 'zh-HK', 'Hant', '950'), (35, '0x1404', 'Chinese (Macao SAR)', 'zh-MO', 'Hant', '950'), (36, '0x0804', 'Chinese (PRC)', 'zh-CN', 'Hans', '936'), (37, '0x1004', 'Chinese (Singapore)', 'zh-SG', 'Hans', '936'), (38, '0x0404', 'Chinese (Taiwan)', 'zh-TW', 'Hant', '950'), (39, '0x101a', 'Croatian (Bosnia and Herzegovina, Latin)', 'hr-BA', 'Latn', '1250'), (40, '0x041a', 'Croatian (Croatia)', 'hr-HR', 'Latn', '1250'), (41, '0x0405', 'Czech (Czech Republic)', 'cs-CZ', 'Latn', '1250'), (42, '0x0406', 'Danish (Denmark)', 'da-DK', 'Latn', '1252'), (43, '0x048c', 'Dari (Afghanistan)', 'prs-AF', 'Arab', '1256'), (44, '0x0465', 'Divehi (Maldives)', 'dv-MV', 'Thaa', 'UTF-8'), (45, '0x0813', 'Dutch (Belgium)', 'nl-BE', 'Latn', '1252'), (46, '0x0413', 'Dutch (Netherlands)', 'nl-NL', 'Latn', '1252'), (47, '0x0c09', 'English (Australia)', 'en-AU', 'Latn', '1252'), (48, '0x2809', 'English (Belize)', 'en-BZ', 'Latn', '1252'), (49, '0x1009', 'English (Canada)', 'en-CA', 'Latn', '1252'), (50, '0x2409', 'English (Caribbean)', 'en-029', 'Latn', '1252'), (51, '0x4009', 'English (India)', 'en-IN', 'Latn', '1252'), (52, '0x1809', 'English (Ireland)', 'en-IE', 'Latn', '1252'), (53, '0x2009', 'English (Jamaica)', 'en-JM', 'Latn', '1252'), (54, '0x4409', 'English (Malaysia)', 'en-MY', 'Latn', '1252'), (55, '0x1409', 'English (New Zealand)', 'en-NZ', 'Latn', '1252'), (56, '0x3409', 'English (Philippines)', 'en-PH', 'Latn', '1252'), (57, '0x4809', 'English (Singapore)', 'en-SG', 'Latn', '1252'), (58, '0x1c09', 'English (South Africa)', 'en-ZA', 'Latn', '1252'), (59, '0x2c09', 'English (Trinidad and Tobago)', 'en-TT', 'Latn', '1252'), (60, '0x0809', 'English (United Kingdom)', 'en-GB', 'Latn', '1252'), (61, '0x0409', 'English (United States)', 'en-US', 'Latn', '1252'), (62, '0x3009', 'English (Zimbabwe)', 'en-ZW', 'Latn', '1252'), (63, '0x0425', 'Estonian (Estonia)', 'et-EE', 'Latn', '1257'), (64, '0x0438', 'Faroese (Faroe Islands)', 'fo-FO', 'Latn', '1252'), (65, '0x0464', 'Filipino (Philippines)', 'fil-PH', 'Latn', '1252'), (66, '0x040b', 'Finnish (Finland)', 'fi-FI', 'Latn', '1252'), (67, '0x080c', 'French (Belgium)', 'fr-BE', 'Latn', '1252'), (68, '0x0c0c', 'French (Canada)', 'fr-CA', 'Latn', '1252'), (69, '0x040c', 'French (France)', 'fr-FR', 'Latn', '1252'), (70, '0x140c', 'French (Luxembourg)', 'fr-LU', 'Latn', '1252'), (71, '0x180c', 'French (Monaco)', 'fr-MC', 'Latn', '1252'), (72, '0x100c', 'French (Switzerland)', 'fr-CH', 'Latn', '1252'), (73, '0x0462', 'Frisian (Netherlands)', 'fy-NL', 'Latn', '1252'), (74, '0x0456', 'Galician (Spain)', 'gl-ES', 'Latn', '1252'), (75, '0x0437', 'Georgian (Georgia)', 'ka-GE', 'Geor', 'UTF-8'), (76, '0x0c07', 'German (Austria)', 'de-AT', 'Latn', '1252'), (77, '0x0407', 'German (Germany)', 'de-DE', 'Latn', '1252'), (78, '0x1407', 'German (Liechtenstein)', 'de-LI', 'Latn', '1252'), (79, '0x1007', 'German (Luxembourg)', 'de-LU', 'Latn', '1252'), (80, '0x0807', 'German (Switzerland)', 'de-CH', 'Latn', '1252'), (81, '0x0408', 'Greek (Greece)', 'el-GR', 'Grek', '1253'), (82, '0x046f', 'Greenlandic (Greenland)', 'kl-GL', 'Latn', '1252'), (83, '0x0447', 'Gujarati (India)', 'gu-IN', 'Gujr', 'UTF-8'), (84, '0x0468', 'Hausa (Nigeria, Latin)', 'ha-Latn-NG', 'Latn', '1252'), (85, '0x040d', 'Hebrew (Israel)', 'he-IL', 'Hebr', '1255'), (86, '0x0439', 'Hindi (India)', 'hi-IN', 'Deva', 'UTF-8'), (87, '0x040e', 'Hungarian (Hungary)', 'hu-HU', 'Latn', '1250'), (88, '0x040f', 'Icelandic (Iceland)', 'is-IS', 'Latn', '1252'), (89, '0x0470', 'Igbo (Nigeria)', 'ig-NG', '', ''), (90, '0x0421', 'Indonesian (Indonesia)', 'id-ID', 'Latn', '1252'), (91, '0x085d', 'Inuktitut (Canada, Latin)', 'iu-Latn-CA', 'Latn', '1252'), (92, '0x045d', 'Inuktitut (Canada, Syllabics)', 'iu-Cans-CA', 'Cans', 'UTF-8'), (93, '0x083c', 'Irish (Ireland)', 'ga-IE', 'Latn', '1252'), (94, '0x0410', 'Italian (Italy)', 'it-IT', 'Latn', '1252'), (95, '0x0810', 'Italian (Switzerland)', 'it-CH', 'Latn', '1252'), (96, '0x0411', 'Japanese (Japan)', 'ja-JP', 'Hani;Hira;Kana', '932'), (97, '0x044b', 'Kannada (India)', 'kn-IN', 'Knda', 'UTF-8'), (98, '0x043f', 'Kazakh (Kazakhstan)', 'kk-KZ', 'Cyrl', '1251'), (99, '0x0453', 'Khmer (Cambodia)', 'kh-KH', 'Khmr', 'UTF-8'), (100, '0x0486', 'K''iche (Guatemala)', 'qut-GT', 'Latn', '1252'), (101, '0x0487', 'Kinyarwanda (Rwanda)', 'rw-RW', 'Latn', '1252'), (102, '0x0457', 'Konkani (India)', 'kok-IN', 'Deva', 'UTF-8'), (103, '0x0812', 'Windows 95, Windows NT 4.0 only: Korean (Johab)', '', '', ''), (104, '0x0412', 'Korean (Korea)', 'ko-KR', 'Hang;Hani', '949'), (105, '0x0440', 'Kyrgyz (Kyrgyzstan)', 'ky-KG', 'Cyrl', '1251'), (106, '0x0454', 'Lao (Lao PDR)', 'lo-LA', 'Laoo', 'UTF-8'), (107, '0x0426', 'Latvian (Latvia)', 'lv-LV', 'Latn', '1257'), (108, '0x0427', 'Lithuanian (Lithuania)', 'lt-LT', 'Latn', '1257'), (109, '0x082e', 'Lower Sorbian (Germany)', 'dsb-DE', 'Latn', '1252'), (110, '0x046e', 'Luxembourgish (Luxembourg)', 'lb-LU', 'Latn', '1252'), (111, '0x042f', 'Macedonian (Macedonia, FYROM)', 'mk-MK', 'Cyrl', '1251'), (112, '0x083e', 'Malay (Brunei Darussalam)', 'ms-BN', 'Latn', '1252'), (113, '0x043e', 'Malay (Malaysia)', 'ms-MY', 'Latn', '1252'), (114, '0x044c', 'Malayalam (India)', 'ml-IN', 'Mlym', 'UTF-8'), (115, '0x043a', 'Maltese (Malta)', 'mt-MT', 'Latn', '1252'), (116, '0x0481', 'Maori (New Zealand)', 'mi-NZ', 'Latn', '1252'), (117, '0x047a', 'Mapudungun (Chile)', 'arn-CL', 'Latn', '1252'), (118, '0x044e', 'Marathi (India)', 'mr-IN', 'Deva', 'UTF-8'), (119, '0x047c', 'Mohawk (Canada)', 'moh-CA', 'Latn', '1252'), (120, '0x0450', 'Mongolian (Mongolia)', 'mn-Cyrl-MN', 'Cyrl', '1251'), (121, '0x0850', 'Mongolian (PRC)', 'mn-Mong-CN', 'Mong', 'UTF-8'), (122, '0x0850', 'Nepali (India)', 'ne-IN', '__', 'UTF-8'), (123, '0x0461', 'Nepali (Nepal)', 'ne-NP', 'Deva', 'UTF-8'), (124, '0x0414', 'Norwegian (Bokmål, Norway)', 'nb-NO', 'Latn', '1252'), (125, '0x0814', 'Norwegian (Nynorsk, Norway)', 'nn-NO', 'Latn', '1252'), (126, '0x0482', 'Occitan (France)', 'oc-FR', 'Latn', '1252'), (127, '0x0448', 'Oriya (India)', 'or-IN', 'Orya', 'UTF-8'), (128, '0x0463', 'Pashto (Afghanistan)', 'ps-AF', '', ''), (129, '0x0429', 'Persian (Iran)', 'fa-IR', 'Arab', '1256'), (130, '0x0415', 'Polish (Poland)', 'pl-PL', 'Latn', '1250'), (131, '0x0416', 'Portuguese (Brazil)', 'pt-BR', 'Latn', '1252'), (132, '0x0816', 'Portuguese (Portugal)', 'pt-PT', 'Latn', '1252'), (133, '0x0446', 'Punjabi (India)', 'pa-IN', 'Guru', 'UTF-8'), (134, '0x046b', 'Quechua (Bolivia)', 'quz-BO', 'Latn', '1252'), (135, '0x086b', 'Quechua (Ecuador)', 'quz-EC', 'Latn', '1252'), (136, '0x0c6b', 'Quechua (Peru)', 'quz-PE', 'Latn', '1252'), (137, '0x0418', 'Romanian (Romania)', 'ro-RO', 'Latn', '1250'), (138, '0x0417', 'Romansh (Switzerland)', 'rm-CH', 'Latn', '1252'), (139, '0x0419', 'Russian (Russia)', 'ru-RU', 'Cyrl', '1251'), (140, '0x243b', 'Sami (Inari, Finland)', 'smn-FI', 'Latn', '1252'), (141, '0x103b', 'Sami (Lule, Norway)', 'smj-NO', 'Latn', '1252'), (142, '0x143b', 'Sami (Lule, Sweden)', 'smj-SE', 'Latn', '1252'), (143, '0x0c3b', 'Sami (Northern, Finland)', 'se-FI', 'Latn', '1252'), (144, '0x043b', 'Sami (Northern, Norway)', 'se-NO', 'Latn', '1252'), (145, '0x083b', 'Sami (Northern, Sweden)', 'se-SE', 'Latn', '1252'), (146, '0x203b', 'Sami (Skolt, Finland)', 'sms-FI', 'Latn', '1252'), (147, '0x183b', 'Sami (Southern, Norway)', 'sma-NO', 'Latn', '1252'), (148, '0x1c3b', 'Sami (Southern, Sweden)', 'sma-SE', 'Latn', '1252'), (149, '0x044f', 'Sanskrit (India)', 'sa-IN', 'Deva', 'UTF-8'), (150, '0x1c1a', 'Serbian (Bosnia and Herzegovina, Cyrillic)', 'sr-Cyrl-BA', 'Cyrl', '1251'), (151, '0x181a', 'Serbian (Bosnia and Herzegovina, Latin)', 'sr-Latn-BA', 'Latn', '1250'), (152, '0x0c1a', 'Serbian (Serbia, Cyrillic)', 'sr-Cyrl-CS', 'Cyrl', '1251'), (153, '0x081a', 'Serbian (Serbia, Latin)', 'sr-Latn-CS', 'Latn', '1250'), (154, '0x046c', 'Sesotho sa Leboa/Northern Sotho (South Africa)', 'ns-ZA', 'Latn', '1252'), (155, '0x0432', 'Setswana/Tswana (South Africa)', 'tn-ZA', 'Latn', '1252'), (156, '0x045b', 'Sinhala (Sri Lanka)', 'si-LK', 'Sinh', 'UTF-8'), (157, '0x041b', 'Slovak (Slovakia)', 'sk-SK', 'Latn', '1250'), (158, '0x0424', 'Slovenian (Slovenia)', 'sl-SI', 'Latn', '1250'), (159, '0x2c0a', 'Spanish (Argentina)', 'es-AR', 'Latn', '1252'), (160, '0x400a', 'Spanish (Bolivia)', 'es-BO', 'Latn', '1252'), (161, '0x340a', 'Spanish (Chile)', 'es-CL', 'Latn', '1252'), (162, '0x240a', 'Spanish (Colombia)', 'es-CO', 'Latn', '1252'), (163, '0x140a', 'Spanish (Costa Rica)', 'es-CR', 'Latn', '1252'), (164, '0x1c0a', 'Spanish (Dominican Republic)', 'es-DO', 'Latn', '1252'), (165, '0x300a', 'Spanish (Ecuador)', 'es-EC', 'Latn', '1252'), (166, '0x440a', 'Spanish (El Salvador)', 'es-SV', 'Latn', '1252'), (167, '0x100a', 'Spanish (Guatemala)', 'es-GT', 'Latn', '1252'), (168, '0x480a', 'Spanish (Honduras)', 'es-HN', 'Latn', '1252'), (169, '0x080a', 'Spanish (Mexico)', 'es-MX', 'Latn', '1252'), (170, '0x4c0a', 'Spanish (Nicaragua)', 'es-NI', 'Latn', '1252'), (171, '0x180a', 'Spanish (Panama)', 'es-PA', 'Latn', '1252'), (172, '0x3c0a', 'Spanish (Paraguay)', 'es-PY', 'Latn', '1252'), (173, '0x280a', 'Spanish (Peru)', 'es-PE', 'Latn', '1252'), (174, '0x500a', 'Spanish (Puerto Rico)', 'es-PR', 'Latn', '1252'), (175, '0x0c0a', 'Spanish (Spain)', 'es-ES', 'Latn', '1252'), (176, '0x040a', 'Spanish (Spain, Traditional Sort)', 'es-ES_tradnl', 'Latn', '1252'), (177, '0x540a', 'Spanish (United States)', 'es-US', '', ''), (178, '0x380a', 'Spanish (Uruguay)', 'es-UY', 'Latn', '1252'), (179, '0x200a', 'Spanish (Venezuela)', 'es-VE', 'Latn', '1252'), (180, '0x0441', 'Swahili (Kenya)', 'sw-KE', 'Latn', '1252'), (181, '0x081d', 'Swedish (Finland)', 'sv-FI', 'Latn', '1252'), (182, '0x041d', 'Swedish (Sweden)', 'sv-SE', 'Latn', '1252'), (183, '0x045a', 'Syriac (Syria)', 'syr-SY', 'Syrc', 'UTF-8'), (184, '0x0428', 'Tajik (Tajikistan)', 'tg-Cyrl-TJ', 'Cyrl', '1251'), (185, '0x085f', 'Tamazight (Algeria, Latin)', 'tzm-Latn-DZ', 'Latn', '1252'), (186, '0x0449', 'Tamil (India)', 'ta-IN', 'Taml', 'UTF-8'), (187, '0x0444', 'Tatar (Russia)', 'tt-RU', 'Cyrl', '1251'), (188, '0x044a', 'Telugu (India)', 'te-IN', 'Telu', 'UTF-8'), (189, '0x041e', 'Thai (Thailand)', 'th-TH', 'Thai', '874'), (190, '0x0851', 'Tibetan (Bhutan)', 'bo-BT', 'Tibt', 'UTF-8'), (191, '0x0451', 'Tibetan (PRC)', 'bo-CN', 'Tibt', 'UTF-8'), (192, '0x041f', 'Turkish (Turkey)', 'tr-TR', 'Latn', '1254'), (193, '0x0442', 'Turkmen (Turkmenistan)', 'tk-TM', 'Cyrl', '1251'), (194, '0x0480', 'Uighur (PRC)', 'ug-CN', 'Arab', '1256'), (195, '0x0422', 'Ukrainian (Ukraine)', 'uk-UA', 'Cyrl', '1251'), (196, '0x042e', 'Upper Sorbian (Germany)', 'wen-DE', 'Latn', '1252'), (197, '0x0820', 'Urdu (India)', 'tr-IN', '', ''), (198, '0x0420', 'Urdu (Pakistan)', 'ur-PK', 'Arab', '1256'), (199, '0x0843', 'Uzbek (Uzbekistan, Cyrillic)', 'uz-Cyrl-UZ', 'Cyrl', '1251'), (200, '0x0443', 'Uzbek (Uzbekistan, Latin)', 'uz-Latn-UZ', 'Latn', '1254'), (201, '0x042a', 'Vietnamese (Vietnam)', 'vi-VN', 'Latn', '1258'), (202, '0x0452', 'Welsh (United Kingdom)', 'cy-GB', 'Latn', '1252'), (203, '0x0488', 'Wolof (Senegal)', 'wo-SN', 'Latn', '1252'), (204, '0x0434', 'Xhosa/isiXhosa (South Africa)', 'xh-ZA', 'Latn', '1252'), (205, '0x0485', 'Yakut (Russia)', 'sah-RU', 'Cyrl', '1251'), (206, '0x0478', 'Yi (PRC)', 'ii-CN', 'Yiii', 'UTF-8'), (207, '0x046a', 'Yoruba (Nigeria)', 'yo-NG', '', ''), (208, '0x0435', 'Zulu/isiZulu (South Africa)', 'zu-ZA', 'Latn', '1252'); UPDATE Phrase SET Module = 'Core' WHERE Module IN ('Proj-Base', 'In-Portal'); UPDATE Phrase SET Module = 'Core' WHERE Phrase IN ('la_fld_Phone', 'la_fld_City', 'la_fld_State', 'la_fld_Zip'); UPDATE Phrase SET Module = 'Core' WHERE Phrase IN ('la_col_Image', 'la_col_Username', 'la_fld_AddressLine1', 'la_fld_AddressLine2', 'la_fld_Comments', 'la_fld_Country', 'la_fld_Email', 'la_fld_Language', 'la_fld_Login', 'la_fld_MessageText', 'la_fld_MetaDescription', 'la_fld_MetaKeywords', 'la_fld_Password', 'la_fld_Username', 'la_fld_Type'); UPDATE Phrase SET Phrase = 'la_Add' WHERE Phrase = 'LA_ADD'; UPDATE Phrase SET Phrase = 'la_col_MembershipExpires' WHERE Phrase = 'la_col_membershipexpires'; UPDATE Phrase SET Phrase = 'la_ShortToolTip_Clone' WHERE Phrase = 'la_shorttooltip_clone'; UPDATE Phrase SET Phrase = 'la_ShortToolTip_Edit' WHERE Phrase = 'LA_SHORTTOOLTIP_EDIT'; UPDATE Phrase SET Phrase = 'la_ShortToolTip_Export' WHERE Phrase = 'LA_SHORTTOOLTIP_EXPORT'; UPDATE Phrase SET Phrase = 'la_ShortToolTip_GoUp' WHERE Phrase = 'LA_SHORTTOOLTIP_GOUP'; UPDATE Phrase SET Phrase = 'la_ShortToolTip_Import' WHERE Phrase = 'LA_SHORTTOOLTIP_IMPORT'; UPDATE Phrase SET Phrase = 'la_ShortToolTip_MoveUp' WHERE Phrase = 'la_shorttooltip_moveup'; UPDATE Phrase SET Phrase = 'la_ShortToolTip_MoveDown' WHERE Phrase = 'la_shorttooltip_movedown'; UPDATE Phrase SET Phrase = 'la_ShortToolTip_RescanThemes' WHERE Phrase = 'la_shorttooltip_rescanthemes'; UPDATE Phrase SET Phrase = 'la_ShortToolTip_SetPrimary' WHERE Phrase = 'LA_SHORTTOOLTIP_SETPRIMARY'; UPDATE Phrase SET Phrase = 'la_ShortToolTip_Rebuild' WHERE Phrase = 'LA_SHORTTOOLTIP_REBUILD'; UPDATE Phrase SET Phrase = 'la_Tab_Service' WHERE Phrase = 'la_tab_service'; UPDATE Phrase SET Phrase = 'la_tab_Files' WHERE Phrase = 'la_tab_files'; UPDATE Phrase SET Phrase = 'la_ToolTipShort_Edit_Current_Category' WHERE Phrase = 'LA_TOOLTIPSHORT_EDIT_CURRENT_CATEGORY'; UPDATE Phrase SET Phrase = 'la_ToolTip_Add' WHERE Phrase = 'LA_TOOLTIP_ADD'; UPDATE Phrase SET Phrase = 'la_ToolTip_Add_Product' WHERE Phrase = 'LA_TOOLTIP_ADD_PRODUCT'; UPDATE Phrase SET Phrase = 'la_ToolTip_NewSearchConfig' WHERE Phrase = 'LA_TOOLTIP_NEWSEARCHCONFIG'; UPDATE Phrase SET Phrase = 'la_ToolTip_Prev' WHERE Phrase = 'la_tooltip_prev'; UPDATE Phrase SET Phrase = 'la_Invalid_Password' WHERE Phrase = 'la_invalid_password'; UPDATE Events SET Module = REPLACE(Module, 'In-Portal', 'Core'); DROP TABLE ImportScripts; CREATE TABLE BanRules ( RuleId int(11) NOT NULL auto_increment, RuleType tinyint(4) NOT NULL default '0', ItemField varchar(255) default NULL, ItemVerb tinyint(4) NOT NULL default '0', ItemValue varchar(255) NOT NULL default '', ItemType int(11) NOT NULL default '0', Priority int(11) NOT NULL default '0', Status tinyint(4) NOT NULL default '1', ErrorTag varchar(255) default NULL, PRIMARY KEY (RuleId), KEY Status (Status), KEY Priority (Priority), KEY ItemType (ItemType) ); CREATE TABLE CountCache ( ListType int(11) NOT NULL default '0', ItemType int(11) NOT NULL default '-1', Value int(11) NOT NULL default '0', CountCacheId int(11) NOT NULL auto_increment, LastUpdate int(11) NOT NULL default '0', ExtraId varchar(50) default NULL, TodayOnly tinyint(4) NOT NULL default '0', PRIMARY KEY (CountCacheId) ); CREATE TABLE Favorites ( FavoriteId int(11) NOT NULL auto_increment, PortalUserId int(11) NOT NULL default '0', ResourceId int(11) NOT NULL default '0', ItemTypeId int(11) NOT NULL default '0', Modified int(11) NOT NULL default '0', PRIMARY KEY (FavoriteId), UNIQUE KEY main (PortalUserId,ResourceId), KEY Modified (Modified), KEY ItemTypeId (ItemTypeId) ); CREATE TABLE Images ( ImageId int(11) NOT NULL auto_increment, ResourceId int(11) NOT NULL default '0', Url varchar(255) NOT NULL default '', Name varchar(255) NOT NULL default '', AltName VARCHAR(255) NOT NULL DEFAULT '', ImageIndex int(11) NOT NULL default '0', LocalImage tinyint(4) NOT NULL default '1', LocalPath varchar(240) NOT NULL default '', Enabled int(11) NOT NULL default '1', DefaultImg int(11) NOT NULL default '0', ThumbUrl varchar(255) default NULL, Priority int(11) NOT NULL default '0', ThumbPath varchar(255) default NULL, LocalThumb tinyint(4) NOT NULL default '1', SameImages tinyint(4) NOT NULL default '1', PRIMARY KEY (ImageId), KEY ResourceId (ResourceId), KEY Enabled (Enabled), KEY Priority (Priority) ); CREATE TABLE ItemRating ( RatingId int(11) NOT NULL auto_increment, IPAddress varchar(255) NOT NULL default '', CreatedOn INT UNSIGNED NULL DEFAULT NULL, RatingValue int(11) NOT NULL default '0', ItemId int(11) NOT NULL default '0', PRIMARY KEY (RatingId), KEY CreatedOn (CreatedOn), KEY ItemId (ItemId), KEY RatingValue (RatingValue) ); CREATE TABLE ItemReview ( ReviewId int(11) NOT NULL auto_increment, CreatedOn INT UNSIGNED NULL DEFAULT NULL, ReviewText longtext NOT NULL, Rating tinyint(3) unsigned default NULL, IPAddress varchar(255) NOT NULL default '', ItemId int(11) NOT NULL default '0', CreatedById int(11) NOT NULL default '-1', ItemType tinyint(4) NOT NULL default '0', Priority int(11) NOT NULL default '0', Status tinyint(4) NOT NULL default '2', TextFormat int(11) NOT NULL default '0', Module varchar(255) NOT NULL default '', PRIMARY KEY (ReviewId), KEY CreatedOn (CreatedOn), KEY ItemId (ItemId), KEY ItemType (ItemType), KEY Priority (Priority), KEY Status (Status) ); CREATE TABLE ItemTypes ( ItemType int(11) NOT NULL default '0', Module varchar(50) NOT NULL default '', Prefix varchar(20) NOT NULL default '', SourceTable varchar(100) NOT NULL default '', TitleField varchar(50) default NULL, CreatorField varchar(255) NOT NULL default '', PopField varchar(255) default NULL, RateField varchar(255) default NULL, LangVar varchar(255) NOT NULL default '', PrimaryItem int(11) NOT NULL default '0', EditUrl varchar(255) NOT NULL default '', ClassName varchar(40) NOT NULL default '', ItemName varchar(50) NOT NULL default '', PRIMARY KEY (ItemType), KEY Module (Module) ); CREATE TABLE ItemFiles ( FileId int(11) NOT NULL auto_increment, ResourceId int(11) unsigned NOT NULL default '0', FileName varchar(255) NOT NULL default '', FilePath varchar(255) NOT NULL default '', Size int(11) NOT NULL default '0', `Status` tinyint(4) NOT NULL default '1', CreatedOn int(11) unsigned NOT NULL default '0', CreatedById int(11) NOT NULL default '-1', MimeType varchar(255) NOT NULL default '', PRIMARY KEY (FileId), KEY ResourceId (ResourceId), KEY CreatedOn (CreatedOn), KEY Status (Status) ); CREATE TABLE Relationship ( RelationshipId int(11) NOT NULL auto_increment, SourceId int(11) default NULL, TargetId int(11) default NULL, SourceType tinyint(4) NOT NULL default '0', TargetType tinyint(4) NOT NULL default '0', Type int(11) NOT NULL default '0', Enabled int(11) NOT NULL default '1', Priority int(11) NOT NULL default '0', PRIMARY KEY (RelationshipId), KEY RelSource (SourceId), KEY RelTarget (TargetId), KEY `Type` (`Type`), KEY Enabled (Enabled), KEY Priority (Priority), KEY SourceType (SourceType), KEY TargetType (TargetType) ); CREATE TABLE SearchConfig ( TableName varchar(40) NOT NULL default '', FieldName varchar(40) NOT NULL default '', SimpleSearch tinyint(4) NOT NULL default '1', AdvancedSearch tinyint(4) NOT NULL default '1', Description varchar(255) default NULL, DisplayName varchar(80) default NULL, ModuleName VARCHAR(20) NOT NULL DEFAULT 'In-Portal', ConfigHeader varchar(255) default NULL, DisplayOrder int(11) NOT NULL default '0', SearchConfigId int(11) NOT NULL auto_increment, Priority int(11) NOT NULL default '0', FieldType varchar(20) NOT NULL default 'text', ForeignField TEXT, JoinClause TEXT, IsWhere text, IsNotWhere text, ContainsWhere text, NotContainsWhere text, CustomFieldId int(11) default NULL, PRIMARY KEY (SearchConfigId), KEY SimpleSearch (SimpleSearch), KEY AdvancedSearch (AdvancedSearch), KEY DisplayOrder (DisplayOrder), KEY Priority (Priority), KEY CustomFieldId (CustomFieldId) ); CREATE TABLE SearchLog ( SearchLogId int(11) NOT NULL auto_increment, Keyword varchar(255) NOT NULL default '', Indices bigint(20) NOT NULL default '0', SearchType int(11) NOT NULL default '0', PRIMARY KEY (SearchLogId), KEY SearchType (SearchType) ); CREATE TABLE IgnoreKeywords ( keyword varchar(20) NOT NULL default '', PRIMARY KEY (keyword) ); CREATE TABLE SpamControl ( ItemResourceId int(11) NOT NULL default '0', IPaddress varchar(20) NOT NULL default '', Expire INT UNSIGNED NULL DEFAULT NULL, PortalUserId int(11) NOT NULL default '0', DataType varchar(20) default NULL, KEY PortalUserId (PortalUserId), KEY Expire (Expire), KEY ItemResourceId (ItemResourceId) ); CREATE TABLE StatItem ( StatItemId int(11) NOT NULL auto_increment, Module varchar(20) NOT NULL default '', ValueSQL varchar(255) default NULL, ResetSQL varchar(255) default NULL, ListLabel varchar(255) NOT NULL default '', Priority int(11) NOT NULL default '0', AdminSummary int(11) NOT NULL default '0', PRIMARY KEY (StatItemId), KEY AdminSummary (AdminSummary), KEY Priority (Priority) ); CREATE TABLE SuggestMail ( email varchar(255) NOT NULL default '', sent INT UNSIGNED NULL DEFAULT NULL, PRIMARY KEY (email), KEY sent (sent) ); CREATE TABLE SysCache ( SysCacheId int(11) NOT NULL auto_increment, Name varchar(255) NOT NULL default '', Value mediumtext, Expire INT UNSIGNED NULL DEFAULT NULL, Module varchar(20) default NULL, Context varchar(255) default NULL, GroupList varchar(255) NOT NULL default '', PRIMARY KEY (SysCacheId), KEY Name (Name) ); CREATE TABLE TagLibrary ( TagId int(11) NOT NULL auto_increment, name varchar(255) NOT NULL default '', description text, example text, scope varchar(20) NOT NULL default 'global', PRIMARY KEY (TagId) ); CREATE TABLE TagAttributes ( AttrId int(11) NOT NULL auto_increment, TagId int(11) NOT NULL default '0', Name varchar(255) NOT NULL default '', AttrType varchar(20) default NULL, DefValue varchar(255) default NULL, Description TEXT, Required int(11) NOT NULL default '0', PRIMARY KEY (AttrId), KEY TagId (TagId) ); CREATE TABLE ImportScripts ( ImportId INT(11) NOT NULL auto_increment, Name VARCHAR(255) NOT NULL DEFAULT '', Description TEXT NOT NULL, Prefix VARCHAR(10) NOT NULL DEFAULT '', Module VARCHAR(50) NOT NULL DEFAULT '', ExtraFields VARCHAR(255) NOT NULL DEFAULT '', Type VARCHAR(10) NOT NULL DEFAULT '', Status TINYINT NOT NULL, PRIMARY KEY (ImportId), KEY Module (Module), KEY Status (Status) ); CREATE TABLE StylesheetSelectors ( SelectorId int(11) NOT NULL auto_increment, StylesheetId int(11) NOT NULL default '0', Name varchar(255) NOT NULL default '', SelectorName varchar(255) NOT NULL default '', SelectorData text NOT NULL, Description text NOT NULL, Type tinyint(4) NOT NULL default '0', AdvancedCSS text NOT NULL, ParentId int(11) NOT NULL default '0', PRIMARY KEY (SelectorId), KEY StylesheetId (StylesheetId), KEY ParentId (ParentId), KEY `Type` (`Type`) ); CREATE TABLE Visits ( VisitId int(11) NOT NULL auto_increment, VisitDate int(10) unsigned NOT NULL default '0', Referer varchar(255) NOT NULL default '', IPAddress varchar(15) NOT NULL default '', AffiliateId int(10) unsigned NOT NULL default '0', PortalUserId int(11) NOT NULL default '-2', PRIMARY KEY (VisitId), KEY PortalUserId (PortalUserId), KEY AffiliateId (AffiliateId), KEY VisitDate (VisitDate) ); CREATE TABLE ImportCache ( CacheId int(11) NOT NULL auto_increment, CacheName varchar(255) NOT NULL default '', VarName int(11) NOT NULL default '0', VarValue text NOT NULL, PRIMARY KEY (CacheId), KEY CacheName (CacheName), KEY VarName (VarName) ); CREATE TABLE RelatedSearches ( RelatedSearchId int(11) NOT NULL auto_increment, ResourceId int(11) NOT NULL default '0', Keyword varchar(255) NOT NULL default '', ItemType tinyint(4) NOT NULL default '0', Enabled tinyint(4) NOT NULL default '1', Priority int(11) NOT NULL default '0', PRIMARY KEY (RelatedSearchId), KEY Enabled (Enabled), KEY ItemType (ItemType), KEY ResourceId (ResourceId) ); UPDATE Modules SET Path = 'core/', Version='4.3.9' WHERE Name = 'In-Portal'; UPDATE Skins SET Logo = 'just_logo.gif' WHERE Logo = 'just_logo_1.gif'; UPDATE ConfigurationAdmin SET prompt = 'la_config_PathToWebsite' WHERE VariableName = 'Site_Path'; # ===== v 5.0.0 ===== CREATE TABLE StopWords ( StopWordId int(11) NOT NULL auto_increment, StopWord varchar(255) NOT NULL default '', PRIMARY KEY (StopWordId), KEY StopWord (StopWord) ); INSERT INTO StopWords VALUES (90, '~'),(152, 'on'),(157, 'see'),(156, 'put'),(128, 'and'),(154, 'or'),(155, 'other'),(153, 'one'),(126, 'as'),(127, 'at'),(125, 'are'),(91, '!'),(92, '@'),(93, '#'),(94, '$'),(95, '%'),(96, '^'),(97, '&'),(98, '*'),(99, '('),(100, ')'),(101, '-'),(102, '_'),(103, '='),(104, '+'),(105, '['),(106, '{'),(107, ']'),(108, '}'),(109, '\\'),(110, '|'),(111, ';'),(112, ':'),(113, ''''),(114, '"'),(115, '<'),(116, '.'),(117, '>'),(118, '/'),(119, '?'),(120, 'ah'),(121, 'all'),(122, 'also'),(123, 'am'),(124, 'an'),(151, 'of'),(150, 'note'),(149, 'not'),(148, 'no'),(147, 'may'),(146, 'its'),(145, 'it'),(144, 'is'),(143, 'into'),(142, 'in'),(141, 'had'),(140, 'has'),(139, 'have'),(138, 'from'),(137, 'form'),(136, 'for'),(135, 'end'),(134, 'each'),(133, 'can'),(132, 'by'),(130, 'be'),(131, 'but'),(129, 'any'),(158, 'that'),(159, 'the'),(160, 'their'),(161, 'there'),(162, 'these'),(163, 'they'),(164, 'this'),(165, 'through'),(166, 'thus'),(167, 'to'),(168, 'two'),(169, 'too'),(170, 'up'),(171, 'where'),(172, 'which'),(173, 'with'),(174, 'were'),(175, 'was'),(176, 'you'),(177, 'yet'); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:stop_words.view', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:stop_words.add', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:stop_words.edit', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:stop_words.delete', 11, 1, 1, 0); INSERT INTO ConfigurationAdmin VALUES ('CheckStopWords', 'la_Text_Website', 'la_config_CheckStopWords', 'checkbox', '', '', 10.29, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CheckStopWords', '0', 'In-Portal', 'in-portal:configure_general'); ALTER TABLE SpamControl ADD INDEX (DataType); CREATE TABLE MailingLists ( MailingId int(10) unsigned NOT NULL auto_increment, PortalUserId int(11) NOT NULL default '-1', `To` longtext, ToParsed longtext, Attachments text, `Subject` varchar(255) NOT NULL, MessageText longtext, MessageHtml longtext, `Status` tinyint(3) unsigned NOT NULL default '1', EmailsQueued int(10) unsigned NOT NULL, EmailsSent int(10) unsigned NOT NULL, EmailsTotal int(10) unsigned NOT NULL, PRIMARY KEY (MailingId), KEY EmailsTotal (EmailsTotal), KEY EmailsSent (EmailsSent), KEY EmailsQueued (EmailsQueued), KEY `Status` (`Status`), KEY PortalUserId (PortalUserId) ); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:mailing_lists.view', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:mailing_lists.add', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:mailing_lists.edit', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:mailing_lists.delete', 11, 1, 1, 0); ALTER TABLE EmailQueue ADD MailingId INT UNSIGNED NOT NULL, ADD INDEX (MailingId); INSERT INTO ConfigurationAdmin VALUES ('MailingListQueuePerStep', 'la_Text_smtp_server', 'la_config_MailingListQueuePerStep', 'text', NULL, NULL, 30.09, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'MailingListQueuePerStep', 10, 'In-Portal', 'in-portal:configure_general'); INSERT INTO ConfigurationAdmin VALUES ('MailingListSendPerStep', 'la_Text_smtp_server', 'la_config_MailingListSendPerStep', 'text', NULL, NULL, 30.10, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'MailingListSendPerStep', 10, 'In-Portal', 'in-portal:configure_general'); ALTER TABLE Events ADD INDEX (Event); ALTER TABLE SearchLog ADD INDEX (Keyword); ALTER TABLE Skins ADD LogoBottom VARCHAR(255) NOT NULL AFTER Logo, ADD LogoLogin VARCHAR(255) NOT NULL AFTER LogoBottom; UPDATE Skins SET Logo = 'in-portal_logo_img.jpg', LogoBottom = 'in-portal_logo_img2.jpg', LogoLogin = 'in-portal_logo_login.gif' WHERE Logo = 'just_logo_1.gif' OR Logo = 'just_logo.gif'; INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SiteNameSubTitle', '', 'In-Portal', 'in-portal:configure_general'); INSERT INTO ConfigurationAdmin VALUES ('SiteNameSubTitle', 'la_Text_Website', 'la_config_SiteNameSubTitle', 'text', '', '', 10.021, 0, 0); INSERT INTO ConfigurationAdmin VALUES ('ResizableFrames', 'la_Text_Website', 'la_config_ResizableFrames', 'checkbox', '', '', 10.30, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'ResizableFrames', '0', 'In-Portal', 'in-portal:configure_general'); INSERT INTO ConfigurationAdmin VALUES ('QuickCategoryPermissionRebuild', 'la_Text_General', 'la_config_QuickCategoryPermissionRebuild', 'checkbox', NULL , NULL , 10.12, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'QuickCategoryPermissionRebuild', '1', 'In-Portal', 'in-portal:configure_categories'); ALTER TABLE Language ADD UserDocsUrl VARCHAR(255) NOT NULL; UPDATE Category SET Template = CategoryTemplate WHERE CategoryTemplate <> ''; ALTER TABLE Category ADD ThemeId INT UNSIGNED NOT NULL, ADD INDEX (ThemeId), ADD COLUMN UseExternalUrl tinyint(3) unsigned NOT NULL default '0' AFTER Template, ADD COLUMN ExternalUrl varchar(255) NOT NULL default '' AFTER UseExternalUrl, ADD COLUMN UseMenuIconUrl tinyint(3) unsigned NOT NULL default '0' AFTER ExternalUrl, ADD COLUMN MenuIconUrl varchar(255) NOT NULL default '' AFTER UseMenuIconUrl, CHANGE MetaKeywords MetaKeywords TEXT, CHANGE MetaDescription MetaDescription TEXT, CHANGE CachedCategoryTemplate CachedTemplate VARCHAR(255) NOT NULL, DROP CategoryTemplate; UPDATE Category SET l1_MenuTitle = l1_Name WHERE l1_MenuTitle = '' OR l1_MenuTitle LIKE '_Auto: %'; UPDATE Category SET l2_MenuTitle = l2_Name WHERE l2_MenuTitle = '' OR l2_MenuTitle LIKE '_Auto: %'; UPDATE Category SET l3_MenuTitle = l3_Name WHERE l3_MenuTitle = '' OR l3_MenuTitle LIKE '_Auto: %'; UPDATE Category SET l4_MenuTitle = l4_Name WHERE l4_MenuTitle = '' OR l4_MenuTitle LIKE '_Auto: %'; UPDATE Category SET l5_MenuTitle = l5_Name WHERE l5_MenuTitle = '' OR l5_MenuTitle LIKE '_Auto: %'; UPDATE Category SET Template = '/platform/designs/general' WHERE Template = '/in-edit/designs/general'; UPDATE Category SET CachedTemplate = '/platform/designs/general' WHERE CachedTemplate = '/in-edit/designs/general'; UPDATE Category SET CachedTemplate = Template WHERE Template <> ''; CREATE TABLE PageContent ( PageContentId int(11) NOT NULL auto_increment, ContentNum int(11) NOT NULL default '0', PageId int(11) NOT NULL default '0', l1_Content text, l2_Content text, l3_Content text, l4_Content text, l5_Content text, l1_Translated tinyint(4) NOT NULL default '0', l2_Translated tinyint(4) NOT NULL default '0', l3_Translated tinyint(4) NOT NULL default '0', l4_Translated tinyint(4) NOT NULL default '0', l5_Translated tinyint(4) NOT NULL default '0', PRIMARY KEY (PageContentId), KEY ContentNum (ContentNum,PageId) ); CREATE TABLE FormFields ( FormFieldId int(11) NOT NULL auto_increment, FormId int(11) NOT NULL default '0', Type int(11) NOT NULL default '0', FieldName varchar(255) NOT NULL default '', FieldLabel varchar(255) default NULL, Heading varchar(255) default NULL, Prompt varchar(255) default NULL, ElementType varchar(50) NOT NULL default '', ValueList varchar(255) default NULL, Priority int(11) NOT NULL default '0', IsSystem tinyint(3) unsigned NOT NULL default '0', Required tinyint(1) NOT NULL default '0', DisplayInGrid tinyint(1) NOT NULL default '1', DefaultValue text NOT NULL, Validation TINYINT NOT NULL DEFAULT '0', PRIMARY KEY (FormFieldId), KEY `Type` (`Type`), KEY FormId (FormId), KEY Priority (Priority), KEY IsSystem (IsSystem), KEY DisplayInGrid (DisplayInGrid) ); CREATE TABLE FormSubmissions ( FormSubmissionId int(11) NOT NULL auto_increment, FormId int(11) NOT NULL default '0', SubmissionTime int(11) NOT NULL default '0', PRIMARY KEY (FormSubmissionId), KEY FormId (FormId), KEY SubmissionTime (SubmissionTime) ); CREATE TABLE Forms ( FormId int(11) NOT NULL auto_increment, Title VARCHAR(255) NOT NULL DEFAULT '', Description text, PRIMARY KEY (FormId) ); UPDATE Events SET Module = 'Core:Category', Description = 'la_event_FormSubmitted' WHERE Event = 'FORM.SUBMITTED'; DELETE FROM PersistantSessionData WHERE VariableName LIKE '%img%'; UPDATE Modules SET TemplatePath = Path WHERE TemplatePath <> ''; UPDATE ConfigurationValues SET VariableValue = '/platform/designs/general' WHERE VariableName = 'cms_DefaultDesign'; UPDATE ConfigurationValues SET ModuleOwner = 'In-Portal', Section = 'in-portal:configure_categories' WHERE VariableName = 'cms_DefaultDesign'; UPDATE ConfigurationAdmin SET DisplayOrder = 10.15 WHERE VariableName = 'cms_DefaultDesign'; UPDATE Phrase SET Phrase = 'la_Regular' WHERE Phrase = 'la_regular'; UPDATE Phrase SET Module = 'Core' WHERE Phrase IN ('la_Hide', 'la_Show', 'la_fld_Requied', 'la_col_Modified', 'la_col_Referer', 'la_Regular'); UPDATE Phrase SET Phrase = 'la_title_Editing_E-mail' WHERE Phrase = 'la_title_editing_e-mail'; ALTER TABLE Phrase ADD UNIQUE (LanguageId, Phrase); ALTER TABLE CustomField ADD IsRequired tinyint(3) unsigned NOT NULL default '0'; DELETE FROM Permissions WHERE (Permission LIKE 'proj-cms:structure%') OR (Permission LIKE 'proj-cms:submissions%') OR (Permission LIKE 'proj-base:users%') OR (Permission LIKE 'proj-base:system_variables%') OR (Permission LIKE 'proj-base:email_settings%') OR (Permission LIKE 'proj-base:other_settings%') OR (Permission LIKE 'proj-base:sysconfig%'); UPDATE Permissions SET Permission = REPLACE(Permission, 'proj-cms:browse', 'in-portal:browse_site'); UPDATE Permissions SET Permission = REPLACE(Permission, 'proj-cms:', 'in-portal:'); UPDATE Permissions SET Permission = REPLACE(Permission, 'proj-base:', 'in-portal:'); ALTER TABLE CategoryItems ADD INDEX (ItemResourceId); ALTER TABLE CategoryItems DROP INDEX Filename; ALTER TABLE CategoryItems ADD INDEX Filename(Filename); DROP TABLE Pages; DELETE FROM PermissionConfig WHERE PermissionName LIKE 'PAGE.%'; DELETE FROM Permissions WHERE Permission LIKE 'PAGE.%'; DELETE FROM SearchConfig WHERE TableName = 'Pages'; DELETE FROM ConfigurationAdmin WHERE VariableName LIKE '%_pages'; DELETE FROM ConfigurationValues WHERE VariableName LIKE '%_pages'; DELETE FROM ConfigurationAdmin WHERE VariableName LIKE 'PerPage_Pages%'; DELETE FROM ConfigurationValues WHERE VariableName LIKE 'PerPage_Pages%'; INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:website_setting_folder.view', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:user_setting_folder.view', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:configure_advanced.view', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:configure_advanced.edit', 11, 1, 1, 0); #INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:spelling_dictionary.delete', 11, 1, 1, 0); #INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:spelling_dictionary.edit', 11, 1, 1, 0); #INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:spelling_dictionary.add', 11, 1, 1, 0); #INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:spelling_dictionary.view', 11, 1, 1, 0); UPDATE ConfigurationValues SET ModuleOwner = 'In-Portal', Section = 'in-portal:configure_general' WHERE ModuleOwner = 'Proj-Base' AND Section IN ('proj-base:system_variables', 'proj-base:email_settings'); UPDATE ConfigurationValues SET ModuleOwner = 'In-Portal', Section = 'in-portal:configure_advanced' WHERE ModuleOwner = 'Proj-Base' AND Section IN ('proj-base:other_settings', 'proj-base:sysconfig'); UPDATE ConfigurationAdmin SET heading = 'la_Text_General' WHERE VariableName IN ('AdvancedUserManagement', 'RememberLastAdminTemplate', 'DefaultSettingsUserId'); UPDATE ConfigurationAdmin SET DisplayOrder = 10.011 WHERE VariableName = 'AdvancedUserManagement'; UPDATE ConfigurationAdmin SET DisplayOrder = 10.14 WHERE VariableName = 'RememberLastAdminTemplate'; UPDATE ConfigurationAdmin SET DisplayOrder = 10.15 WHERE VariableName = 'DefaultSettingsUserId'; UPDATE ConfigurationAdmin SET DisplayOrder = 10.13 WHERE VariableName = 'FilenameSpecialCharReplacement'; UPDATE ConfigurationAdmin SET DisplayOrder = 10.14 WHERE VariableName = 'YahooApplicationId'; UPDATE ConfigurationAdmin SET heading = 'la_section_SettingsMailling', prompt = 'la_prompt_AdminMailFrom', ValueList = 'size="40"', DisplayOrder = 30.07 WHERE VariableName = 'Smtp_AdminMailFrom'; UPDATE ConfigurationAdmin SET heading = 'la_section_SettingsWebsite' WHERE VariableName IN ('Site_Path','SiteNameSubTitle','UseModRewrite','Config_Server_Time','Config_Site_Time','ErrorTemplate','NoPermissionTemplate','UsePageHitCounter','ForceImageMagickResize','CheckStopWords','Site_Name'); UPDATE ConfigurationAdmin SET heading = 'la_section_SettingsSession' WHERE VariableName IN ('CookieSessions','SessionCookieName','SessionTimeout','KeepSessionOnBrowserClose','SessionReferrerCheck','UseJSRedirect'); UPDATE ConfigurationAdmin SET heading = 'la_section_SettingsSSL' WHERE VariableName IN ('SSL_URL','AdminSSL_URL','Require_SSL','Require_AdminSSL','Force_HTTP_When_SSL_Not_Required','UseModRewriteWithSSL'); UPDATE ConfigurationAdmin SET heading = 'la_section_SettingsAdmin' WHERE VariableName IN ('UseToolbarLabels','UseSmallHeader','UseColumnFreezer','UsePopups','UseDoubleSorting','MenuFrameWidth','ResizableFrames','AutoRefreshIntervals'); UPDATE ConfigurationAdmin SET heading = 'la_section_SettingsMailling' WHERE VariableName IN ('Smtp_Server','Smtp_Port','Smtp_Authenticate','Smtp_User','Smtp_Pass','Smtp_DefaultHeaders','MailFunctionHeaderSeparator','MailingListQueuePerStep','MailingListSendPerStep'); UPDATE ConfigurationAdmin SET heading = 'la_section_SettingsSystem' WHERE VariableName IN ('UseOutputCompression','OutputCompressionLevel','TrimRequiredFields','UseCronForRegularEvent','UseChangeLog','Backup_Path','SystemTagCache','SocketBlockingMode'); UPDATE ConfigurationAdmin SET heading = 'la_section_SettingsCSVExport' WHERE VariableName IN ('CSVExportDelimiter','CSVExportEnclosure','CSVExportSeparator','CSVExportEncoding'); UPDATE ConfigurationAdmin SET DisplayOrder = 10.01 WHERE VariableName = 'Site_Path'; UPDATE ConfigurationAdmin SET DisplayOrder = 10.02 WHERE VariableName = 'SiteNameSubTitle'; UPDATE ConfigurationAdmin SET DisplayOrder = 10.03 WHERE VariableName = 'UseModRewrite'; UPDATE ConfigurationAdmin SET DisplayOrder = 10.04 WHERE VariableName = 'Config_Server_Time'; UPDATE ConfigurationAdmin SET DisplayOrder = 10.05 WHERE VariableName = 'Config_Site_Time'; UPDATE ConfigurationAdmin SET DisplayOrder = 10.06 WHERE VariableName = 'ErrorTemplate'; UPDATE ConfigurationAdmin SET DisplayOrder = 10.07 WHERE VariableName = 'NoPermissionTemplate'; UPDATE ConfigurationAdmin SET DisplayOrder = 10.08 WHERE VariableName = 'UsePageHitCounter'; UPDATE ConfigurationAdmin SET DisplayOrder = 10.09 WHERE VariableName = 'ForceImageMagickResize'; UPDATE ConfigurationAdmin SET DisplayOrder = 10.10 WHERE VariableName = 'CheckStopWords'; UPDATE ConfigurationAdmin SET DisplayOrder = 20.01 WHERE VariableName = 'CookieSessions'; UPDATE ConfigurationAdmin SET DisplayOrder = 20.02 WHERE VariableName = 'SessionCookieName'; UPDATE ConfigurationAdmin SET DisplayOrder = 20.03 WHERE VariableName = 'SessionTimeout'; UPDATE ConfigurationAdmin SET DisplayOrder = 20.04 WHERE VariableName = 'KeepSessionOnBrowserClose'; UPDATE ConfigurationAdmin SET DisplayOrder = 20.05 WHERE VariableName = 'SessionReferrerCheck'; UPDATE ConfigurationAdmin SET DisplayOrder = 20.06 WHERE VariableName = 'UseJSRedirect'; UPDATE ConfigurationAdmin SET DisplayOrder = 30.01 WHERE VariableName = 'SSL_URL'; UPDATE ConfigurationAdmin SET DisplayOrder = 30.02 WHERE VariableName = 'AdminSSL_URL'; UPDATE ConfigurationAdmin SET DisplayOrder = 30.03 WHERE VariableName = 'Require_SSL'; UPDATE ConfigurationAdmin SET DisplayOrder = 30.04 WHERE VariableName = 'Require_AdminSSL'; UPDATE ConfigurationAdmin SET DisplayOrder = 30.05 WHERE VariableName = 'Force_HTTP_When_SSL_Not_Required'; UPDATE ConfigurationAdmin SET DisplayOrder = 30.06 WHERE VariableName = 'UseModRewriteWithSSL'; UPDATE ConfigurationAdmin SET DisplayOrder = 40.01 WHERE VariableName = 'UseToolbarLabels'; UPDATE ConfigurationAdmin SET DisplayOrder = 40.02 WHERE VariableName = 'UseSmallHeader'; UPDATE ConfigurationAdmin SET DisplayOrder = 40.03 WHERE VariableName = 'UseColumnFreezer'; UPDATE ConfigurationAdmin SET DisplayOrder = 40.04 WHERE VariableName = 'UsePopups'; UPDATE ConfigurationAdmin SET DisplayOrder = 40.05 WHERE VariableName = 'UseDoubleSorting'; UPDATE ConfigurationAdmin SET DisplayOrder = 40.06 WHERE VariableName = 'MenuFrameWidth'; UPDATE ConfigurationAdmin SET DisplayOrder = 40.07 WHERE VariableName = 'ResizableFrames'; UPDATE ConfigurationAdmin SET DisplayOrder = 40.08 WHERE VariableName = 'AutoRefreshIntervals'; UPDATE ConfigurationAdmin SET DisplayOrder = 50.01 WHERE VariableName = 'Smtp_Server'; UPDATE ConfigurationAdmin SET DisplayOrder = 50.02 WHERE VariableName = 'Smtp_Port'; UPDATE ConfigurationAdmin SET DisplayOrder = 50.03 WHERE VariableName = 'Smtp_Authenticate'; UPDATE ConfigurationAdmin SET DisplayOrder = 50.04 WHERE VariableName = 'Smtp_User'; UPDATE ConfigurationAdmin SET DisplayOrder = 50.05 WHERE VariableName = 'Smtp_Pass'; UPDATE ConfigurationAdmin SET DisplayOrder = 50.06 WHERE VariableName = 'Smtp_DefaultHeaders'; UPDATE ConfigurationAdmin SET DisplayOrder = 50.07 WHERE VariableName = 'MailFunctionHeaderSeparator'; UPDATE ConfigurationAdmin SET DisplayOrder = 50.08 WHERE VariableName = 'MailingListQueuePerStep'; UPDATE ConfigurationAdmin SET DisplayOrder = 50.09 WHERE VariableName = 'MailingListSendPerStep'; UPDATE ConfigurationAdmin SET DisplayOrder = 60.01 WHERE VariableName = 'UseOutputCompression'; UPDATE ConfigurationAdmin SET DisplayOrder = 60.02 WHERE VariableName = 'OutputCompressionLevel'; UPDATE ConfigurationAdmin SET DisplayOrder = 60.03 WHERE VariableName = 'TrimRequiredFields'; UPDATE ConfigurationAdmin SET DisplayOrder = 60.04 WHERE VariableName = 'UseCronForRegularEvent'; UPDATE ConfigurationAdmin SET DisplayOrder = 60.05 WHERE VariableName = 'UseChangeLog'; UPDATE ConfigurationAdmin SET DisplayOrder = 60.06 WHERE VariableName = 'Backup_Path'; UPDATE ConfigurationAdmin SET DisplayOrder = 60.07 WHERE VariableName = 'SystemTagCache'; UPDATE ConfigurationAdmin SET DisplayOrder = 60.08 WHERE VariableName = 'SocketBlockingMode'; UPDATE ConfigurationAdmin SET DisplayOrder = 70.01 WHERE VariableName = 'CSVExportDelimiter'; UPDATE ConfigurationAdmin SET DisplayOrder = 70.02 WHERE VariableName = 'CSVExportEnclosure'; UPDATE ConfigurationAdmin SET DisplayOrder = 70.03 WHERE VariableName = 'CSVExportSeparator'; UPDATE ConfigurationAdmin SET DisplayOrder = 70.04 WHERE VariableName = 'CSVExportEncoding'; UPDATE Phrase SET Phrase = 'la_section_SettingsWebsite' WHERE Phrase = 'la_Text_Website'; UPDATE Phrase SET Phrase = 'la_section_SettingsMailling' WHERE Phrase = 'la_Text_smtp_server'; UPDATE Phrase SET Phrase = 'la_section_SettingsCSVExport' WHERE Phrase = 'la_Text_CSV_Export'; DELETE FROM Phrase WHERE Phrase IN ( 'la_Text_BackupPath', 'la_config_AllowManualFilenames', 'la_fld_cat_MenuLink', 'la_fld_UseCategoryTitle', 'la_In-Edit', 'la_ItemTab_Pages', 'la_Text_Pages', 'la_title_Pages', 'la_title_Page_Categories', 'lu_Pages', 'lu_page_HtmlTitle', 'lu_page_OnPageTitle', 'la_tab_AllPages', 'la_title_AllPages', 'la_title_ContentManagement', 'la_title_ContentManagment', 'lu_ViewSubPages', 'la_CMS_FormSubmitted' ); DELETE FROM Phrase WHERE (Phrase LIKE 'la_Description_In-Edit%') OR (Phrase LIKE 'la_Pages_PerPage%') OR (Phrase LIKE 'lu_PermName_Page.%'); UPDATE ConfigurationValues SET VariableValue = 1, ModuleOwner = 'In-Portal:Users', Section = 'in-portal:configure_users' WHERE VariableName = 'RememberLastAdminTemplate'; UPDATE ConfigurationValues SET ModuleOwner = 'In-Portal:Users', Section = 'in-portal:configure_users' WHERE VariableName IN ('AdvancedUserManagement', 'DefaultSettingsUserId'); INSERT INTO ConfigurationAdmin VALUES ('Search_MinKeyword_Length', 'la_Text_General', 'la_config_Search_MinKeyword_Length', 'text', NULL, NULL, 10.19, 0, 0); UPDATE ConfigurationValues SET Section = 'in-portal:configure_categories' WHERE VariableName = 'Search_MinKeyword_Length'; UPDATE ConfigurationAdmin SET ValueList = '=+,SELECT DestName AS OptionName, DestId AS OptionValue FROM StdDestinations WHERE COALESCE(DestParentId, 0) = 0 ORDER BY OptionName' WHERE VariableName = 'User_Default_Registration_Country'; UPDATE ConfigurationValues SET ModuleOwner = 'In-Portal', Section = 'in-portal:configure_advanced' WHERE VariableName IN ( 'Site_Path', 'SiteNameSubTitle', 'CookieSessions', 'SessionCookieName', 'SessionTimeout', 'SessionReferrerCheck', 'SystemTagCache', 'SocketBlockingMode', 'SSL_URL', 'AdminSSL_URL', 'Require_SSL', 'Force_HTTP_When_SSL_Not_Required', 'UseModRewrite', 'UseModRewriteWithSSL', 'UseJSRedirect', 'UseCronForRegularEvent', 'ErrorTemplate', 'NoPermissionTemplate', 'UseOutputCompression', 'OutputCompressionLevel', 'UseToolbarLabels', 'UseSmallHeader', 'UseColumnFreezer', 'TrimRequiredFields', 'UsePageHitCounter', 'UseChangeLog', 'AutoRefreshIntervals', 'KeepSessionOnBrowserClose', 'ForceImageMagickResize', 'CheckStopWords', 'ResizableFrames', 'Config_Server_Time', 'Config_Site_Time', 'Smtp_Server', 'Smtp_Port', 'Smtp_Authenticate', 'Smtp_User', 'Smtp_Pass', 'Smtp_DefaultHeaders', 'MailFunctionHeaderSeparator', 'MailingListQueuePerStep', 'MailingListSendPerStep', 'Backup_Path', 'CSVExportDelimiter', 'CSVExportEnclosure', 'CSVExportSeparator', 'CSVExportEncoding' ); DELETE FROM ConfigurationValues WHERE VariableName IN ( 'Columns_Category', 'Perpage_Archive', 'debug', 'Perpage_User', 'Perpage_LangEmail', 'Default_FromAddr', 'email_replyto', 'email_footer', 'Default_Theme', 'Default_Language', 'User_SortField', 'User_SortOrder', 'Suggest_MinInterval', 'SubCat_ListCount', 'Timeout_Rating', 'Perpage_Relations', 'Group_SortField', 'Group_SortOrder', 'Default_FromName', 'Relation_LV_Sortfield', 'ampm_time', 'Perpage_Template', 'Perpage_Phrase', 'Perpage_Sessionlist', 'Perpage_Items', 'GuestSessions', 'Perpage_Email', 'LinksValidation_LV_Sortfield', 'CustomConfig_LV_Sortfield', 'Event_LV_SortField', 'Theme_LV_SortField', 'Template_LV_SortField', 'Lang_LV_SortField', 'Phrase_LV_SortField', 'LangEmail_LV_SortField', 'CustomData_LV_SortField', 'Summary_SortField', 'Session_SortField', 'SearchLog_SortField', 'Perpage_StatItem', 'Perpage_Groups', 'Perpage_Event', 'Perpage_BanRules', 'Perpage_SearchLog', 'Perpage_LV_lang', 'Perpage_LV_Themes', 'Perpage_LV_Catlist', 'Perpage_Reviews', 'Perpage_Modules', 'Perpage_Grouplist', 'Perpage_Images', 'EmailsL_SortField', 'Perpage_EmailsL', 'Perpage_CustomData', 'Perpage_Review', 'SearchRel_DefaultIncrease', 'SearchRel_DefaultKeyword', 'SearchRel_DefaultPop', 'SearchRel_DefaultRating', 'Category_Highlight_OpenTag', 'Category_Highlight_CloseTag', 'DomainSelect', 'MetaKeywords', 'MetaDescription', 'Config_Name', 'Config_Company', 'Config_Reg_Number', 'Config_Website_Name', 'Config_Web_Address', 'Smtp_SendHTML', 'ProjCMSAllowManualFilenames' ); DELETE FROM ConfigurationAdmin WHERE VariableName IN ('Domain_Detect', 'Server_Name', 'ProjCMSAllowManualFilenames'); DROP TABLE SuggestMail; ALTER TABLE ThemeFiles ADD FileMetaInfo TEXT NULL; UPDATE SearchConfig SET SimpleSearch = 0 WHERE FieldType NOT IN ('text', 'range') AND SimpleSearch = 1; DELETE FROM PersistantSessionData WHERE VariableName IN ('c_columns_.', 'c.showall_columns_.', 'emailevents_columns_.', 'emailmessages_columns_.'); INSERT INTO ConfigurationAdmin VALUES ('DebugOnlyFormConfigurator', 'la_section_SettingsAdmin', 'la_config_DebugOnlyFormConfigurator', 'checkbox', '', '', 40.09, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'DebugOnlyFormConfigurator', '0', 'In-Portal', 'in-portal:configure_advanced'); CREATE TABLE Semaphores ( SemaphoreId int(11) NOT NULL auto_increment, SessionKey int(10) unsigned NOT NULL, Timestamp int(10) unsigned NOT NULL, MainPrefix varchar(255) NOT NULL, PRIMARY KEY (SemaphoreId), KEY SessionKey (SessionKey), KEY Timestamp (Timestamp), KEY MainPrefix (MainPrefix) ); ALTER TABLE Language ADD IconDisabledURL VARCHAR(255) NULL DEFAULT NULL AFTER IconURL; UPDATE Phrase SET Translation = REPLACE(Translation, 'category', 'section') WHERE (Phrase IN ( 'la_confirm_maintenance', 'la_error_move_subcategory', 'la_error_RootCategoriesDelete', 'la_error_unknown_category', 'la_fld_IsBaseCategory', 'la_nextcategory', 'la_prevcategory', 'la_prompt_max_import_category_levels', 'la_prompt_root_name', 'la_SeparatedCategoryPath', 'la_title_category_select' ) OR Phrase LIKE 'la_Description_%') AND (PhraseType = 1); UPDATE Phrase SET Translation = REPLACE(Translation, 'Category', 'Section') WHERE PhraseType = 1; UPDATE Phrase SET Translation = REPLACE(Translation, 'categories', 'sections') WHERE (Phrase IN ( 'la_category_perpage_prompt', 'la_category_showpick_prompt', 'la_category_sortfield_prompt', 'la_Description_in-portal:advanced_view', 'la_Description_in-portal:browse', 'la_Description_in-portal:site', 'la_error_copy_subcategory', 'la_Msg_PropagateCategoryStatus', 'la_Text_DataType_1' )) AND (PhraseType = 1); UPDATE Phrase SET Translation = REPLACE(Translation, 'Categories', 'Sections') WHERE PhraseType = 1; UPDATE Phrase SET Translation = REPLACE(Translation, 'Page', 'Section') WHERE (Phrase IN ('la_col_PageTitle', 'la_col_System', 'la_fld_IsIndex', 'la_fld_PageTitle', 'la_section_Page')) AND (PhraseType = 1); DELETE FROM Phrase WHERE Phrase IN ('la_title_Adding_Page', 'la_title_Editing_Page', 'la_title_New_Page', 'la_fld_PageId'); INSERT INTO ConfigurationAdmin VALUES ('UseModalWindows', 'la_section_SettingsAdmin', 'la_config_UseModalWindows', 'checkbox', '', '', 40.10, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'UseModalWindows', '1', 'In-Portal', 'in-portal:configure_advanced'); UPDATE Language SET UserDocsUrl = 'http://docs.in-portal.org/eng/index.php'; DELETE FROM Modules WHERE Name = 'Proj-Base'; DELETE FROM Phrase WHERE Phrase IN ('la_fld_ImageId', 'la_fld_RelationshipId', 'la_fld_ReviewId', 'la_prompt_CensorhipId', 'my_account_title', 'Next Theme', 'Previous Theme', 'test 1', 'la_article_reviewed', 'la_configerror_review', 'la_link_reviewed', 'la_Prompt_ReviewedBy', 'la_prompt_ReviewId', 'la_prompt_ReviewText', 'la_reviewer', 'la_review_added', 'la_review_alreadyreviewed', 'la_review_error', 'la_tab_Editing_Review', 'la_tab_Review', 'la_ToolTip_New_Review', 'la_topic_reviewed', 'lu_add_review', 'lu_article_reviews', 'lu_ferror_review_duplicate', 'lu_link_addreview_confirm_pending_text', 'lu_link_reviews', 'lu_link_review_confirm', 'lu_link_review_confirm_pending', 'lu_link_addreview_confirm_text', 'lu_news_addreview_confirm_text', 'lu_news_addreview_confirm__pending_text', 'lu_news_review_confirm', 'lu_news_review_confirm_pending', 'lu_prompt_review', 'lu_reviews_updated', 'lu_review_access_denied', 'lu_review_article', 'lu_review_link', 'lu_review_news', 'lu_review_this_article', 'lu_fld_Review', 'lu_product_reviews', 'lu_ReviewProduct', ' lu_resetpw_confirm_text', 'lu_resetpw_confirm_text'); UPDATE Modules SET Version = '5.0.0', Loaded = 1 WHERE Name = 'In-Portal'; # ===== v 5.0.1 ===== UPDATE ConfigurationAdmin SET ValueList = '1=la_opt_UserInstantRegistration,2=la_opt_UserNotAllowedRegistration,3=la_opt_UserUponApprovalRegistration,4=la_opt_UserEmailActivation' WHERE VariableName = 'User_Allow_New'; UPDATE ConfigurationValues SET VariableValue = '1' WHERE VariableName = 'ResizableFrames'; UPDATE Phrase SET Translation = REPLACE(Translation, 'Page', 'Section') WHERE (Phrase IN ('la_col_PageTitle', 'la_col_System', 'la_fld_IsIndex', 'la_fld_PageTitle', 'la_section_Page')) AND (PhraseType = 1); DELETE FROM Phrase WHERE Phrase IN ('la_Tab', 'la_Colon', 'la_Semicolon', 'la_Space', 'la_Colon', 'la_User_Instant', 'la_User_Not_Allowed', 'la_User_Upon_Approval', 'lu_title_PrivacyPolicy'); UPDATE ConfigurationAdmin SET ValueList = '0=la_opt_Tab,1=la_opt_Comma,2=la_opt_Semicolon,3=la_opt_Space,4=la_opt_Colon' WHERE VariableName = 'CSVExportDelimiter'; UPDATE ConfigurationAdmin SET ValueList = '0=lu_opt_QueryString,1=lu_opt_Cookies,2=lu_opt_AutoDetect' WHERE VariableName = 'CookieSessions'; UPDATE ConfigurationAdmin SET ValueList = 'Name=la_opt_Title,Description=la_opt_Description,CreatedOn=la_opt_CreatedOn,EditorsPick=la_opt_EditorsPick,SELECT Prompt AS OptionName, CONCAT("cust_", FieldName) AS OptionValue FROM CustomField WHERE (Type = 1) AND (IsSystem = 0)' WHERE VariableName = 'Category_Sortfield'; UPDATE ConfigurationAdmin SET ValueList = 'Name=la_opt_Title,Description=la_opt_Description,CreatedOn=la_opt_CreatedOn,EditorsPick=la_opt_EditorsPick,SELECT Prompt AS OptionName, CONCAT("cust_", FieldName) AS OptionValue FROM CustomField WHERE (Type = 1) AND (IsSystem = 0)' WHERE VariableName = 'Category_Sortfield2'; UPDATE Category SET Template = '#inherit#' WHERE COALESCE(Template, '') = ''; ALTER TABLE Category CHANGE Template Template VARCHAR(255) NOT NULL DEFAULT '#inherit#'; UPDATE Phrase SET Phrase = 'la_config_DefaultDesignTemplate' WHERE Phrase = 'la_prompt_DefaultDesignTemplate'; UPDATE ConfigurationAdmin SET heading = 'la_section_SettingsWebsite', prompt = 'la_config_DefaultDesignTemplate', DisplayOrder = 10.06 WHERE VariableName = 'cms_DefaultDesign'; UPDATE ConfigurationValues SET Section = 'in-portal:configure_advanced' WHERE VariableName = 'cms_DefaultDesign'; UPDATE ConfigurationAdmin SET DisplayOrder = DisplayOrder + 0.01 WHERE VariableName IN ('ErrorTemplate', 'NoPermissionTemplate'); UPDATE ConfigurationAdmin SET DisplayOrder = 10.15 WHERE VariableName = 'Search_MinKeyword_Length'; UPDATE ConfigurationAdmin SET DisplayOrder = 10.01 WHERE VariableName = 'Site_Name'; UPDATE ConfigurationAdmin SET DisplayOrder = 20.01 WHERE VariableName = 'FirstDayOfWeek'; UPDATE ConfigurationAdmin SET DisplayOrder = 30.01 WHERE VariableName = 'Smtp_AdminMailFrom'; UPDATE ConfigurationAdmin SET heading = 'la_Text_Date_Time_Settings', DisplayOrder = DisplayOrder + 9.98 WHERE VariableName IN ('Config_Server_Time', 'Config_Site_Time'); UPDATE ConfigurationValues SET Section = 'in-portal:configure_general' WHERE VariableName IN ('Config_Server_Time', 'Config_Site_Time'); UPDATE ConfigurationAdmin SET DisplayOrder = DisplayOrder - 0.02 WHERE VariableName IN ('cms_DefaultDesign', 'ErrorTemplate', 'NoPermissionTemplate', 'UsePageHitCounter', 'ForceImageMagickResize', 'CheckStopWords'); UPDATE ConfigurationAdmin SET DisplayOrder = 40.01 WHERE VariableName = 'SessionTimeout'; UPDATE ConfigurationValues SET Section = 'in-portal:configure_general' WHERE VariableName = 'SessionTimeout'; UPDATE ConfigurationAdmin SET DisplayOrder = DisplayOrder - 0.01 WHERE VariableName IN ('KeepSessionOnBrowserClose', 'SessionReferrerCheck', 'UseJSRedirect'); ALTER TABLE Events ADD FrontEndOnly TINYINT UNSIGNED NOT NULL DEFAULT '0' AFTER Enabled, ADD INDEX (FrontEndOnly); UPDATE Events SET FrontEndOnly = 1 WHERE Enabled = 2; UPDATE Events SET Enabled = 1 WHERE Enabled = 2; ALTER TABLE Events CHANGE FromUserId FromUserId INT(11) NULL DEFAULT NULL; UPDATE Events SET FromUserId = NULL WHERE FromUserId = 0; DELETE FROM ConfigurationAdmin WHERE VariableName = 'SiteNameSubTitle'; DELETE FROM ConfigurationValues WHERE VariableName = 'SiteNameSubTitle'; UPDATE ConfigurationAdmin SET DisplayOrder = DisplayOrder - 0.01 WHERE VariableName IN ('UseModRewrite', 'cms_DefaultDesign', 'ErrorTemplate' 'NoPermissionTemplate', 'UsePageHitCounter', 'ForceImageMagickResize', 'CheckStopWords'); ALTER TABLE ConfigurationAdmin CHANGE validation Validation TEXT NULL DEFAULT NULL; UPDATE ConfigurationAdmin SET Validation = 'a:3:{s:4:"type";s:3:"int";s:13:"min_value_inc";i:1;s:8:"required";i:1;}' WHERE VariableName = 'SessionTimeout'; INSERT INTO ConfigurationAdmin VALUES ('AdminConsoleInterface', 'la_section_SettingsAdmin', 'la_config_AdminConsoleInterface', 'select', '', 'simple=+simple,advanced=+advanced,custom=+custom', 50.01, 0, 1); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'AdminConsoleInterface', 'simple', 'In-Portal', 'in-portal:configure_general'); INSERT INTO ConfigurationAdmin VALUES ('AllowAdminConsoleInterfaceChange', 'la_section_SettingsAdmin', 'la_config_AllowAdminConsoleInterfaceChange', 'checkbox', NULL , NULL , 40.01, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'AllowAdminConsoleInterfaceChange', '1', 'In-Portal', 'in-portal:configure_advanced'); UPDATE ConfigurationAdmin SET DisplayOrder = DisplayOrder + 0.01 WHERE VariableName IN ('UseToolbarLabels', 'UseSmallHeader', 'UseColumnFreezer', 'UsePopups', 'UseDoubleSorting', 'MenuFrameWidth', 'ResizableFrames', 'AutoRefreshIntervals', 'DebugOnlyFormConfigurator', 'UseModalWindows'); INSERT INTO ConfigurationAdmin VALUES ('UseTemplateCompression', 'la_section_SettingsSystem', 'la_config_UseTemplateCompression', 'checkbox', '', '', 60.03, 0, 1); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'UseTemplateCompression', '0', 'In-Portal', 'in-portal:configure_advanced'); UPDATE ConfigurationAdmin SET DisplayOrder = DisplayOrder + 0.01 WHERE VariableName IN ('TrimRequiredFields', 'UseCronForRegularEvent', 'UseChangeLog', 'Backup_Path', 'SystemTagCache', 'SocketBlockingMode'); DELETE FROM ConfigurationAdmin WHERE VariableName = 'UseModalWindows'; DELETE FROM ConfigurationValues WHERE VariableName = 'UseModalWindows'; DELETE FROM Phrase WHERE Phrase = 'la_config_UseModalWindows'; UPDATE ConfigurationAdmin SET element_type = 'select', ValueList = '0=la_opt_SameWindow,1=la_opt_PopupWindow,2=la_opt_ModalWindow' WHERE VariableName = 'UsePopups'; UPDATE Phrase SET Translation = 'Editing Window Style' WHERE Phrase = 'la_config_UsePopups'; INSERT INTO ConfigurationAdmin VALUES ('UseVisitorTracking', 'la_section_SettingsWebsite', 'la_config_UseVisitorTracking', 'checkbox', '', '', 10.09, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'UseVisitorTracking', '0', 'In-Portal', 'in-portal:configure_advanced'); DELETE FROM ConfigurationAdmin WHERE VariableName = 'SessionReferrerCheck'; DELETE FROM ConfigurationValues WHERE VariableName = 'SessionReferrerCheck'; DELETE FROM Phrase WHERE Phrase = 'la_promt_ReferrerCheck'; INSERT INTO ConfigurationAdmin VALUES ('SessionBrowserSignatureCheck', 'la_section_SettingsSession', 'la_config_SessionBrowserSignatureCheck', 'checkbox', NULL, NULL, 20.04, 0, 1); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SessionBrowserSignatureCheck', '0', 'In-Portal', 'in-portal:configure_advanced'); INSERT INTO ConfigurationAdmin VALUES ('SessionIPAddressCheck', 'la_section_SettingsSession', 'la_config_SessionIPAddressCheck', 'checkbox', NULL, NULL, 20.05, 0, 1); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SessionIPAddressCheck', '0', 'In-Portal', 'in-portal:configure_advanced'); UPDATE ConfigurationAdmin SET DisplayOrder = DisplayOrder + 0.01 WHERE VariableName = 'UseJSRedirect'; ALTER TABLE UserSession DROP CurrentTempKey, DROP PrevTempKey, ADD BrowserSignature VARCHAR(32) NOT NULL, ADD INDEX (BrowserSignature); UPDATE ConfigurationAdmin SET DisplayOrder = DisplayOrder + 0.01 WHERE heading = 'la_section_SettingsAdmin' AND DisplayOrder > 40 AND DisplayOrder < 50; UPDATE ConfigurationAdmin SET heading = 'la_section_SettingsAdmin', DisplayOrder = 40.01 WHERE VariableName = 'RootPass'; UPDATE ConfigurationValues SET ModuleOwner = 'In-Portal', Section = 'in-portal:configure_advanced' WHERE VariableName = 'RootPass'; UPDATE ConfigurationAdmin SET DisplayOrder = 10.12 WHERE VariableName = 'User_Default_Registration_Country'; UPDATE ConfigurationAdmin SET heading = 'la_section_SettingsAdmin', DisplayOrder = 40.12 WHERE VariableName = 'RememberLastAdminTemplate'; UPDATE ConfigurationValues SET ModuleOwner = 'In-Portal', Section = 'in-portal:configure_advanced' WHERE VariableName = 'RememberLastAdminTemplate'; UPDATE ConfigurationAdmin SET DisplayOrder = 10.14 WHERE VariableName = 'DefaultSettingsUserId'; INSERT INTO ConfigurationAdmin VALUES ('UseHTTPAuth', 'la_section_SettingsAdmin', 'la_config_UseHTTPAuth', 'checkbox', '', '', 40.13, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'UseHTTPAuth', '0', 'In-Portal', 'in-portal:configure_advanced'); INSERT INTO ConfigurationAdmin VALUES ('HTTPAuthUsername', 'la_section_SettingsAdmin', 'la_config_HTTPAuthUsername', 'text', '', '', 40.14, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'HTTPAuthUsername', '', 'In-Portal', 'in-portal:configure_advanced'); INSERT INTO ConfigurationAdmin VALUES ('HTTPAuthPassword', 'la_section_SettingsAdmin', 'la_config_HTTPAuthPassword', 'password', NULL, NULL, 40.15, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'HTTPAuthPassword', '', 'In-Portal', 'in-portal:configure_advanced'); INSERT INTO ConfigurationAdmin VALUES ('HTTPAuthBypassIPs', 'la_section_SettingsAdmin', 'la_config_HTTPAuthBypassIPs', 'text', '', '', 40.15, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'HTTPAuthBypassIPs', '', 'In-Portal', 'in-portal:configure_advanced'); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:service.edit', 11, 1, 1, 0); UPDATE Phrase SET Phrase = 'la_col_Rating' WHERE Phrase = 'la_col_rating'; UPDATE Phrase SET Phrase = 'la_text_Review' WHERE Phrase = 'la_text_review'; UPDATE Phrase SET Phrase = 'la_title_Reviews' WHERE Phrase = 'la_title_reviews'; UPDATE Phrase SET Phrase = 'la_ToolTip_cancel' WHERE Phrase = 'la_tooltip_cancel'; ALTER TABLE Phrase ADD PhraseKey VARCHAR(255) NOT NULL AFTER Phrase, ADD INDEX (PhraseKey); UPDATE Phrase SET PhraseKey = UPPER(Phrase); UPDATE Modules SET Loaded = 1 WHERE `Name` = 'In-Portal'; # ===== v 5.0.2-B1 ===== ALTER TABLE PortalGroup DROP ResourceId; ALTER TABLE Category DROP l1_Translated, DROP l2_Translated, DROP l3_Translated, DROP l4_Translated, DROP l5_Translated; ALTER TABLE PageContent DROP l1_Translated, DROP l2_Translated, DROP l3_Translated, DROP l4_Translated, DROP l5_Translated; ALTER TABLE Category CHANGE CachedTemplate CachedTemplate varchar(255) NOT NULL DEFAULT '', CHANGE ThemeId ThemeId int(10) unsigned NOT NULL DEFAULT '0'; ALTER TABLE UserSession CHANGE BrowserSignature BrowserSignature varchar(32) NOT NULL DEFAULT ''; ALTER TABLE ChangeLogs CHANGE Changes Changes text NULL, CHANGE OccuredOn OccuredOn INT(11) NULL DEFAULT NULL; ALTER TABLE EmailLog CHANGE EventParams EventParams text NULL; ALTER TABLE FormFields CHANGE DefaultValue DefaultValue text NULL; ALTER TABLE ImportCache CHANGE VarValue VarValue text NULL; ALTER TABLE ImportScripts CHANGE Description Description text NULL; ALTER TABLE PersistantSessionData CHANGE VariableValue VariableValue text NULL; ALTER TABLE Phrase CHANGE `Translation` `Translation` text NULL, CHANGE PhraseKey PhraseKey VARCHAR(255) NOT NULL DEFAULT '', CHANGE LastChanged LastChanged INT(10) UNSIGNED NULL DEFAULT NULL; ALTER TABLE PhraseCache CHANGE PhraseList PhraseList text NULL; ALTER TABLE Stylesheets CHANGE AdvancedCSS AdvancedCSS text NULL, CHANGE LastCompiled LastCompiled INT(10) UNSIGNED NULL DEFAULT NULL; ALTER TABLE StylesheetSelectors CHANGE SelectorData SelectorData text NULL, CHANGE Description Description text NULL, CHANGE AdvancedCSS AdvancedCSS text NULL; ALTER TABLE Category CHANGE `Status` `Status` TINYINT(4) NOT NULL DEFAULT '1', CHANGE CreatedOn CreatedOn INT(11) NULL DEFAULT NULL, CHANGE Modified Modified INT(11) NULL DEFAULT NULL; ALTER TABLE Language CHANGE UserDocsUrl UserDocsUrl VARCHAR(255) NOT NULL DEFAULT ''; ALTER TABLE MailingLists CHANGE Subject Subject VARCHAR(255) NOT NULL DEFAULT '', CHANGE EmailsQueued EmailsQueued INT(10) UNSIGNED NOT NULL DEFAULT '0', CHANGE EmailsSent EmailsSent INT(10) UNSIGNED NOT NULL DEFAULT '0', CHANGE EmailsTotal EmailsTotal INT(10) UNSIGNED NOT NULL DEFAULT '0'; ALTER TABLE EmailQueue CHANGE MailingId MailingId INT(10) UNSIGNED NOT NULL DEFAULT '0', CHANGE Queued Queued INT(10) UNSIGNED NULL DEFAULT NULL, CHANGE LastSendRetry LastSendRetry INT(10) UNSIGNED NULL DEFAULT NULL; ALTER TABLE ImportScripts CHANGE `Status` `Status` TINYINT(4) NOT NULL DEFAULT '1'; ALTER TABLE Semaphores CHANGE SessionKey SessionKey INT(10) UNSIGNED NOT NULL DEFAULT '0', CHANGE `Timestamp` `Timestamp` INT(10) UNSIGNED NOT NULL DEFAULT '0', CHANGE MainPrefix MainPrefix VARCHAR(255) NOT NULL DEFAULT ''; ALTER TABLE Skins CHANGE LogoBottom LogoBottom VARCHAR(255) NOT NULL DEFAULT '', CHANGE LogoLogin LogoLogin VARCHAR(255) NOT NULL DEFAULT ''; ALTER TABLE ItemReview CHANGE ReviewText ReviewText LONGTEXT NULL; ALTER TABLE SessionData CHANGE VariableValue VariableValue LONGTEXT NULL; ALTER TABLE PortalUser CHANGE `Status` `Status` TINYINT(4) NOT NULL DEFAULT '1', CHANGE Modified Modified INT(11) NULL DEFAULT NULL; ALTER TABLE ItemFiles CHANGE CreatedOn CreatedOn INT(11) UNSIGNED NULL DEFAULT NULL; ALTER TABLE FormSubmissions CHANGE SubmissionTime SubmissionTime INT(11) NULL DEFAULT NULL; ALTER TABLE SessionLogs CHANGE SessionStart SessionStart INT(11) NULL DEFAULT NULL; ALTER TABLE Visits CHANGE VisitDate VisitDate INT(10) UNSIGNED NULL DEFAULT NULL; # ===== v 5.0.2-B2 ===== ALTER TABLE Theme ADD LanguagePackInstalled TINYINT UNSIGNED NOT NULL DEFAULT '0', ADD TemplateAliases TEXT, ADD INDEX (LanguagePackInstalled); ALTER TABLE ThemeFiles ADD TemplateAlias VARCHAR(255) NOT NULL DEFAULT '' AFTER FilePath, ADD INDEX (TemplateAlias); UPDATE Phrase SET PhraseType = 1 WHERE Phrase IN ('la_ToolTip_MoveUp', 'la_ToolTip_MoveDown', 'la_invalid_state', 'la_Pending', 'la_text_sess_expired', 'la_ToolTip_Export'); DELETE FROM Phrase WHERE Phrase IN ('la_ToolTip_Move_Up', 'la_ToolTip_Move_Down'); UPDATE Phrase SET Phrase = 'lu_btn_SendPassword' WHERE Phrase = 'LU_BTN_SENDPASSWORD'; ALTER TABLE Category DROP IsIndex; DELETE FROM Phrase WHERE Phrase IN ('la_CategoryIndex', 'la_Container', 'la_fld_IsIndex', 'lu_text_Redirecting', 'lu_title_Redirecting', 'lu_zip_code'); ALTER TABLE PortalUser ADD AdminLanguage INT(11) NULL DEFAULT NULL, ADD INDEX (AdminLanguage); # ===== v 5.0.2-RC1 ===== # ===== v 5.0.2 ===== # ===== v 5.0.3-B1 ===== ALTER TABLE PermCache ADD INDEX (ACL); INSERT INTO ConfigurationAdmin VALUES ('cms_DefaultTrackingCode', 'la_section_SettingsWebsite', 'la_config_DefaultTrackingCode', 'textarea', NULL, 'COLS=40 ROWS=5', 10.10, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'cms_DefaultTrackingCode', '', 'In-Portal', 'in-portal:configure_advanced'); UPDATE Phrase SET Module = 'Core' WHERE Phrase IN ('la_fld_Image', 'la_fld_Qty'); # ===== v 5.0.3-B2 ===== UPDATE CustomField SET ValueList = REPLACE(ValueList, '=+||', '') WHERE ElementType = 'radio'; # ===== v 5.0.3-RC1 ===== # ===== v 5.0.3 ===== # ===== v 5.0.4-B1 ===== # ===== v 5.0.4-B2 ===== # ===== v 5.0.4 ===== # ===== v 5.1.0-B1 ===== DROP TABLE EmailMessage; DELETE FROM PersistantSessionData WHERE VariableName = 'emailevents_columns_.'; INSERT INTO Permissions (Permission, GroupId, PermissionValue, Type, CatId) SELECT 'in-portal:configemail.add' AS Permission, GroupId, PermissionValue, Type, CatId FROM <%TABLE_PREFIX%>Permissions WHERE Permission = 'in-portal:configemail.edit'; INSERT INTO Permissions (Permission, GroupId, PermissionValue, Type, CatId) SELECT 'in-portal:configemail.delete' AS Permission, GroupId, PermissionValue, Type, CatId FROM <%TABLE_PREFIX%>Permissions WHERE Permission = 'in-portal:configemail.edit'; ALTER TABLE Events ADD l1_Description text; UPDATE Events e SET e.l1_Description = ( SELECT p.l<%PRIMARY_LANGUAGE%>_Translation FROM <%TABLE_PREFIX%>Phrase p WHERE p.Phrase = e.Description ); UPDATE Events SET Description = l1_Description; ALTER TABLE Events DROP l1_Description, CHANGE Description Description TEXT NULL; DELETE FROM Phrase WHERE Phrase LIKE 'la_event_%'; DELETE FROM PersistantSessionData WHERE VariableName = 'phrases_columns_.'; UPDATE Category SET FormId = NULL WHERE FormId = 0; INSERT INTO ConfigurationAdmin VALUES ('MemcacheServers', 'la_section_SettingsCaching', 'la_config_MemcacheServers', 'text', '', '', 80.02, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'MemcacheServers', 'localhost:11211', 'In-Portal', 'in-portal:configure_advanced'); ALTER TABLE Category ADD EnablePageCache TINYINT NOT NULL DEFAULT '0', ADD OverridePageCacheKey TINYINT NOT NULL DEFAULT '0', ADD PageCacheKey VARCHAR(255) NOT NULL DEFAULT '', ADD PageExpiration INT NULL DEFAULT NULL , ADD INDEX (EnablePageCache), ADD INDEX (OverridePageCacheKey), ADD INDEX (PageExpiration); DELETE FROM Cache WHERE VarName LIKE 'mod_rw_%'; CREATE TABLE CachedUrls ( UrlId int(11) NOT NULL AUTO_INCREMENT, Url varchar(255) NOT NULL DEFAULT '', DomainId int(11) NOT NULL DEFAULT '0', `Hash` int(11) NOT NULL DEFAULT '0', Prefixes varchar(255) NOT NULL DEFAULT '', ParsedVars text NOT NULL, Cached int(10) unsigned DEFAULT NULL, LifeTime int(11) NOT NULL DEFAULT '-1', PRIMARY KEY (UrlId), KEY Url (Url), KEY `Hash` (`Hash`), KEY Prefixes (Prefixes), KEY Cached (Cached), KEY LifeTime (LifeTime), KEY DomainId (DomainId) ); INSERT INTO ConfigurationAdmin VALUES ('CacheHandler', 'la_section_SettingsCaching', 'la_config_CacheHandler', 'select', NULL, 'Fake=la_None||Memcache=+Memcached||Apc=+Alternative PHP Cache||XCache=+XCache', 80.01, 0, 0); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CacheHandler', 'Fake', 'In-Portal', 'in-portal:configure_advanced'); ALTER TABLE ConfigurationValues ADD Heading varchar(255) NOT NULL DEFAULT '', ADD Prompt varchar(255) NOT NULL DEFAULT '', ADD ElementType varchar(255) NOT NULL DEFAULT '', ADD Validation text, ADD ValueList text, ADD DisplayOrder double NOT NULL DEFAULT '0', ADD GroupDisplayOrder double NOT NULL DEFAULT '0', ADD Install int(11) NOT NULL DEFAULT '1', ADD INDEX (DisplayOrder), ADD INDEX (GroupDisplayOrder), ADD INDEX (Install); UPDATE ConfigurationValues cv SET cv.Heading = (SELECT ca1.heading FROM <%TABLE_PREFIX%>ConfigurationAdmin ca1 WHERE ca1.VariableName = cv.VariableName), cv.Prompt = (SELECT ca2.prompt FROM <%TABLE_PREFIX%>ConfigurationAdmin ca2 WHERE ca2.VariableName = cv.VariableName), cv.ElementType = (SELECT ca3.element_type FROM <%TABLE_PREFIX%>ConfigurationAdmin ca3 WHERE ca3.VariableName = cv.VariableName), cv.Validation = (SELECT ca4.Validation FROM <%TABLE_PREFIX%>ConfigurationAdmin ca4 WHERE ca4.VariableName = cv.VariableName), cv.ValueList = (SELECT ca5.ValueList FROM <%TABLE_PREFIX%>ConfigurationAdmin ca5 WHERE ca5.VariableName = cv.VariableName), cv.DisplayOrder = (SELECT ca6.DisplayOrder FROM <%TABLE_PREFIX%>ConfigurationAdmin ca6 WHERE ca6.VariableName = cv.VariableName), cv.GroupDisplayOrder = (SELECT ca7.GroupDisplayOrder FROM <%TABLE_PREFIX%>ConfigurationAdmin ca7 WHERE ca7.VariableName = cv.VariableName), cv.`Install` = (SELECT ca8.`Install` FROM <%TABLE_PREFIX%>ConfigurationAdmin ca8 WHERE ca8.VariableName = cv.VariableName); DROP TABLE ConfigurationAdmin; UPDATE ConfigurationValues SET ValueList = '=+||SELECT l%3$s_Name AS OptionName, CountryStateId AS OptionValue FROM CountryStates WHERE Type = 1 ORDER BY OptionName' WHERE ValueList = '=+||SELECT DestName AS OptionName, DestId AS OptionValue FROM StdDestinations WHERE COALESCE(DestParentId, 0) = 0 ORDER BY OptionName'; ALTER TABLE Forms ADD RequireLogin TINYINT NOT NULL DEFAULT '0', ADD INDEX (RequireLogin), ADD UseSecurityImage TINYINT NOT NULL DEFAULT '0', ADD INDEX (UseSecurityImage), ADD EnableEmailCommunication TINYINT NOT NULL DEFAULT '0', ADD INDEX (EnableEmailCommunication), ADD ReplyFromName VARCHAR(255) NOT NULL DEFAULT '', ADD ReplyFromEmail VARCHAR(255) NOT NULL DEFAULT '', ADD ReplyCc VARCHAR(255) NOT NULL DEFAULT '', ADD ReplyBcc VARCHAR(255) NOT NULL DEFAULT '', ADD ReplyMessageSignature TEXT, ADD ReplyServer VARCHAR(255) NOT NULL DEFAULT '', ADD ReplyPort INT(10) NOT NULL DEFAULT '110', ADD ReplyUsername VARCHAR(255) NOT NULL DEFAULT '', ADD ReplyPassword VARCHAR(255) NOT NULL DEFAULT '', ADD BounceEmail VARCHAR(255) NOT NULL DEFAULT '', ADD BounceServer VARCHAR(255) NOT NULL DEFAULT '', ADD BouncePort INT(10) NOT NULL DEFAULT '110', ADD BounceUsername VARCHAR(255) NOT NULL DEFAULT '', ADD BouncePassword VARCHAR(255) NOT NULL DEFAULT ''; ALTER TABLE FormFields ADD Visibility TINYINT NOT NULL DEFAULT '1', ADD INDEX (Visibility), ADD EmailCommunicationRole TINYINT NOT NULL DEFAULT '0', ADD INDEX (EmailCommunicationRole); ALTER TABLE FormSubmissions ADD IPAddress VARCHAR(15) NOT NULL DEFAULT '' AFTER SubmissionTime, ADD ReferrerURL VARCHAR(255) NOT NULL DEFAULT '' AFTER IPAddress, ADD LogStatus TINYINT UNSIGNED NOT NULL DEFAULT '2' AFTER ReferrerURL, ADD LastUpdatedOn INT UNSIGNED NULL AFTER LogStatus, ADD Notes TEXT NULL AFTER LastUpdatedOn, ADD INDEX (LogStatus), ADD INDEX (LastUpdatedOn); CREATE TABLE SubmissionLog ( SubmissionLogId int(11) NOT NULL AUTO_INCREMENT, FormSubmissionId int(10) unsigned NOT NULL, FromEmail varchar(255) NOT NULL DEFAULT '', ToEmail varchar(255) NOT NULL DEFAULT '', Cc text, Bcc text, `Subject` varchar(255) NOT NULL DEFAULT '', Message text, Attachment text, ReplyStatus tinyint(3) unsigned NOT NULL DEFAULT '0', SentStatus tinyint(3) unsigned NOT NULL DEFAULT '0', SentOn int(10) unsigned DEFAULT NULL, RepliedOn int(10) unsigned DEFAULT NULL, VerifyCode varchar(32) NOT NULL DEFAULT '', DraftId int(10) unsigned NOT NULL DEFAULT '0', MessageId varchar(255) NOT NULL DEFAULT '', BounceInfo text, BounceDate int(11) DEFAULT NULL, PRIMARY KEY (SubmissionLogId), KEY FormSubmissionId (FormSubmissionId), KEY ReplyStatus (ReplyStatus), KEY SentStatus (SentStatus), KEY SentOn (SentOn), KEY RepliedOn (RepliedOn), KEY VerifyCode (VerifyCode), KEY DraftId (DraftId), KEY BounceDate (BounceDate), KEY MessageId (MessageId) ); CREATE TABLE Drafts ( DraftId int(11) NOT NULL AUTO_INCREMENT, FormSubmissionId int(10) unsigned NOT NULL DEFAULT '0', CreatedOn int(10) unsigned DEFAULT NULL, CreatedById int(11) NOT NULL, Message text, PRIMARY KEY (DraftId), KEY FormSubmissionId (FormSubmissionId), KEY CreatedOn (CreatedOn), KEY CreatedById (CreatedById) ); INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'FORM.SUBMISSION.REPLY.TO.USER', NULL, 1, 0, NULL, 'Core:Category', 'Admin Reply to User Form Submission', 1); INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'FORM.SUBMISSION.REPLY.FROM.USER', NULL, 1, 0, NULL, 'Core:Category', 'User Replied to It\'s Form Submission', 1); INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'FORM.SUBMISSION.REPLY.FROM.USER.BOUNCED', NULL, 1, 0, NULL, 'Core:Category', 'Form Submission Admin Reply Delivery Failure', 1); ALTER TABLE ConfigurationValues ADD HintLabel VARCHAR(255) NULL DEFAULT NULL, ADD INDEX (HintLabel); UPDATE ConfigurationValues SET HintLabel = 'la_hint_MemcacheServers' WHERE VariableName = 'MemcacheServers'; INSERT INTO ConfigurationValues VALUES(DEFAULT, 'ModRewriteUrlEnding', '.html', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsWebsite', 'la_config_ModRewriteUrlEnding', 'select', '', '=+||/=+/||.html=+.html', 10.021, 0, 0, NULL); INSERT INTO ConfigurationValues VALUES(DEFAULT, 'ForceModRewriteUrlEnding', '0', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsWebsite', 'la_config_ForceModRewriteUrlEnding', 'checkbox', '', NULL, 10.022, 0, 0, 'la_hint_ForceModRewriteUrlEnding'); UPDATE Phrase SET l<%PRIMARY_LANGUAGE%>_Translation = 'Enable SEO-friendly URLs mode (MOD-REWRITE)' WHERE Phrase = 'la_config_use_modrewrite' AND l<%PRIMARY_LANGUAGE%>_Translation = 'Use MOD REWRITE'; INSERT INTO ConfigurationValues VALUES(DEFAULT, 'UseContentLanguageNegotiation', '0', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsWebsite', 'la_config_UseContentLanguageNegotiation', 'checkbox', '', '', 10.023, 0, 0, NULL); INSERT INTO ConfigurationValues VALUES(DEFAULT, 'SessionCookieDomains', '', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsSession', 'la_config_SessionCookieDomains', 'textarea', '', 'rows="5" cols="40"', 20.021, 0, 0, NULL); CREATE TABLE SiteDomains ( DomainId int(11) NOT NULL AUTO_INCREMENT, DomainName varchar(255) NOT NULL DEFAULT '', DomainNameUsesRegExp tinyint(4) NOT NULL DEFAULT '0', SSLUrl varchar(255) NOT NULL DEFAULT '', SSLUrlUsesRegExp tinyint(4) NOT NULL DEFAULT '0', AdminEmail varchar(255) NOT NULL DEFAULT '', Country varchar(3) NOT NULL DEFAULT '', PrimaryLanguageId int(11) NOT NULL DEFAULT '0', Languages varchar(255) NOT NULL DEFAULT '', PrimaryThemeId int(11) NOT NULL DEFAULT '0', Themes varchar(255) NOT NULL DEFAULT '', DomainIPRange text, ExternalUrl varchar(255) NOT NULL DEFAULT '', RedirectOnIPMatch tinyint(4) NOT NULL DEFAULT '0', Priority int(11) NOT NULL DEFAULT '0', PRIMARY KEY (DomainId), KEY DomainName (DomainName), KEY DomainNameUsesRegExp (DomainNameUsesRegExp), KEY SSLUrl (SSLUrl), KEY SSLUrlUsesRegExp (SSLUrlUsesRegExp), KEY AdminEmail (AdminEmail), KEY Country (Country), KEY PrimaryLanguageId (PrimaryLanguageId), KEY Languages (Languages), KEY PrimaryThemeId (PrimaryThemeId), KEY Themes (Themes), KEY ExternalUrl (ExternalUrl), KEY RedirectOnIPMatch (RedirectOnIPMatch), KEY Priority (Priority) ); DELETE FROM Phrase WHERE Phrase = 'la_config_time_server'; DELETE FROM ConfigurationValues WHERE VariableName = 'Config_Server_Time'; UPDATE ConfigurationValues SET ValueList = NULL, DisplayOrder = 20.02 WHERE VariableName = 'Config_Site_Time'; UPDATE ConfigurationValues SET VariableValue = '' WHERE VariableName = 'Config_Site_Time' AND VariableValue = 14; UPDATE Events SET AllowChangingSender = 1, AllowChangingRecipient = 1; UPDATE Events SET Module = 'Core' WHERE Module LIKE 'Core:%'; DELETE FROM Permissions WHERE Permission LIKE 'in-portal:configuration_email%'; DELETE FROM Permissions WHERE Permission LIKE 'in-portal:user_email%'; DELETE FROM Phrase WHERE Phrase IN ('la_fld_FromToUser', 'la_col_FromToUser'); # ===== v 5.1.0-B2 ===== # ===== v 5.1.0-RC1 ===== UPDATE Phrase SET Module = 'Core' WHERE Phrase = 'la_fld_Group'; UPDATE PermissionConfig SET Description = REPLACE(Description, 'lu_PermName_', 'la_PermName_'), ErrorMessage = REPLACE(ErrorMessage, 'lu_PermName_', 'la_PermName_'); UPDATE Phrase SET Phrase = REPLACE(Phrase, 'lu_PermName_', 'la_PermName_'), PhraseKey = REPLACE(PhraseKey, 'LU_PERMNAME_', 'LA_PERMNAME_'), PhraseType = 1 WHERE PhraseKey LIKE 'LU_PERMNAME_%'; UPDATE Phrase SET Phrase = 'la_no_permissions', PhraseKey = 'LA_NO_PERMISSIONS', PhraseType = 1 WHERE PhraseKey = 'LU_NO_PERMISSIONS'; UPDATE Phrase SET PhraseType = 0 WHERE PhraseKey IN ( 'LU_FERROR_FORGOTPW_NODATA', 'LU_FERROR_UNKNOWN_USERNAME', 'LU_FERROR_UNKNOWN_EMAIL' ); DELETE FROM ConfigurationValues WHERE VariableName = 'Root_Name'; DELETE FROM Phrase WHERE PhraseKey = 'LA_PROMPT_ROOT_NAME'; UPDATE ConfigurationValues SET DisplayOrder = DisplayOrder - 0.01 WHERE ModuleOwner = 'In-Portal' AND `Section` = 'in-portal:configure_categories' AND DisplayOrder > 10.07; # ===== v 5.1.0 ===== UPDATE Events SET Headers = NULL WHERE Headers = ''; UPDATE Events SET MessageType = 'text' WHERE Event = 'FORM.SUBMISSION.REPLY.TO.USER'; ALTER TABLE Forms ADD ProcessUnmatchedEmails TINYINT NOT NULL DEFAULT '0' AFTER EnableEmailCommunication, ADD INDEX (ProcessUnmatchedEmails); ALTER TABLE FormSubmissions ADD MessageId VARCHAR(255) NULL DEFAULT NULL AFTER Notes, ADD INDEX (MessageId); # ===== v 5.1.1-B1 ===== ALTER TABLE PortalUser ADD DisplayToPublic TEXT NULL; UPDATE Phrase SET l<%PRIMARY_LANGUAGE%>_Translation = 'Comments' WHERE PhraseKey = 'LA_FLD_COMMENTS'; ALTER TABLE Category CHANGE `Type` `Type` INT(11) NOT NULL DEFAULT '1', CHANGE `IsSystem` `Protected` TINYINT( 4 ) NOT NULL DEFAULT '0', ADD INDEX ( `Protected` ); UPDATE Category SET `Type` = IF(`Protected` = 1, 2, 1); UPDATE Category SET `Protected` = 1 WHERE ThemeId > 0; ALTER TABLE Category CHANGE CachedDescendantCatsQty CachedDescendantCatsQty INT(11) NOT NULL DEFAULT '0'; ALTER TABLE Events CHANGE `Module` `Module` VARCHAR(40) NOT NULL DEFAULT 'Core'; ALTER TABLE Language CHANGE DateFormat DateFormat VARCHAR(50) NOT NULL DEFAULT 'm/d/Y', CHANGE TimeFormat TimeFormat VARCHAR(50) NOT NULL DEFAULT 'g:i:s A', CHANGE DecimalPoint DecimalPoint VARCHAR(10) NOT NULL DEFAULT '.', CHANGE Charset Charset VARCHAR(20) NOT NULL DEFAULT 'utf-8'; ALTER TABLE ItemReview CHANGE Rating Rating TINYINT(3) UNSIGNED NOT NULL DEFAULT '0'; UPDATE PortalUser SET tz = NULL; ALTER TABLE Category CHANGE CreatedById CreatedById INT(11) NULL DEFAULT NULL, CHANGE ModifiedById ModifiedById INT(11) NULL DEFAULT NULL; UPDATE Category SET CreatedById = NULL WHERE CreatedById = 0; UPDATE Category SET ModifiedById = NULL WHERE ModifiedById = 0; ALTER TABLE ItemFiles CHANGE CreatedById CreatedById INT(11) NULL DEFAULT NULL; ALTER TABLE Drafts CHANGE CreatedById CreatedById INT(11) NULL DEFAULT NULL; UPDATE Drafts SET CreatedById = NULL WHERE CreatedById = 0; ALTER TABLE ItemReview CHANGE CreatedById CreatedById INT(11) NULL DEFAULT NULL; # ===== v 5.1.1-B2 ===== UPDATE Phrase SET `Module` = 'Core' WHERE PhraseKey = 'LU_SECTION_FILES'; # ===== v 5.1.1-RC1 ===== ALTER TABLE PortalUser CHANGE Phone Phone VARCHAR(255) NOT NULL DEFAULT '', CHANGE City City VARCHAR(255) NOT NULL DEFAULT '', CHANGE Street Street VARCHAR(255) NOT NULL DEFAULT '', CHANGE Zip Zip VARCHAR(20) NOT NULL DEFAULT '', CHANGE ip ip VARCHAR(20) NOT NULL DEFAULT ''; UPDATE Phrase SET l<%PRIMARY_LANGUAGE%>_Translation = 'Use Cron to run Agents' WHERE PhraseKey = 'LA_USECRONFORREGULAREVENT' AND l<%PRIMARY_LANGUAGE%>_Translation = 'Use Cron for Running Regular Events'; # ===== v 5.1.1 ===== # ===== v 5.1.2-B1 ===== DROP TABLE EmailSubscribers; DROP TABLE IgnoreKeywords; DROP TABLE IgnoreKeywords; ALTER TABLE PermissionConfig DROP ErrorMessage; # ===== v 5.1.2-B2 ===== # ===== v 5.1.2-RC1 ===== DROP TABLE Stylesheets; DROP TABLE StylesheetSelectors; DROP TABLE SysCache; DROP TABLE TagAttributes; DROP TABLE TagLibrary; DELETE FROM Phrase WHERE PhraseKey IN ( 'LA_FLD_STYLESHEETID', 'LA_PROMPT_STYLESHEET', 'LA_TAB_STYLESHEETS', 'LA_TITLE_ADDING_STYLESHEET', 'LA_TITLE_EDITING_STYLESHEET', 'LA_TITLE_NEW_STYLESHEET', 'LA_TITLE_STYLESHEETS', 'LA_TOOLTIP_NEWSTYLESHEET', 'LA_COL_SELECTORNAME', 'LA_COL_BASEDON', 'LA_FLD_SELECTORBASE', 'LA_FLD_SELECTORDATA', 'LA_FLD_SELECTORID', 'LA_FLD_SELECTORNAME' ); # ===== v 5.1.2 ===== # ===== v 5.1.3-B1 ===== ALTER TABLE FormSubmissions CHANGE ReferrerURL ReferrerURL TEXT NULL; INSERT INTO ConfigurationValues VALUES (DEFAULT, 'UserEmailActivationTimeout', '', 'In-Portal:Users', 'in-portal:configure_users', 'la_title_General', 'la_config_UserEmailActivationTimeout', 'text', NULL, NULL, 10.051, 0, 0, NULL); # ===== v 5.1.3-B2 ===== ALTER TABLE Modules ADD AppliedDBRevisions TEXT NULL; # ===== v 5.1.3-RC1 ===== # ===== v 5.1.3-RC2 ===== UPDATE Events SET l<%PRIMARY_LANGUAGE%>_Subject = 'New User Registration ( - Activation Email)' WHERE Event = 'USER.ADD.PENDING' AND `Type` = 0 AND l<%PRIMARY_LANGUAGE%>_Subject LIKE '% - Activation Email)%'; INSERT INTO ConfigurationValues VALUES(DEFAULT, 'MaxUserName', '', 'In-Portal:Users', 'in-portal:configure_users', 'la_title_General', 'la_text_min_username', 'text', '', 'style="width: 50px;"', 10.03, 2, 0, NULL); UPDATE ConfigurationValues SET GroupDisplayOrder = 1, ValueList = 'style="width: 50px;"' WHERE VariableName = 'Min_UserName'; UPDATE Phrase SET l<%PRIMARY_LANGUAGE%>_Translation = 'User name length (min - max)' WHERE PhraseKey = 'LA_TEXT_MIN_USERNAME' AND l<%PRIMARY_LANGUAGE%>_Translation = 'Minimum user name length'; # ===== v 5.1.3 ===== UPDATE PortalUser SET Modified = NULL; INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:site_domains.delete', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:site_domains.edit', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:site_domains.add', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:site_domains.view', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:country_states.delete', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:country_states.edit', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:country_states.add', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:country_states.view', 11, 1, 1, 0); # ===== v 5.2.0-B1 ===== ALTER TABLE PortalUser ADD UserType TINYINT NOT NULL, ADD PrimaryGroupId INT NULL, ADD INDEX (UserType); UPDATE PortalUser u SET u.PrimaryGroupId = (SELECT ug.GroupId FROM <%TABLE_PREFIX%>UserGroup ug WHERE ug.PortalUserId = u.PortalUserId AND ug.PrimaryGroup = 1); UPDATE PortalUser u SET u.UserType = IF(u.PrimaryGroupId = 11, 1, 0); ALTER TABLE UserGroup DROP PrimaryGroup; UPDATE ConfigurationValues SET DisplayOrder = DisplayOrder + 0.01 WHERE `ModuleOwner` = 'In-Portal:Users' AND `Section` = 'in-portal:configure_users' AND DisplayOrder BETWEEN 10.12 AND 20.00; INSERT INTO ConfigurationValues VALUES(DEFAULT, 'User_AdminGroup', '11', 'In-Portal:Users', 'in-portal:configure_users', 'la_title_General', 'la_users_admin_group', 'select', NULL, '0=lu_none||SELECT GroupId as OptionValue, Name as OptionName FROM PortalGroup WHERE Enabled=1 AND Personal=0', 10.12, 0, 1, NULL); ALTER TABLE PortalUser DROP INDEX Login, ADD INDEX Login (Login); ALTER TABLE PortalUser CHANGE Login Login VARCHAR(255) NOT NULL; ALTER TABLE PortalUser ADD OldStyleLogin TINYINT NOT NULL; UPDATE PortalUser SET OldStyleLogin = 1 WHERE (Login <> '') AND (Login NOT REGEXP '^[A-Z0-9_\\-\\.]+$'); DELETE FROM Events WHERE Event = 'USER.PSWD'; UPDATE Phrase SET l<%PRIMARY_LANGUAGE%>_Translation = 'Your password has been reset.' WHERE PhraseKey = 'LU_TEXT_FORGOTPASSHASBEENRESET' AND l<%PRIMARY_LANGUAGE%>_Translation = 'Your password has been reset. The new password has been sent to your e-mail address. You may now login with the new password.'; ALTER TABLE PortalUser DROP MinPwResetDelay, DROP PassResetTime, CHANGE PwResetConfirm PwResetConfirm VARCHAR(255) NOT NULL; UPDATE PortalUser SET PwRequestTime = NULL WHERE PwRequestTime = 0; ALTER TABLE Category ADD DirectLinkEnabled TINYINT NOT NULL DEFAULT '1', ADD DirectLinkAuthKey VARCHAR(20) NOT NULL; UPDATE Category SET DirectLinkAuthKey = SUBSTRING( MD5( CONCAT(CategoryId, ':', ParentId, ':', l<%PRIMARY_LANGUAGE%>_Name, ':b38') ), 1, 20) WHERE DirectLinkAuthKey = ''; INSERT INTO ConfigurationValues VALUES(DEFAULT, 'ExcludeTemplateSectionsFromSearch', '0', 'In-Portal', 'in-portal:configure_categories', 'la_title_General', 'la_config_ExcludeTemplateSectionsFromSearch', 'checkbox', '', '', 10.15, 0, 0, NULL); ALTER TABLE Agents ADD SiteDomainLimitation VARCHAR(255) NOT NULL, ADD INDEX (SiteDomainLimitation); UPDATE ConfigurationValues SET DisplayOrder = DisplayOrder + 0.01 WHERE VariableName = 'HTTPAuthBypassIPs'; UPDATE ConfigurationValues SET DisplayOrder = DisplayOrder + 0.01 WHERE ModuleOwner = 'In-Portal' AND `Section` = 'in-portal:configure_advanced' AND Heading = 'la_section_SettingsAdmin' AND DisplayOrder > 40.06; INSERT INTO ConfigurationValues VALUES (DEFAULT, 'StickyGridSelection', '1', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsAdmin', 'la_config_StickyGridSelection', 'radio', '', '1=la_Yes||0=la_No', 40.07, 0, 0, NULL); ALTER TABLE Forms ADD SubmitNotifyEmail VARCHAR(255) NOT NULL DEFAULT '' AFTER UseSecurityImage; ALTER TABLE FormFields ADD UploadExtensions VARCHAR(255) NOT NULL DEFAULT '' AFTER Validation, ADD UploadMaxSize INT NULL AFTER UploadExtensions; ALTER TABLE Language ADD SynchronizationModes VARCHAR(255) NOT NULL DEFAULT ''; ALTER TABLE PortalUser CHANGE ip IPAddress VARCHAR(15) NOT NULL, ADD IPRestrictions TEXT NULL; ALTER TABLE PortalGroup ADD IPRestrictions TEXT NULL; INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, Module, Description, Type, AllowChangingSender, AllowChangingRecipient) VALUES(DEFAULT, 'ROOT.RESET.PASSWORD', NULL, 1, 0, 'Core', 'Root Reset Password', 1, 1, 0); ALTER TABLE Skins ADD DisplaySiteNameInHeader TINYINT(1) NOT NULL DEFAULT '1'; DELETE FROM PersistantSessionData WHERE VariableName LIKE 'formsubs_Sort%' AND VariableValue = 'FormFieldId'; ALTER TABLE ItemReview ADD HelpfulCount INT NOT NULL , ADD NotHelpfulCount INT NOT NULL; ALTER TABLE PermissionConfig ADD IsSystem TINYINT(1) NOT NULL DEFAULT '0'; UPDATE PermissionConfig SET IsSystem = 1; INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:permission_types.view', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:permission_types.add', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:permission_types.edit', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:permission_types.delete', 11, 1, 1, 0); ALTER TABLE Agents ADD Timeout INT(10) UNSIGNED NULL AFTER RunTime, ADD LastTimeoutOn int(10) unsigned default NULL AFTER Timeout, ADD INDEX (Timeout); CREATE TABLE CurlLog ( LogId int(11) NOT NULL AUTO_INCREMENT, Message varchar(255) NOT NULL, PageUrl varchar(255) NOT NULL, RequestUrl varchar(255) NOT NULL, PortalUserId int(11) NOT NULL, SessionKey int(11) NOT NULL, IsAdmin tinyint(4) NOT NULL, PageData text, RequestData text, ResponseData text, RequestDate int(11) DEFAULT NULL, ResponseDate int(11) DEFAULT NULL, ResponseHttpCode int(11) NOT NULL, CurlError varchar(255) NOT NULL, PRIMARY KEY (LogId), KEY Message (Message), KEY PageUrl (PageUrl), KEY RequestUrl (RequestUrl), KEY PortalUserId (PortalUserId), KEY SessionKey (SessionKey), KEY IsAdmin (IsAdmin), KEY RequestDate (RequestDate), KEY ResponseDate (ResponseDate), KEY ResponseHttpCode (ResponseHttpCode), KEY CurlError (CurlError) ); DELETE FROM ConfigurationValues WHERE VariableName = 'Site_Path'; UPDATE ConfigurationValues SET DisplayOrder = DisplayOrder + 0.01 WHERE `Section` = 'in-portal:configure_advanced' AND Heading = 'la_section_SettingsWebsite'; UPDATE ItemTypes SET TitleField = 'Username' WHERE SourceTable = 'PortalUser' AND TitleField = 'Login'; UPDATE SearchConfig SET FieldName = 'Username' WHERE TableName = 'PortalUser' AND FieldName = 'Login'; ALTER TABLE PortalUser DROP INDEX Login; ALTER TABLE PortalUser CHANGE Login Username VARCHAR(255) NOT NULL; ALTER TABLE PortalUser ADD INDEX Username (Username); UPDATE Events SET l<%PRIMARY_LANGUAGE%>_Subject = REPLACE(l<%PRIMARY_LANGUAGE%>_Subject, 'name="Login"', 'name="Username"'), l<%PRIMARY_LANGUAGE%>_Body = REPLACE(l<%PRIMARY_LANGUAGE%>_Body, 'name="Login"', 'name="Username"'); DELETE FROM PersistantSessionData WHERE (VariableName LIKE 'u%]columns_.') OR (VariableName LIKE 'u%_sort%'); DELETE FROM Phrase WHERE Phrase = 'LU_FLD_LOGIN'; UPDATE BanRules SET ItemField = 'Username' WHERE ItemField = 'Login'; DELETE FROM Phrase WHERE PhraseKey IN ( 'LU_USERNAME', 'LU_EMAIL', 'LU_PASSWORD', 'LA_TEXT_LOGIN', 'LA_PROMPT_PASSWORD', 'LA_USE_EMAILS_AS_LOGIN', 'LU_USER_AND_EMAIL_ALREADY_EXIST', 'LU_ENTERFORGOTEMAIL' ); UPDATE ConfigurationValues SET VariableName = 'RegistrationUsernameRequired', Prompt = 'la_config_RegistrationUsernameRequired' WHERE VariableName = 'Email_As_Login'; UPDATE ConfigurationValues SET VariableValue = IF(VariableValue = 1, 0, 1) WHERE VariableName = 'RegistrationUsernameRequired'; INSERT INTO ConfigurationValues VALUES (DEFAULT, 'PerformExactSearch', '1', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsWebsite', 'la_config_PerformExactSearch', 'checkbox', '', '', '10.10', 0, 0, 'la_hint_PerformExactSearch'); UPDATE Phrase SET PhraseType = 1 WHERE PhraseKey IN ( 'LA_USERS_SUBSCRIBER_GROUP', 'LA_PROMPT_DUPREVIEWS', 'LA_PROMPT_DUPREVIEWS', 'LA_PROMPT_DUPRATING', 'LA_PROMPT_OVERWRITEPHRASES', 'LA_TEXT_BACKUP_ACCESS', 'LA_PHRASETYPE_BOTH', 'LA_TOOLTIP_NEWLISTING' ); UPDATE Phrase SET PhraseType = 0 WHERE PhraseKey IN ('LU_TITLE_SHIPPINGINFORMATION', 'LU_COMM_LASTQUATER'); UPDATE Phrase SET Phrase = REPLACE(Phrase, 'lu_', 'la_'), PhraseKey = UPPER(Phrase) WHERE PhraseKey IN ('LU_OPT_AUTODETECT', 'LU_OPT_COOKIES', 'LU_OPT_QUERYSTRING'); UPDATE ConfigurationValues SET ValueList = REPLACE(ValueList, 'lu_', 'la_') WHERE VariableName = 'CookieSessions'; DELETE FROM Phrase WHERE PhraseKey IN ('LU_INVALID_PASSWORD', 'LA_OF', 'LU_TITLE_REVIEWPRODUCT'); UPDATE Phrase SET PhraseType = 2 WHERE PhraseType = 1 AND (PhraseKey LIKE 'lu_field_%' OR PhraseKey = 'LA_TEXT_VALID'); UPDATE Phrase SET Phrase = REPLACE(Phrase, 'la_', 'lc_'), PhraseKey = UPPER(Phrase) WHERE PhraseType = 2; UPDATE Phrase SET Phrase = REPLACE(Phrase, 'lu_', 'lc_'), PhraseKey = UPPER(Phrase) WHERE PhraseType = 2; UPDATE SearchConfig SET DisplayName = REPLACE(DisplayName, 'lu_', 'lc_') WHERE DisplayName IN ( 'lu_field_newitem', 'lu_field_popitem', 'lu_field_hotitem', 'lu_field_resourceid', 'lu_field_createdbyid', 'lu_field_priority', 'lu_field_status', 'lu_field_createdon', 'lu_field_description', 'lu_field_name', 'lu_field_modified', 'lu_field_modifiedbyid', 'lu_field_ParentPath', 'lu_field_ParentId', 'lu_field_MetaKeywords', 'lu_field_MetaDescription', 'lu_field_EditorsPick', 'lu_field_CategoryId', 'lu_field_CachedNavBar', 'lu_field_CachedDescendantCatsQty', 'lu_field_hits', 'lu_field_cachedrating', 'lu_field_cachedvotesqty', 'lu_field_cachedreviewsqty', 'lu_field_orgid' ); CREATE TABLE SpamReports ( ReportId int(11) NOT NULL AUTO_INCREMENT, ItemPrefix varchar(255) NOT NULL, ItemId int(11) NOT NULL, MessageText text, ReportedOn int(11) DEFAULT NULL, ReportedById int(11) DEFAULT NULL, PRIMARY KEY (ReportId), KEY ItemPrefix (ItemPrefix), KEY ItemId (ItemId), KEY ReportedById (ReportedById) ); DELETE FROM Phrase WHERE PhraseKey IN ( 'LA_SECTION_SETTINGSCACHING', 'LA_CONFIG_CACHEHANDLER', 'LA_CONFIG_MEMCACHESERVERS', 'LA_HINT_MEMCACHESERVERS' ); DELETE FROM ConfigurationValues WHERE VariableName IN ('CacheHandler', 'MemcacheServers'); CREATE TABLE PromoBlocks ( BlockId int(11) NOT NULL AUTO_INCREMENT, Title varchar(50) NOT NULL DEFAULT '', Priority int(11) NOT NULL DEFAULT '0', Status tinyint(1) NOT NULL DEFAULT '0', l1_Image varchar(255) NOT NULL DEFAULT '', l2_Image varchar(255) NOT NULL DEFAULT '', l3_Image varchar(255) NOT NULL DEFAULT '', l4_Image varchar(255) NOT NULL DEFAULT '', l5_Image varchar(255) NOT NULL DEFAULT '', CSSClassName varchar(255) NOT NULL DEFAULT '', LinkType tinyint(1) NOT NULL DEFAULT '1', CategoryId int(11) NOT NULL DEFAULT '0', ExternalLink varchar(255) NOT NULL DEFAULT '', OpenInNewWindow tinyint(3) unsigned NOT NULL DEFAULT '0', ScheduleFromDate int(11) DEFAULT NULL, ScheduleToDate int(11) DEFAULT NULL, NumberOfClicks int(11) NOT NULL DEFAULT '0', NumberOfViews int(11) NOT NULL DEFAULT '0', Sticky tinyint(1) NOT NULL DEFAULT '0', Html text, l1_Html text, l2_Html text, l3_Html text, l4_Html text, l5_Html text, PRIMARY KEY (BlockId), KEY OpenInNewWindow (OpenInNewWindow) ); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'PromoRotationDelay', '7', 'In-Portal', 'in-portal:configure_promo_blocks', 'la_Text_PromoSettings', 'la_config_PromoRotationDelay', 'text', '', '', 10.01, 0, 0, NULL); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'PromoTransitionTime', '0.6', 'In-Portal', 'in-portal:configure_promo_blocks', 'la_Text_PromoSettings', 'la_config_PromoTransitionTime', 'text', '', '', 10.02, 0, 0, NULL); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'PromoTransitionControls', '1', 'In-Portal', 'in-portal:configure_promo_blocks', 'la_Text_PromoSettings', 'la_config_PromoTransitionControls', 'select', '', '1=la_Enabled||0=la_Disabled', 10.03, 0, 0, NULL); INSERT INTO ConfigurationValues VALUES (DEFAULT, 'PromoTransitionEffect', 'fade', 'In-Portal', 'in-portal:configure_promo_blocks', 'la_Text_PromoSettings', 'la_config_PromoTransitionEffect', 'select', '', 'fade=la_opt_AnimationFade||slide=la_opt_AnimationSlide', 10.04, 0, 0, NULL); UPDATE Phrase SET l<%PRIMARY_LANGUAGE%>_ColumnTranslation = l<%PRIMARY_LANGUAGE%>_Translation WHERE PhraseKey IN ('LA_FLD_CATEGORY', 'LA_FLD_ORDER'); CREATE TABLE PageRevisions ( RevisionId int(11) NOT NULL AUTO_INCREMENT, PageId int(11) NOT NULL, RevisionNumber int(11) NOT NULL, IsDraft tinyint(4) NOT NULL, FromRevisionId int(11) NOT NULL, CreatedById int(11) DEFAULT NULL, CreatedOn int(11) DEFAULT NULL, AutoSavedOn int(11) DEFAULT NULL, `Status` tinyint(4) NOT NULL DEFAULT '2', PRIMARY KEY (RevisionId), KEY PageId (PageId), KEY RevisionNumber (RevisionNumber), KEY IsDraft (IsDraft), KEY `Status` (`Status`) ); ALTER TABLE Category ADD LiveRevisionNumber INT NOT NULL DEFAULT '1' AFTER PageExpiration, ADD INDEX (LiveRevisionNumber); ALTER TABLE PageContent ADD RevisionId INT NOT NULL AFTER PageId, ADD INDEX (RevisionId); ALTER TABLE PermissionConfig CHANGE PermissionName PermissionName VARCHAR(255) NOT NULL DEFAULT ''; INSERT INTO PermissionConfig VALUES (DEFAULT, 'CATEGORY.REVISION.ADD', 'la_PermName_Category.Revision.Add_desc', 'In-Portal', 1); INSERT INTO PermissionConfig VALUES (DEFAULT, 'CATEGORY.REVISION.ADD.PENDING', 'la_PermName_Category.Revision.Add.Pending_desc', 'In-Portal', 1); INSERT INTO PermissionConfig VALUES (DEFAULT, 'CATEGORY.REVISION.MODERATE', 'la_PermName_Category.Revision.Moderate_desc', 'In-Portal', 1); INSERT INTO PermissionConfig VALUES (DEFAULT, 'CATEGORY.REVISION.HISTORY.VIEW', 'la_PermName_Category.Revision.History.View_desc', 'In-Portal', 1); INSERT INTO PermissionConfig VALUES (DEFAULT, 'CATEGORY.REVISION.HISTORY.RESTORE', 'la_PermName_Category.Revision.History.Restore_desc', 'In-Portal', 1); INSERT INTO Permissions VALUES(DEFAULT, 'CATEGORY.REVISION.ADD', 11, 1, 0, 1); INSERT INTO Permissions VALUES(DEFAULT, 'CATEGORY.REVISION.HISTORY.VIEW', 11, 1, 0, 1); INSERT INTO Permissions VALUES(DEFAULT, 'CATEGORY.REVISION.HISTORY.RESTORE', 11, 1, 0, 1); ALTER TABLE EmailQueue ADD `LogData` TEXT; UPDATE Permissions SET Permission = REPLACE(Permission, 'agents', 'scheduled_tasks') WHERE Permission LIKE 'in-portal:agents%'; DELETE FROM Phrase WHERE PhraseKey IN ( 'LA_TITLE_ADDINGAGENT', 'LA_TITLE_EDITINGAGENT', 'LA_TITLE_NEWAGENT', 'LA_TITLE_AGENTS', 'LA_TOOLTIP_NEWAGENT' ); UPDATE Phrase SET l<%PRIMARY_LANGUAGE%>_Translation = REPLACE(l<%PRIMARY_LANGUAGE%>_Translation, 'Agents', 'Scheduled Tasks') WHERE PhraseKey IN ( 'LA_USECRONFORREGULAREVENT', 'LA_HINT_SYSTEMTOOLSRESETPARSEDCACHEDDATA', 'LA_HINT_SYSTEMTOOLSRESETCONFIGSANDPARSEDDATA' ); DELETE FROM PersistantSessionData WHERE VariableName LIKE 'agent%'; RENAME TABLE <%TABLE_PREFIX%>Agents TO <%TABLE_PREFIX%>ScheduledTasks; ALTER TABLE ScheduledTasks CHANGE AgentId ScheduledTaskId INT(11) NOT NULL AUTO_INCREMENT, CHANGE AgentName Name VARCHAR(255) NOT NULL DEFAULT '', CHANGE AgentType `Type` TINYINT(3) UNSIGNED NOT NULL DEFAULT '1'; ALTER TABLE ScheduledTasks DROP INDEX AgentType, ADD INDEX `Type` (`Type`); UPDATE ConfigurationValues SET VariableName = 'RunScheduledTasksFromCron' WHERE VariableName = 'UseCronForRegularEvent'; CREATE TABLE ItemFilters ( FilterId int(11) NOT NULL AUTO_INCREMENT, ItemPrefix varchar(255) NOT NULL, FilterField varchar(255) NOT NULL, FilterType varchar(100) NOT NULL, Enabled tinyint(4) NOT NULL DEFAULT '1', RangeCount int(11) DEFAULT NULL, PRIMARY KEY (FilterId), KEY ItemPrefix (ItemPrefix), KEY Enabled (Enabled) ); UPDATE ConfigurationValues SET HintLabel = CONCAT('hint:', Prompt) WHERE VariableName IN ('ForceModRewriteUrlEnding', 'PerformExactSearch'); DELETE FROM Phrase WHERE PhraseKey IN ( 'LA_TEXT_PROMOSETTINGS', 'LA_CONFIG_PROMOROTATIONDELAY', 'LA_CONFIG_PROMOTRANSITIONTIME', 'LA_CONFIG_PROMOTRANSITIONCONTROLS', 'LA_CONFIG_PROMOTRANSITIONEFFECT' ); DELETE FROM ConfigurationValues WHERE VariableName IN ('PromoRotationDelay', 'PromoTransitionTime', 'PromoTransitionControls', 'PromoTransitionEffect'); DELETE FROM Permissions WHERE Permission LIKE 'in-portal:promo_blocks.%'; CREATE TABLE PromoBlockGroups ( PromoBlockGroupId int(11) NOT NULL AUTO_INCREMENT, Title varchar(255) NOT NULL DEFAULT '', CreatedOn int(10) unsigned DEFAULT NULL, `Status` tinyint(1) NOT NULL DEFAULT '1', RotationDelay decimal(9,2) DEFAULT NULL, TransitionTime decimal(9,2) DEFAULT NULL, TransitionControls tinyint(1) NOT NULL DEFAULT '1', TransitionEffect varchar(255) NOT NULL DEFAULT '', TransitionEffectCustom varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (PromoBlockGroupId) ); ALTER TABLE Category ADD PromoBlockGroupId int(10) unsigned NOT NULL DEFAULT '0', ADD INDEX (PromoBlockGroupId); ALTER TABLE PromoBlocks ADD PromoBlockGroupId int(10) unsigned NOT NULL DEFAULT '0', ADD INDEX (PromoBlockGroupId); INSERT INTO ConfigurationValues VALUES(DEFAULT, 'DebugOnlyPromoBlockGroupConfigurator', '1', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsAdmin', 'la_config_DebugOnlyPromoBlockGroupConfigurator', 'checkbox', '', '', 40.13, 0, 0, NULL); UPDATE ConfigurationValues SET DisplayOrder = DisplayOrder + 0.01 WHERE VariableName IN ('RememberLastAdminTemplate', 'UseHTTPAuth', 'HTTPAuthUsername', 'HTTPAuthPassword', 'HTTPAuthBypassIPs'); INSERT INTO PromoBlockGroups VALUES (DEFAULT, 'Default Group', UNIX_TIMESTAMP(), '1', '7.00', '0.60', '1', 'fade', ''); UPDATE PromoBlocks SET PromoBlockGroupId = 1; INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:promo_block_groups.view', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:promo_block_groups.add', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:promo_block_groups.edit', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:promo_block_groups.delete', 11, 1, 1, 0); INSERT INTO ConfigurationValues VALUES(DEFAULT, 'MaintenanceMessageFront', 'Website is currently undergoing the upgrades. Please come back shortly!', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsMaintenance', 'la_config_MaintenanceMessageFront', 'textarea', '', 'style="width: 100%; height: 100px;"', '15.01', 0, 0, 'hint:la_config_MaintenanceMessageFront'); INSERT INTO ConfigurationValues VALUES(DEFAULT, 'MaintenanceMessageAdmin', 'Website is currently undergoing the upgrades. Please come back shortly!', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsMaintenance', 'la_config_MaintenanceMessageAdmin', 'textarea', '', 'style="width: 100%; height: 100px;"', '15.02', 0, 0, 'hint:la_config_MaintenanceMessageAdmin'); INSERT INTO ConfigurationValues VALUES(DEFAULT, 'SoftMaintenanceTemplate', 'maintenance', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsMaintenance', 'la_config_SoftMaintenanceTemplate', 'text', '', 'style="width: 200px;"', '15.03', 0, 0, 'hint:la_config_SoftMaintenanceTemplate'); INSERT INTO ConfigurationValues VALUES(DEFAULT, 'HardMaintenanceTemplate', 'maintenance', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsMaintenance', 'la_config_HardMaintenanceTemplate', 'text', '', 'style="width: 200px;"', '15.04', 0, 0, 'hint:la_config_HardMaintenanceTemplate'); UPDATE ConfigurationValues SET VariableName = 'DefaultEmailSender' WHERE VariableName = 'Smtp_AdminMailFrom'; INSERT INTO ConfigurationValues VALUES(DEFAULT, 'DefaultEmailRecipients', '', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsMailling', 'la_config_DefaultEmailRecipients', 'text', NULL, NULL, 50.10, 0, 0, NULL); ALTER TABLE SiteDomains ADD DefaultEmailRecipients TEXT NULL AFTER AdminEmail; UPDATE ConfigurationValues SET Section = 'in-portal:configure_advanced', Heading = 'la_section_Settings3rdPartyAPI', DisplayOrder = 80.01 WHERE VariableName = 'YahooApplicationId'; UPDATE ConfigurationValues SET DisplayOrder = DisplayOrder - 0.01 WHERE VariableName IN ('Search_MinKeyword_Length', 'ExcludeTemplateSectionsFromSearch'); UPDATE Phrase SET l<%PRIMARY_LANGUAGE%>_ColumnTranslation = l<%PRIMARY_LANGUAGE%>_Translation WHERE PhraseKey IN ('LA_FLD_ADDRESSLINE1', 'LA_FLD_ADDRESSLINE2', 'LA_FLD_CITY', 'LA_FLD_COMPANY', 'LA_FLD_FAX', 'LA_FLD_STATE', 'LA_FLD_ZIP'); DELETE FROM Phrase WHERE PhraseKey IN ('LA_TEXT_RESTRICTIONS', 'LA_USERS_REVIEW_DENY', 'LA_USERS_VOTES_DENY'); DELETE FROM ConfigurationValues WHERE VariableName IN ('User_Review_Deny', 'User_Votes_Deny'); ALTER TABLE PortalUser ADD FrontLanguage INT(11) NULL AFTER PwRequestTime; ALTER TABLE PortalUser DROP INDEX AdminLanguage; UPDATE PortalUser SET FrontLanguage = 1 WHERE UserType = 0; ALTER TABLE PortalUser ADD PrevEmails TEXT NULL AFTER Email, ADD EmailVerified TINYINT NOT NULL AFTER `Status`; UPDATE PortalUser SET EmailVerified = 1; INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, Module, Description, Type, AllowChangingSender, AllowChangingRecipient) VALUES(DEFAULT, 'USER.EMAIL.CHANGE.VERIFY', NULL, 1, 0, 'Core', 'Changed E-mail Verification', 0, 1, 1); INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, Module, Description, Type, AllowChangingSender, AllowChangingRecipient) VALUES(DEFAULT, 'USER.EMAIL.CHANGE.UNDO', NULL, 1, 0, 'Core', 'Changed E-mail Rollback', 0, 1, 1); ALTER TABLE Category ADD RequireSSL TINYINT NOT NULL DEFAULT '0', ADD RequireLogin TINYINT NOT NULL DEFAULT '0'; INSERT INTO ConfigurationValues VALUES(DEFAULT, 'UpdateCountersOnFilterChange', '1', 'In-Portal', 'in-portal:configure_categories', 'la_title_General', 'la_config_UpdateCountersOnFilterChange', 'checkbox', '', '', 10.15, 0, 0, NULL); # use new table name (see /core/install.php:390)! ALTER TABLE UserSessions DROP `tz`; ALTER TABLE UserSessions ADD `TimeZone` VARCHAR(255) NOT NULL AFTER `GroupList`; ALTER TABLE PortalUser DROP `tz`; ALTER TABLE PortalUser ADD `TimeZone` VARCHAR(255) NOT NULL AFTER `dob`; UPDATE SearchConfig SET FieldName = 'TimeZone' WHERE FieldName = 'tz' AND TableName = 'PortalUser'; RENAME TABLE <%TABLE_PREFIX%>BanRules TO <%TABLE_PREFIX%>UserBanRules; RENAME TABLE <%TABLE_PREFIX%>Cache TO <%TABLE_PREFIX%>SystemCache; RENAME TABLE <%TABLE_PREFIX%>ConfigurationValues TO <%TABLE_PREFIX%>SystemSettings; RENAME TABLE <%TABLE_PREFIX%>Category TO <%TABLE_PREFIX%>Categories; UPDATE ItemTypes SET SourceTable = 'Categories' WHERE ItemType = 1; UPDATE ItemTypes SET SourceTable = 'Users' WHERE ItemType = 6; UPDATE SearchConfig SET TableName = 'Categories' WHERE TableName = 'Category'; UPDATE SearchConfig SET TableName = 'CustomFields' WHERE TableName = 'CustomField'; UPDATE SearchConfig SET TableName = 'Users' WHERE TableName = 'PortalUser'; UPDATE StatItem SET ValueSQL = REPLACE(ValueSQL, '<%prefix%>Category', '<%prefix%>Categories'); UPDATE StatItem SET ValueSQL = REPLACE(ValueSQL, '<%prefix%>ItemReview', '<%prefix%>CatalogReviews'); UPDATE StatItem SET ValueSQL = REPLACE(ValueSQL, '<%prefix%>Language', '<%prefix%>Languages'); UPDATE StatItem SET ValueSQL = REPLACE(ValueSQL, '<%prefix%>PortalGroup', '<%prefix%>UserGroups'); UPDATE StatItem SET ValueSQL = REPLACE(ValueSQL, '<%prefix%>PortalUser', '<%prefix%>Users'); UPDATE StatItem SET ValueSQL = REPLACE(ValueSQL, '<%prefix%>Theme', '<%prefix%>Themes'); UPDATE StatItem SET ValueSQL = REPLACE(ValueSQL, '<%prefix%>UserSession', '<%prefix%>UserSessions'); UPDATE SystemSettings SET ValueList = REPLACE(ValueList, 'CustomField', 'CustomFields'); UPDATE SystemSettings SET ValueList = REPLACE(ValueList, 'PortalGroup', 'UserGroups'); UPDATE Counters SET CountQuery = 'SELECT COUNT(*) FROM <%PREFIX%>Users WHERE Status = 1', TablesAffected = '|Users|' WHERE `Name` = 'members_count'; UPDATE Counters SET CountQuery = REPLACE(CountQuery, '<%PREFIX%>UserSession', '<%PREFIX%>UserSessions'), TablesAffected = REPLACE(TablesAffected, '|UserSession|', '|UserSessions|'); RENAME TABLE <%TABLE_PREFIX%>CustomField TO <%TABLE_PREFIX%>CustomFields; RENAME TABLE <%TABLE_PREFIX%>Drafts TO <%TABLE_PREFIX%>FormSubmissionReplyDrafts; RENAME TABLE <%TABLE_PREFIX%>Events TO <%TABLE_PREFIX%>EmailEvents; DELETE FROM PersistantSessionData WHERE VariableName LIKE '%custom_filter%'; RENAME TABLE <%TABLE_PREFIX%>Favorites TO <%TABLE_PREFIX%>UserFavorites; RENAME TABLE <%TABLE_PREFIX%>Images TO <%TABLE_PREFIX%>CatalogImages; RENAME TABLE <%TABLE_PREFIX%>ItemFiles TO <%TABLE_PREFIX%>CatalogFiles; RENAME TABLE <%TABLE_PREFIX%>ItemRating TO <%TABLE_PREFIX%>CatalogRatings; RENAME TABLE <%TABLE_PREFIX%>ItemReview TO <%TABLE_PREFIX%>CatalogReviews; RENAME TABLE <%TABLE_PREFIX%>Language TO <%TABLE_PREFIX%>Languages; RENAME TABLE <%TABLE_PREFIX%>PermCache TO <%TABLE_PREFIX%>CategoryPermissionsCache; RENAME TABLE <%TABLE_PREFIX%>PermissionConfig TO <%TABLE_PREFIX%>CategoryPermissionsConfig; RENAME TABLE <%TABLE_PREFIX%>Phrase TO <%TABLE_PREFIX%>LanguageLabels; RENAME TABLE <%TABLE_PREFIX%>PortalGroup TO <%TABLE_PREFIX%>UserGroups; RENAME TABLE <%TABLE_PREFIX%>PersistantSessionData TO <%TABLE_PREFIX%>UserPersistentSessionData; RENAME TABLE <%TABLE_PREFIX%>PortalUser TO <%TABLE_PREFIX%>Users; RENAME TABLE <%TABLE_PREFIX%>PortalUserCustomData TO <%TABLE_PREFIX%>UserCustomData; RENAME TABLE <%TABLE_PREFIX%>RelatedSearches TO <%TABLE_PREFIX%>CategoryRelatedSearches; RENAME TABLE <%TABLE_PREFIX%>Relationship TO <%TABLE_PREFIX%>CatalogRelationships; RENAME TABLE <%TABLE_PREFIX%>SearchLog TO <%TABLE_PREFIX%>SearchLogs; RENAME TABLE <%TABLE_PREFIX%>Skins TO <%TABLE_PREFIX%>AdminSkins; RENAME TABLE <%TABLE_PREFIX%>SubmissionLog TO <%TABLE_PREFIX%>FormSubmissionReplies; RENAME TABLE <%TABLE_PREFIX%>Theme TO <%TABLE_PREFIX%>Themes; RENAME TABLE <%TABLE_PREFIX%>UserGroup TO <%TABLE_PREFIX%>UserGroupRelations; RENAME TABLE <%TABLE_PREFIX%>Visits TO <%TABLE_PREFIX%>UserVisits; RENAME TABLE <%TABLE_PREFIX%>SessionLogs TO <%TABLE_PREFIX%>UserSessionLogs; DELETE FROM LanguageLabels WHERE PhraseKey = 'LA_FLD_RUNMODE'; ALTER TABLE ScheduledTasks DROP RunMode; INSERT INTO SystemSettings VALUES(DEFAULT, 'CKFinderLicenseName', '', 'In-Portal', 'in-portal:configure_advanced', 'la_section_Settings3rdPartyAPI', 'la_config_CKFinderLicenseName', 'text', NULL, NULL, 80.03, 0, 0, NULL); INSERT INTO SystemSettings VALUES(DEFAULT, 'CKFinderLicenseKey', '', 'In-Portal', 'in-portal:configure_advanced', 'la_section_Settings3rdPartyAPI', 'la_config_CKFinderLicenseKey', 'text', NULL, NULL, 80.04, 0, 0, NULL); INSERT INTO SystemSettings VALUES(DEFAULT, 'EnablePageContentRevisionControl', '0', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsAdmin', 'la_config_EnablePageContentRevisionControl', 'checkbox', '', '', 40.19, 0, 0, NULL); # ===== v 5.2.0-B2 ===== ALTER TABLE Users CHANGE Username Username varchar(255) NOT NULL DEFAULT '', CHANGE IPAddress IPAddress varchar(15) NOT NULL DEFAULT '', CHANGE PwResetConfirm PwResetConfirm varchar(255) NOT NULL DEFAULT ''; ALTER TABLE UserSessions CHANGE TimeZone TimeZone varchar(255) NOT NULL DEFAULT ''; ALTER TABLE CountryStates CHANGE l1_Name l1_Name varchar(255) NOT NULL DEFAULT '', CHANGE l2_Name l2_Name varchar(255) NOT NULL DEFAULT '', CHANGE l3_Name l3_Name varchar(255) NOT NULL DEFAULT '', CHANGE l4_Name l4_Name varchar(255) NOT NULL DEFAULT '', CHANGE l5_Name l5_Name varchar(255) NOT NULL DEFAULT ''; ALTER TABLE Categories CHANGE DirectLinkAuthKey DirectLinkAuthKey varchar(20) NOT NULL DEFAULT ''; ALTER TABLE ScheduledTasks CHANGE SiteDomainLimitation SiteDomainLimitation varchar(255) NOT NULL DEFAULT ''; ALTER TABLE ItemFilters CHANGE ItemPrefix ItemPrefix varchar(255) NOT NULL DEFAULT '', CHANGE FilterField FilterField varchar(255) NOT NULL DEFAULT '', CHANGE FilterType FilterType varchar(100) NOT NULL DEFAULT ''; ALTER TABLE SpamReports CHANGE ItemPrefix ItemPrefix varchar(255) NOT NULL DEFAULT ''; ALTER TABLE CachedUrls CHANGE ParsedVars ParsedVars text; ALTER TABLE CurlLog CHANGE Message Message varchar(255) NOT NULL DEFAULT '', CHANGE PageUrl PageUrl varchar(255) NOT NULL DEFAULT '', CHANGE RequestUrl RequestUrl varchar(255) NOT NULL DEFAULT '', CHANGE CurlError CurlError varchar(255) NOT NULL DEFAULT ''; UPDATE SystemSettings SET DisplayOrder = DisplayOrder + 0.01 WHERE ModuleOwner = 'In-Portal' AND Section = 'in-portal:configure_advanced' AND Heading = 'la_section_SettingsAdmin' AND DisplayOrder > 40.11; INSERT INTO SystemSettings VALUES(DEFAULT, 'DefaultGridPerPage', '20', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsAdmin', 'la_config_DefaultGridPerPage', 'select', '', '10=+10||20=+20||50=+50||100=+100||500=+500', 40.12, 0, 0, NULL); ALTER TABLE EmailEvents ADD LastChanged INT UNSIGNED NULL; ALTER TABLE PromoBlocks DROP Html, CHANGE Status Status TINYINT(1) NOT NULL DEFAULT '1', CHANGE CategoryId CategoryId INT(11) NULL; # ===== v 5.2.0-B3 ===== ALTER TABLE Languages ADD HtmlEmailTemplate TEXT NULL, ADD TextEmailTemplate TEXT NULL; ALTER TABLE EmailLog CHANGE fromuser `From` VARCHAR(255) NOT NULL DEFAULT ''; ALTER TABLE EmailLog CHANGE addressto `To` VARCHAR(255) NOT NULL DEFAULT ''; ALTER TABLE EmailLog CHANGE subject `Subject` VARCHAR(255) NOT NULL DEFAULT ''; ALTER TABLE EmailLog CHANGE `timestamp` SentOn INT(11) NULL; ALTER TABLE EmailLog CHANGE `event` EventName VARCHAR(255) NOT NULL DEFAULT ''; ALTER TABLE EmailLog ADD OtherRecipients TEXT NULL AFTER `To`; ALTER TABLE EmailLog ADD HtmlBody LONGTEXT NULL AFTER `Subject`, ADD TextBody LONGTEXT NULL AFTER HtmlBody; ALTER TABLE EmailLog ADD AccessKey VARCHAR(32) NOT NULL DEFAULT ''; INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:emaillog.edit', 11, 1, 1, 0); DELETE FROM LanguageLabels WHERE PhraseKey = 'LA_PROMPT_FROMUSERNAME'; INSERT INTO SystemSettings VALUES(DEFAULT, 'EmailLogRotationInterval', '-1', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsMailling', 'la_config_EmailLogRotationInterval', 'select', NULL, '=la_opt_EmailLogKeepNever||86400=la_opt_OneDay||604800=la_opt_OneWeek||1209600=la_opt_TwoWeeks||2419200=la_opt_OneMonth||7257600=la_opt_ThreeMonths||29030400=la_opt_OneYear||-1=la_opt_EmailLogKeepForever', 50.11, 0, 0, 'hint:la_config_EmailLogRotationInterval'); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:spam_reports.view', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:spam_reports.edit', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:spam_reports.delete', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:item_filters.view', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:item_filters.add', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:item_filters.edit', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:item_filters.delete', 11, 1, 1, 0); ALTER TABLE SlowSqlCapture CHANGE QueryCrc QueryCrc BIGINT(11) NOT NULL DEFAULT '0'; UPDATE SlowSqlCapture SET QueryCrc = CAST((QueryCrc & 0xFFFFFFFF) AS UNSIGNED INTEGER) WHERE QueryCrc < 0; ALTER TABLE ImportCache CHANGE VarName VarName BIGINT(11) NOT NULL DEFAULT '0'; UPDATE ImportCache SET VarName = CAST((VarName & 0xFFFFFFFF) AS UNSIGNED INTEGER) WHERE VarName < 0; ALTER TABLE PageContent CHANGE ContentNum ContentNum BIGINT(11) NOT NULL DEFAULT '0'; UPDATE PageContent SET ContentNum = CAST((ContentNum & 0xFFFFFFFF) AS UNSIGNED INTEGER) WHERE ContentNum < 0; ALTER TABLE CachedUrls CHANGE Hash Hash BIGINT(11) NOT NULL DEFAULT '0'; UPDATE CachedUrls SET Hash = CAST((Hash & 0xFFFFFFFF) AS UNSIGNED INTEGER) WHERE Hash < 0; ALTER TABLE EmailEvents ADD BindToSystemEvent VARCHAR(255) NOT NULL DEFAULT ''; CREATE TABLE SystemEventSubscriptions ( SubscriptionId int(11) NOT NULL AUTO_INCREMENT, EmailEventId int(11) DEFAULT NULL, SubscriberEmail varchar(255) NOT NULL DEFAULT '', UserId int(11) DEFAULT NULL, CategoryId int(11) DEFAULT NULL, IncludeSublevels tinyint(4) NOT NULL DEFAULT '1', ItemId int(11) DEFAULT NULL, ParentItemId int(11) DEFAULT NULL, SubscribedOn int(11) DEFAULT NULL, PRIMARY KEY (SubscriptionId), KEY EmailEventId (EmailEventId) ); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:system_event_subscriptions.view', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:system_event_subscriptions.add', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:system_event_subscriptions.edit', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:system_event_subscriptions.delete', 11, 1, 1, 0); UPDATE LanguageLabels SET l1_ColumnTranslation = l1_Translation, l2_ColumnTranslation = l2_Translation, l3_ColumnTranslation = l3_Translation, l4_ColumnTranslation = l4_Translation, l5_ColumnTranslation = l5_Translation WHERE PhraseKey IN ('LA_FLD_BINDTOSYSTEMEVENT', 'LA_FLD_CATEGORYID'); UPDATE Categories SET l1_MenuTitle = l1_Name WHERE l1_Name = 'Content'; UPDATE SystemSettings SET ValueList = '0=la_opt_QueryString||1=la_opt_Cookies||2=la_opt_AutoDetect' WHERE VariableName = 'CookieSessions'; # ===== v 5.2.0-RC1 ===== UPDATE LanguageLabels SET l<%PRIMARY_LANGUAGE%>_Translation = '<TITLE> Tag' WHERE PhraseKey = 'LA_FLD_PAGECONTENTTITLE'; ALTER TABLE EmailLog ADD EventType TINYINT(4) NULL AFTER EventName; DELETE FROM UserPersistentSessionData WHERE VariableName IN ('email-log[Default]columns_.', 'promo-block[Default]columns_.'); ALTER TABLE Categories ADD NamedParentPathHash INT UNSIGNED NOT NULL DEFAULT '0' AFTER NamedParentPath, ADD CachedTemplateHash INT UNSIGNED NOT NULL DEFAULT '0' AFTER CachedTemplate, ADD INDEX (NamedParentPathHash), ADD INDEX (CachedTemplateHash); # ===== v 5.2.0 ===== INSERT INTO SystemSettings VALUES(DEFAULT, 'CategoryPermissionRebuildMode', '3', 'In-Portal', 'in-portal:configure_categories', 'la_title_General', 'la_config_CategoryPermissionRebuildMode', 'select', NULL, '1=la_opt_Manual||2=la_opt_Silent||3=la_opt_Automatic', 10.11, 0, 0, 'hint:la_config_CategoryPermissionRebuildMode'); DELETE FROM LanguageLabels WHERE PhraseKey = 'LA_CONFIG_QUICKCATEGORYPERMISSIONREBUILD'; ALTER TABLE ScheduledTasks ADD RunSchedule VARCHAR(255) NOT NULL DEFAULT '* * * * *' AFTER Event; DELETE FROM UserPersistentSessionData WHERE VariableName = 'scheduled-task[Default]columns_.'; DELETE FROM LanguageLabels WHERE PhraseKey = 'LA_FLD_RUNINTERVAL'; ALTER TABLE Languages ADD ShortDateFormat VARCHAR(255) NOT NULL DEFAULT 'm/d' AFTER DateFormat, ADD ShortTimeFormat VARCHAR(255) NOT NULL DEFAULT 'g:i A' AFTER TimeFormat; UPDATE Languages SET ShortDateFormat = REPLACE(REPLACE(DateFormat, '/Y', ''), '/y', ''), ShortTimeFormat = REPLACE(TimeFormat, ':s', ''); UPDATE SystemSettings SET GroupDisplayOrder = 1 WHERE VariableName = 'AdminConsoleInterface'; UPDATE SystemSettings SET Section = 'in-portal:configure_general', Prompt = 'la_config_AdminConsoleInterface', DisplayOrder = 50.01, GroupDisplayOrder = 2 WHERE VariableName = 'AllowAdminConsoleInterfaceChange'; DELETE FROM LanguageLabels WHERE PhraseKey = 'LA_CONFIG_ALLOWADMINCONSOLEINTERFACECHANGE'; UPDATE SystemSettings SET DisplayOrder = DisplayOrder - 0.01 WHERE ModuleOwner = 'In-Portal' AND Section = 'in-portal:configure_advanced' AND DisplayOrder > 40.02 AND DisplayOrder < 50; UPDATE SystemSettings SET VariableValue = 1 WHERE VariableName = 'UseOutputCompression'; ALTER TABLE EmailQueue CHANGE LogData LogData LONGTEXT NULL DEFAULT NULL; DELETE FROM UserPersistentSessionData WHERE VariableName = 'mailing-list[Default]columns_.'; INSERT INTO Permissions VALUES(DEFAULT, 'in-portal:configure_general.add', 11, 1, 1, 0); INSERT INTO Permissions VALUES(DEFAULT, 'in-portal:configure_advanced.add', 11, 1, 1, 0); INSERT INTO Permissions VALUES(DEFAULT, 'in-portal:configure_categories.add', 11, 1, 1, 0); INSERT INTO Permissions VALUES(DEFAULT, 'in-portal:configure_users.add', 11, 1, 1, 0); # ===== v 5.2.1-B1 ===== UPDATE SystemSettings SET DisplayOrder = 30.05 WHERE VariableName = 'Force_HTTP_When_SSL_Not_Required'; INSERT INTO EmailEvents (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, Module, Description, Type, AllowChangingSender, AllowChangingRecipient) VALUES(DEFAULT, 'USER.NEW.PASSWORD', NULL, 1, 0, 'Core', 'Sends new password to an existing user', 0, 1, 0); INSERT INTO EmailEvents (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, Module, Description, Type, AllowChangingSender, AllowChangingRecipient) VALUES(DEFAULT, 'USER.ADD.BYADMIN', NULL, 1, 0, 'Core', 'Sends password to a new user', 0, 1, 0); CREATE TABLE SystemLog ( LogId int(11) NOT NULL AUTO_INCREMENT, LogUniqueId int(11) DEFAULT NULL, LogLevel tinyint(4) NOT NULL DEFAULT '7', LogType tinyint(4) NOT NULL DEFAULT '3', LogCode int(11) DEFAULT NULL, LogMessage longtext, LogTimestamp int(11) DEFAULT NULL, LogDate datetime DEFAULT NULL, LogEventName varchar(100) NOT NULL DEFAULT '', LogHostname varchar(255) NOT NULL DEFAULT '', LogRequestSource tinyint(4) DEFAULT NULL, LogRequestURI varchar(255) NOT NULL DEFAULT '', LogRequestData longtext, LogUserId int(11) DEFAULT NULL, LogInterface tinyint(4) DEFAULT NULL, IpAddress varchar(15) NOT NULL DEFAULT '', LogSessionKey int(11) DEFAULT NULL, LogSessionData longtext, LogBacktrace longtext, LogSourceFilename varchar(255) NOT NULL DEFAULT '', LogSourceFileLine int(11) DEFAULT NULL, LogProcessId bigint(20) unsigned DEFAULT NULL, LogMemoryUsed bigint(20) unsigned NOT NULL, LogUserData longtext NOT NULL, LogNotificationStatus tinyint(4) NOT NULL DEFAULT '0', PRIMARY KEY (LogId), KEY LogLevel (LogLevel), KEY LogType (LogType), KEY LogNotificationStatus (LogNotificationStatus) ); INSERT INTO SystemSettings VALUES(DEFAULT, 'EnableEmailLog', '1', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_EnableEmailLog', 'radio', NULL, '1=la_Yes||0=la_No', 65.01, 0, 1, 'hint:la_config_EnableEmailLog'); UPDATE SystemSettings SET DisplayOrder = 65.02, Heading = 'la_section_SettingsLogs', ValueList = '86400=la_opt_OneDay||604800=la_opt_OneWeek||1209600=la_opt_TwoWeeks||2419200=la_opt_OneMonth||7257600=la_opt_ThreeMonths||29030400=la_opt_OneYear||-1=la_opt_EmailLogKeepForever' WHERE VariableName = 'EmailLogRotationInterval'; UPDATE LanguageLabels SET l<%PRIMARY_LANGUAGE%>_Translation = 'Keep "E-mail Log" for', l<%PRIMARY_LANGUAGE%>_HintTranslation = 'This setting allows you to control for how long "E-mail Log" messages will be stored in the log and then automatically deleted. Use option "Forever" with caution since it will completely disable automatic log cleanup and can lead to large size of database table that stores e-mail messages.' WHERE PhraseKey = 'LA_CONFIG_EMAILLOGROTATIONINTERVAL' AND l<%PRIMARY_LANGUAGE%>_Translation = 'Keep Email Log for'; DELETE FROM LanguageLabels WHERE PhraseKey = 'LA_OPT_EMAILLOGKEEPNEVER'; INSERT INTO SystemSettings VALUES(DEFAULT, 'SystemLogRotationInterval', '2419200', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_SystemLogRotationInterval', 'select', NULL, '86400=la_opt_OneDay||604800=la_opt_OneWeek||1209600=la_opt_TwoWeeks||2419200=la_opt_OneMonth||7257600=la_opt_ThreeMonths||29030400=la_opt_OneYear||-1=la_opt_SystemLogKeepForever', 65.03, 0, 1, 'hint:la_config_SystemLogRotationInterval'); INSERT INTO SystemSettings VALUES(DEFAULT, 'SystemLogNotificationEmail', '', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_SystemLogNotificationEmail', 'text', 'a:5:{s:4:"type";s:6:"string";s:9:"formatter";s:10:"kFormatter";s:6:"regexp";s:85:"/^([-a-zA-Z0-9!\\#$%&*+\\/=?^_`{|}~.]+@[a-zA-Z0-9]{1}[-.a-zA-Z0-9_]*\\.[a-zA-Z]{2,6})$/i";s:10:"error_msgs";a:1:{s:14:"invalid_format";s:18:"!la_invalid_email!";}s:7:"default";s:0:"";}', NULL, 65.04, 0, 1, 'hint:la_config_SystemLogNotificationEmail'); INSERT INTO EmailEvents (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, Module, Description, Type, AllowChangingSender, AllowChangingRecipient) VALUES(DEFAULT, 'SYSTEM.LOG.NOTIFY', NULL, 1, 0, 'Core', 'Notification about message added to System Log', 1, 1, 1); ALTER TABLE Users ADD PasswordHashingMethod TINYINT NOT NULL DEFAULT '3' AFTER Password; UPDATE Users SET PasswordHashingMethod = 1; INSERT INTO SystemSettings VALUES(DEFAULT, 'TypeKitId', '', 'In-Portal', 'in-portal:configure_advanced', 'la_section_Settings3rdPartyAPI', 'la_config_TypeKitId', 'text', NULL, NULL, 80.05, 0, 1, NULL); ALTER TABLE MailingLists CHANGE EmailsQueued EmailsQueuedTotal INT(10) UNSIGNED NOT NULL DEFAULT '0'; RENAME TABLE <%TABLE_PREFIX%>EmailEvents TO <%TABLE_PREFIX%>EmailTemplates; ALTER TABLE EmailTemplates CHANGE `Event` TemplateName VARCHAR(40) NOT NULL DEFAULT ''; ALTER TABLE EmailTemplates CHANGE EventId TemplateId INT(11) NOT NULL AUTO_INCREMENT; ALTER TABLE SystemEventSubscriptions CHANGE EmailEventId EmailTemplateId INT(11) NULL DEFAULT NULL; DELETE FROM LanguageLabels WHERE PhraseKey IN ( 'LA_FLD_EXPORTEMAILEVENTS', 'LA_FLD_EVENT', 'LA_TITLE_EMAILMESSAGES', 'LA_TAB_E-MAILS', 'LA_COL_EMAILEVENTS', 'LA_OPT_EMAILEVENTS', 'LA_FLD_EMAILEVENT', 'LA_TITLE_EMAILEVENTS', 'LA_TITLE_ADDING_E-MAIL', 'LA_TITLE_EDITING_E-MAIL', 'LA_TITLE_EDITINGEMAILEVENT', 'LA_TITLE_NEWEMAILEVENT', 'LA_TAB_EMAILEVENTS' ); DELETE FROM UserPersistentSessionData WHERE VariableName IN ('system-event-subscription[Default]columns_.', 'email-log[Default]columns_.'); ALTER TABLE EmailLog CHANGE EventName TemplateName VARCHAR(255) NOT NULL DEFAULT ''; # ===== v 5.2.1-B2 ===== DELETE FROM LanguageLabels WHERE PhraseKey = 'LA_TAB_REPORTS'; ALTER TABLE Modules ADD ClassNamespace VARCHAR(255) NOT NULL DEFAULT '' AFTER Path; UPDATE Modules SET ClassNamespace = 'Intechnic\\InPortal\\Core' WHERE `Name` IN ('Core', 'In-Portal'); UPDATE SystemSettings SET DisplayOrder = DisplayOrder + 0.01 WHERE ModuleOwner = 'In-Portal' AND Section = 'in-portal:configure_categories' AND DisplayOrder > 10.10 AND DisplayOrder < 20; INSERT INTO SystemSettings VALUES(DEFAULT, 'CheckViewPermissionsInCatalog', '1', 'In-Portal', 'in-portal:configure_categories', 'la_title_General', 'la_config_CheckViewPermissionsInCatalog', 'radio', NULL, '1=la_Yes||0=la_No', 10.11, 0, 1, 'hint:la_config_CheckViewPermissionsInCatalog'); # ===== v 5.2.1-RC1 ===== UPDATE LanguageLabels SET l1_Translation = REPLACE(l1_Translation, '
', '\n') WHERE PhraseKey = 'LA_EDITINGINPROGRESS'; UPDATE LanguageLabels SET l1_ColumnTranslation = 'Helpful' WHERE PhraseKey = 'LA_FLD_HELPFULCOUNT'; UPDATE LanguageLabels SET l1_ColumnTranslation = 'Not Helpful' WHERE PhraseKey = 'LA_FLD_NOTHELPFULCOUNT'; UPDATE LanguageLabels SET Module = 'Core' WHERE PhraseKey = 'LA_SECTION_FILE'; # ===== v 5.2.1 ===== +# ===== v 5.2.2-B1 ===== +UPDATE LanguageLabels +SET l1_Translation = 'Incorrect data format, please use {type}' +WHERE PhraseKey = 'LA_ERR_BAD_TYPE'; + +UPDATE LanguageLabels +SET l1_Translation = 'Field value is out of range, possible values from {min_value} to {max_value}' +WHERE PhraseKey = 'LA_ERR_VALUE_OUT_OF_RANGE'; + +UPDATE LanguageLabels +SET l1_Translation = 'Field value length is out of range, possible value length from {min_length} to {max_length}' +WHERE PhraseKey = 'LA_ERR_LENGTH_OUT_OF_RANGE'; + +ALTER TABLE Themes ADD StylesheetFile VARCHAR( 255 ) NOT NULL DEFAULT ''; +UPDATE Themes SET StylesheetFile = 'platform/inc/styles.css' WHERE `Name` = 'advanced'; + # ===== v 5.3.0-B1 ===== ALTER TABLE ScheduledTasks ADD Settings TEXT NULL; ALTER TABLE Themes ADD ImageResizeRules TEXT NULL; DELETE FROM UserPersistentSessionData WHERE VariableName = 'emailevents[Emails]columns_.'; INSERT INTO <%TABLE_PREFIX%>SystemCache (VarName, Data) SELECT 'tmp_translation' AS VarName, l<%PRIMARY_LANGUAGE%>_Translation AS Data FROM <%TABLE_PREFIX%>LanguageLabels WHERE PhraseKey = 'LC_IMPORTLANG_PHRASEWARNING'; UPDATE <%TABLE_PREFIX%>LanguageLabels SET Phrase = 'la_fld_ImportOverwrite', PhraseKey = 'LA_FLD_IMPORTOVERWRITE', l<%PRIMARY_LANGUAGE%>_HintTranslation = (SELECT Data FROM <%TABLE_PREFIX%>SystemCache WHERE VarName = 'tmp_translation' LIMIT 1) WHERE PhraseKey = 'LA_PROMPT_OVERWRITEPHRASES'; DELETE FROM LanguageLabels WHERE PhraseKey = 'LC_IMPORTLANG_PHRASEWARNING'; DELETE FROM LanguageLabels WHERE PhraseKey = 'LA_CONFIG_USETEMPLATECOMPRESSION'; DELETE FROM SystemSettings WHERE VariableName = 'UseTemplateCompression'; UPDATE SystemSettings SET DisplayOrder = ROUND(DisplayOrder - 0.01, 2) WHERE (DisplayOrder BETWEEN 60.04 AND 60.10) AND (ModuleOwner = 'In-Portal') AND (Section = 'in-portal:configure_advanced'); INSERT INTO SystemSettings VALUES(DEFAULT, 'RandomString', '', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsSystem', 'la_config_RandomString', 'text', '', '', 60.09, 0, 1, NULL); INSERT INTO SystemSettings VALUES(DEFAULT, 'PlainTextCookies', '', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsSystem', 'la_config_PlainTextCookies', 'text', '', '', 60.10, 0, 1, NULL); INSERT INTO SystemSettings VALUES(DEFAULT, 'ForceCanonicalUrls', '0', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsWebsite', 'la_config_ForceCanonicalUrls', 'checkbox', '', '', 10.0125, 0, 0, NULL); UPDATE LanguageLabels SET l1_HintTranslation = '
    \r\n
  • This deploy script will apply all Database Changes stored in [module]/project_upgrades.sql to the current website and save applied Revisions in AppliedDBRevisions.
  • \r\n
  • This deploy script will create all new language phrases by re-importing [module]/install/english.lang file.
  • \r\n
  • This deploy script will reset all caches at once.
  • \r\n
' WHERE Phrase = 'la_title_SystemToolsDeploy'; INSERT INTO SystemSettings VALUES(DEFAULT, 'EmailDelivery', '2', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsMailling', 'la_config_EmailDelivery', 'radio', NULL, '1=la_opt_EmailDeliveryQueue||2=la_opt_EmailDeliveryImmediate', 50.11, 0, 1, NULL); DELETE FROM UserPersistentSessionData WHERE VariableName = 'email-queue[Default]columns_.'; ALTER TABLE EmailLog ADD ToUserId INT(11) DEFAULT NULL, ADD ItemPrefix VARCHAR(50) NOT NULL DEFAULT '', ADD ItemId INT(11) DEFAULT NULL; DELETE FROM UserPersistentSessionData WHERE VariableName = 'email-log[Default]columns_.'; ALTER TABLE EmailLog ADD Status TINYINT NOT NULL DEFAULT '1' AFTER TextBody, ADD ErrorMessage VARCHAR(255) NOT NULL DEFAULT '' AFTER Status; ALTER TABLE ScheduledTasks ADD Module varchar(30) NOT NULL DEFAULT 'Core'; CREATE TABLE ModuleDeploymentLog ( Id int(11) NOT NULL AUTO_INCREMENT, Module varchar(30) NOT NULL DEFAULT 'In-Portal', RevisionNumber int(11) NOT NULL DEFAULT '0', RevisionTitle varchar(255) NOT NULL DEFAULT '', CreatedOn int(10) unsigned DEFAULT NULL, IPAddress varchar(15) NOT NULL DEFAULT '', Output text, ErrorMessage varchar(255) NOT NULL DEFAULT '', Mode tinyint(1) NOT NULL DEFAULT '1', Status tinyint(1) NOT NULL DEFAULT '1', PRIMARY KEY (Id), KEY CreatedOn (CreatedOn), KEY Mode (Mode), KEY Status (Status) ); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:module_deployment_log.view', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:module_deployment_log.edit', 11, 1, 1, 0); INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:module_deployment_log.delete', 11, 1, 1, 0); UPDATE EmailTemplates SET l<%PRIMARY_LANGUAGE%>_Subject = REPLACE(l<%PRIMARY_LANGUAGE%>_Subject, '', ''), l<%PRIMARY_LANGUAGE%>_PlainTextBody = REPLACE(l<%PRIMARY_LANGUAGE%>_PlainTextBody, '', ''), l<%PRIMARY_LANGUAGE%>_HtmlBody = REPLACE(l<%PRIMARY_LANGUAGE%>_HtmlBody, '', '') WHERE TemplateName IN ('USER.SUBSCRIBE', 'USER.UNSUBSCRIBE'); ALTER TABLE CategoryItems ADD Id int(11) NOT NULL auto_increment FIRST, ADD PRIMARY KEY (Id); ALTER TABLE UserGroupRelations DROP PRIMARY KEY; ALTER TABLE UserGroupRelations ADD Id int(11) NOT NULL auto_increment FIRST, ADD PRIMARY KEY (Id), ADD UNIQUE KEY UserGroup (PortalUserId, GroupId); DELETE FROM UserPersistentSessionData WHERE VariableName IN ('u-ug[Default]columns_.', 'g-ug[Default]columns_.'); ALTER TABLE SpamControl ADD Id int(11) NOT NULL auto_increment FIRST, ADD PRIMARY KEY (Id); INSERT INTO SystemSettings VALUES(DEFAULT, 'SSLDomain', '', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsSSL', 'la_config_SSLDomain', 'text', '', '', 30.01, 0, 1, NULL); INSERT INTO SystemSettings VALUES(DEFAULT, 'AdminSSLDomain', '', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsSSL', 'la_config_AdminSSLDomain', 'text', '', '', 30.02, 0, 0, NULL); DELETE FROM LanguageLabels WHERE PhraseKey IN ('LA_CONFIG_SSL_URL', 'LA_CONFIG_ADMINSSL_URL', 'LA_FLD_SSLURL'); ALTER TABLE SiteDomains CHANGE SSLUrl SSLDomainName VARCHAR(255) NOT NULL DEFAULT '', CHANGE SSLUrlUsesRegExp SSLDomainNameUsesRegExp TINYINT(4) NOT NULL DEFAULT '0'; -DELETE FROM UserPersistentSessionData WHERE VariableName = 'site-domain[Default]columns_.'; +DELETE FROM UserPersistentSessionData WHERE VariableName = 'site-domain[Default]columns_.'; \ No newline at end of file Index: branches/5.3.x/core/install/english.lang =================================================================== --- branches/5.3.x/core/install/english.lang (revision 16123) +++ branches/5.3.x/core/install/english.lang (revision 16124) @@ -1,2245 +1,2247 @@ JGJvZHkNCjxici8+PGJyLz4NCg0KU2luY2VyZWx5LDxici8+PGJyLz4NCg0KV2Vic2l0ZSBhZG1pbmlzdHJhdGlvbi4NCg0KPCEtLSMjIDxpbnAyOmVtYWlsLWxvZ19JdGVtTGluayB0ZW1wbGF0ZT0icGxhdGZvcm0vbXlfYWNjb3VudC9lbWFpbCIvPiAjIy0tPg== QWN0aXZl QWRk QWRkIFRv QWRtaW5pc3RyYXRpdmUgQ29uc29sZQ== YWxsb3cgY2hhbmdpbmc= QWxsb3cgZGVsZXRpbmcgTW9kdWxlIFJvb3QgU2VjdGlvbg== VmlldyBpbiBCcm93c2UgTW9kZQ== R28gSW5zaWRl QWx3YXlz YW5k QXV0bw== QXV0b21hdGlj QXZhaWxhYmxlIENvbHVtbnM= QXZhaWxhYmxlIEl0ZW1z QmFja2dyb3VuZA== Qm9yZGVycw== QWRk RWRpdCBJdGVt QnJvd3NlIE1vZGU= Q2FuY2Vs Q2hhbmdl Q2xlYXI= Q29udGVudCBNb2Rl RGVsZXRl RGVsZXRl ZGVsZXRlIHJldmlldw== RGVwbG95 RGVzaWduIE1vZGU= RG93bg== RWRpdA== RWRpdCBCbG9jaw== RWRpdCBDb250ZW50 RWRpdCBEZXNpZ24= R2VuZXJhdGU= R2VuZXJhdGUgUGFnZQ== R2V0IFZhbHVl TG9jYXRl TW92ZSBEb3du TW92ZSBVcA== UHVibGlzaGluZyBUb29scw== UmVidWlsZA== UmVjb21waWxl UmVmcmVzaA== UmVzZXQ= UmVzZXQgJmFtcDsgVmFsaWRhdGUgQ29uZmlnIEZpbGVz UmVzZXQgInJvb3QiIHBhc3N3b3Jk U2F2ZQ== U2F2ZSBDaGFuZ2Vz U2VjdGlvbiBQcm9wZXJ0aWVz U2VjdGlvbiBUZW1wbGF0ZQ== U2VsZWN0IEFsbA== U2V0IFZhbHVl U2hvdyBTdHJ1Y3R1cmU= U3luY2hyb25pemU= VW5zZWxlY3Q= VXA= VXNl Ynk= Q2FuY2Vs U2VjdGlvbg== TnVtYmVyIG9mIGRheXMgZm9yIGEgY2F0LiB0byBiZSBORVc= RGVmYXVsdCBNRVRBIGRlc2NyaXB0aW9u RGVmYXVsdCBNRVRBIEtleXdvcmRz TnVtYmVyIG9mIHNlY3Rpb25zIHBlciBwYWdl U2VjdGlvbnMgUGVyIFBhZ2UgKFNob3J0bGlzdCk= RGlzcGxheSBlZGl0b3IgUElDS3MgYWJvdmUgcmVndWxhciBzZWN0aW9ucw== QW5kIHRoZW4gYnk= T3JkZXIgc2VjdGlvbnMgYnk= Q2xvc2U= QWNjZXNz QWRkaXRpb25hbA== QWZmZWN0ZWQgSXRlbXM= QWx0IFZhbHVl QnVpbGQgRGF0ZQ== U2VjdGlvbiBOYW1l Q29sdW1uIFBocmFzZQ== RWZmZWN0aXZl RS1tYWlsIFRlbXBsYXRlcw== RW5hYmxlIEUtbWFpbCBDb21tdW5pY2F0aW9u Jm5ic3A7 RXZlbnQgRGVzY3JpcHRpb24= RXZlbnQgUGFyYW1z SGludCBQaHJhc2U= U3RhdHVz SW1hZ2U= VVJM SW5oZXJpdGVk SW5oZXJpdGVkIEZyb20= SW4gTWVudQ== SVAgQWRkcmVzcw== UG9wdWxhcg== VXNlciBQcmltYXJ5 S2V5d29yZA== TGFiZWw= TGFuZ3VhZ2UgUGFjayBJbnN0YWxsZWQ= TGFzdCBDaGFuZ2Vk TGFzdCBDb21waWxlZA== TGFzdCBBdHRlbXB0 TGluayBVUkw= TWFpbGluZyBMaXN0 TWVtYmVyc2hpcCBFeHBpcmVz TWVzc2FnZSBIZWFkZXJz SFRNTA== T3JpZ2luYWwgVmFsdWU= UGF0aA== QWRk RGVsZXRl RWRpdA== UGVybWlzc2lvbiBOYW1l QWNjZXNz Vmlldw== UGhyYXNlcw== VXNlciBJRA== UHJldmlldw== UHJpbWFyeSBHcm91cA== UHJpbWFyeSBWYWx1ZQ== RmllbGQgUHJvbXB0 UXVldWVk UmVmZXJlcg== UmVzZXQgdG8gZGVmYXVsdA== Q29tbWVudHM= Q3JlYXRlZCBieQ== U2NoZWR1bGUgRnJvbSBEYXRl U2NoZWR1bGUgVG8gRGF0ZQ== QXR0ZW1wdHMg U2Vzc2lvbiBFbmQ= U2Vzc2lvbiBTdGFydA== U29ydCBieQ== VHlwZQ== U3lzdGVtIFBhdGg= SXRlbSBUeXBl VXNlcnM= TGFzdG5hbWUgRmlyc3RuYW1l RmllbGQgVmFsdWU= VmlzaWJsZQ== VmlzaXQgRGF0ZQ== QXNjZW5kaW5n RGVzY2VuZGluZw== QWRtaW4gQ29uc29sZSBJbnRlcmZhY2U= U1NMIERvbWFpbiBmb3IgQWRtaW5pc3RyYXRpdmUgQ29uc29sZSAod3d3LmRvbWFpbi5jb20p QWxsb3cgdG8gc2VsZWN0IG1lbWJlcnNoaXAgZ3JvdXAgb24gRnJvbnQtZW5k TGlzdCBhdXRvbWF0aWMgcmVmcmVzaCBpbnRlcnZhbHMgKGluIG1pbnV0ZXMp QmFja3VwIFBhdGg= U3dpdGNoIENhdGFsb2cgdGFicyBiYXNlZCBvbiBNb2R1bGU= U2VjdGlvbiBQZXJtaXNzaW9uIFJlYnVpbGQgTW9kZQ== Q2hlY2sgU3RvcCBXb3Jkcw== RW5hYmxlICJWaWV3IFBlcm1pc3Npb25zIiBDaGVjayBpbiBDYXRhbG9n Q0tGaW5kZXIgTGljZW5zZSBLZXk= Q0tGaW5kZXIgTGljZW5zZSBOYW1l RGVmYXVsdCBDU1YgRXhwb3J0IERlbGltaXRlcg== RGVmYXVsdCBDU1YgRXhwb3J0IEVuY2xvc3VyZSBDaGFyYWN0ZXI= RGVmYXVsdCBDU1YgRXhwb3J0IEVuY29kaW5n RGVmYXVsdCBDU1YgRXhwb3J0IE5ldyBMaW5lIFNlcGFyYXRvcg== U2hvdyAiRm9ybXMgRWRpdG9yIiBpbiBERUJVRyBtb2RlIG9ubHk= U2hvdyAiUHJvbW8gQmxvY2sgR3JvdXBzIEVkaXRvciIgaW4gREVCVUcgbW9kZSBvbmx5 RGVmYXVsdCBEZXNpZ24gVGVtcGxhdGU= RGVmYXVsdCBFLW1haWwgUmVjaXBpZW50cw== RGVmYXVsdCAiUGVyIFBhZ2UiIHNldHRpbmcgaW4gR3JpZHM= RGVmYXVsdCBSZWdpc3RyYXRpb24gQ291bnRyeQ== RGVmYXVsdCBBbmFseXRpY3MgVHJhY2tpbmcgQ29kZQ== RW1haWwgRGVsaXZlcnk= S2VlcCAiRS1tYWlsIExvZyIgZm9y RW5hYmxlICJFLW1haWwgTG9nIg== RW5hYmxlIFJldmlzaW9uIENvbnRyb2wgZm9yIFNlY3Rpb24gQ29udGVudA== VGVtcGxhdGUgZm9yICJGaWxlIG5vdCBmb3VuZCAoNDA0KSIgRXJyb3I= RXhjbHVkZSB0ZW1wbGF0ZSBiYXNlZCBTZWN0aW9ucyBmcm9tIFNlYXJjaCBSZXN1bHRzIChpZS4gVXNlciBSZWdpc3RyYXRpb24p RmlsZW5hbWUgU3BlY2lhbCBDaGFyIFJlcGxhY2VtZW50 Rmlyc3QgRGF5IE9mIFdlZWs= Rm9yY2UgQ2Fub25pY2FsIFVSTHM= QWx3YXlzIHVzZSBJbWFnZU1hZ2ljayB0byByZXNpemUgaW1hZ2Vz Rm9yY2UgUmVkaXJlY3QgdG8gU2VsZWN0ZWQgVVJMIEVuZGluZw== UmVkaXJlY3QgdG8gSFRUUCB3aGVuIFNTTCBpcyBub3QgcmVxdWlyZWQ= RnVsbCBpbWFnZSBIZWlnaHQ= RnVsbCBpbWFnZSBXaWR0aA== VGVtcGxhdGUgZm9yIEhhcmQgTWFpbnRlbmFuY2U= QnlwYXNzIEhUVFAgQXV0aGVudGljYXRpb24gZnJvbSBJUHMgKHNlcGFyYXRlZCBieSBzZW1pY29sb25zKQ== UGFzc3dvcmQgZm9yIEhUVFAgQXV0aGVudGljYXRpb24= VXNlcm5hbWUgZm9yIEhUVFAgQXV0aGVudGljYXRpb24= S2VlcCBTZXNzaW9uIGFsaXZlIG9uIEJyb3dzZXIgY2xvc2U= TWFpbCBGdW5jdGlvbiBIZWFkZXIgU2VwYXJhdG9y TWFpbGluZyBMaXN0IFF1ZXVlIFBlciBTdGVw TWFpbGluZyBMaXN0IFNlbmQgUGVyIFN0ZXA= TWFpbnRlbmFuY2UgTWVzc2FnZSBmb3IgQWRtaW4= TWFpbnRlbmFuY2UgTWVzc2FnZSBmb3IgRnJvbnQgRW5k TWF4aW11bSBudW1iZXIgb2YgaW1hZ2Vz RGVmYXVsdCBVUkwgRW5kaW5nIGluIFNFTy1mcmllbmRseSBtb2Rl VGVtcGxhdGUgZm9yICJJbnN1ZmZpY2llbnQgUGVybWlzc2lvbnMiIEVycm9y R1pJUCBjb21wcmVzc2lvbiBsZXZlbCAwLTk= UGF0aCB0byBXZWJzaXRl UGVyZm9ybSBFeGFjdCBTZWFyY2g= Q29tbWVudHMgcGVyIHBhZ2U= UGxhaW4gVGV4dCBDb29raWVz UmFuZG9tIFN0cmluZw== IlJlY3ljbGUgQmluIiBTZWN0aW9uSWQ= VXNlcm5hbWUgUmVxdWlyZWQgRHVyaW5nIFJlZ2lzdHJhdGlvbg== UmVzdG9yZSBsYXN0IHZpc2l0ZWQgQWRtaW4gU2VjdGlvbiBhZnRlciBMb2dpbg== UmVxdWlyZSBTU0wgZm9yIEFkbWluaXN0cmF0aXZlIENvbnNvbGU= UmVxdWlyZSBTU0wgZm9yIGxvZ2luICYgY2hlY2tvdXQ= RnJhbWVzIGluIGFkbWluaXN0cmF0aXZlIGNvbnNvbGUgYXJlIHJlc2l6YWJsZQ== TWluaW1hbCBTZWFyY2ggS2V5d29yZCBMZW5ndGg= U2Vzc2lvbiBTZWN1cml0eSBDaGVjayBiYXNlZCBvbiBCcm93c2VyIFNpZ25hdHVyZQ== U2Vzc2lvbiBDb29raWUgRG9tYWlucyAoc2luZ2xlIGRvbWFpbiBwZXIgbGluZSk= U2Vzc2lvbiBTZWN1cml0eSBDaGVjayBiYXNlZCBvbiBJUA== V2Vic2l0ZSBTdWJ0aXRsZQ== VGltZSB6b25lIG9mIHRoZSBzaXRl VGVtcGxhdGUgZm9yIFNvZnQgTWFpbnRlbmFuY2U= U1NMIERvbWFpbiAod3d3LmRvbWFpbi5jb20p VXNlIFN0aWNreSBHcmlkIFNlbGVjdGlvbg== U2VuZCBVc2VyLWRlZmluZWQgIlN5c3RlbSBMb2ciIG1lc3NhZ2VzIHRv S2VlcCAiU3lzdGVtIExvZyIgZm9y VGh1bWJuYWlsIEhlaWdodA== VGh1bWJuYWlsIFdpZHRo VHJpbSBSZXF1aXJlZCBGaWVsZHM= VHlwZUtpdCBJRA== VXBkYXRlIGNvdW50ZXJzIChpbiBvdGhlciBmaWx0ZXJzKSBvbiBmaWx0ZXIgY2hhbmdl VHJhY2sgZGF0YWJhc2UgY2hhbmdlcyB0byBjaGFuZ2UgbG9n VXNlIENvbHVtbiBGcmVlemVy QXV0by1kZXRlY3QgVXNlcidzIGxhbmd1YWdlIGJhc2VkIG9uIGl0J3MgQnJvd3NlciBzZXR0aW5ncw== VXNlIERvdWJsZSBTb3J0aW5n RW5hYmxlIEhUVFAgQXV0aGVudGljYXRpb24= RW5hYmxlIEhUTUwgR1pJUCBjb21wcmVzc2lvbg== VXNlIFBhZ2VIaXQgY291bnRlcg== RWRpdGluZyBXaW5kb3cgU3R5bGU= RW1haWwgYWN0aXZhdGlvbiBleHBpcmF0aW9uIHRpbWVvdXQgKGluIG1pbnV0ZXMp VXNlIFNtYWxsIFNlY3Rpb24gSGVhZGVycw== VXNlIFRvb2xiYXIgTGFiZWxz VXNlIFZpc2l0b3IgVHJhY2tpbmc= VXNlIEphdmFTY3JpcHQgcmVkaXJlY3Rpb24gYWZ0ZXIgbG9naW4vbG9nb3V0IChmb3IgSUlTKQ== RW5hYmxlIFNFTy1mcmllbmRseSBVUkxzIG1vZGUgKE1PRC1SRVdSSVRFKQ== RW5hYmxlIE1PRF9SRVdSSVRFIGZvciBTU0w= V2Vic2l0ZSBuYW1l WWFob28gQXBwbGljYXRpb25JZA== QXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGRlbGV0ZSBzZWxlY3RlZCBFeHBvcnQgUHJlc2V0Pw== VGhlIHNlY3Rpb24gdHJlZSBtdXN0IGJlIHVwZGF0ZWQgdG8gcmVmbGVjdCB0aGUgbGF0ZXN0IGNoYW5nZXM= Q3VycmVudCBUaGVtZQ== RGF0YSBHcmlkcw== RGF0YSBHcmlkcyAy ZGF5cw== QXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGRlbGV0ZSB0aGUgaXRlbShzKT8gVGhpcyBhY3Rpb24gY2Fubm90IGJlIHVuZG9uZS4= VGhpcyBzZWN0aW9uIGFsbG93cyB5b3UgdG8gbWFuYWdlIHNlY3Rpb25zIGFuZCBpdGVtcyBhY3Jvc3MgYWxsIHNlY3Rpb25z VGhpcyBzZWN0aW9uIGFsbG93cyB5b3UgdG8gYnJvd3NlIHRoZSBjYXRhbG9nIGFuZCBtYW5hZ2Ugc2VjdGlvbnMgYW5kIGl0ZW1z TWFuYWdlIHRoZSBzdHJ1Y3R1cmUgb2YgeW91ciBzaXRlLCBpbmNsdWRpbmcgc2VjdGlvbnMsIGl0ZW1zIGFuZCBzZWN0aW9uIHNldHRpbmdzLg== RGlzYWJsZWQ= RG91YmxlLVF1b3Rlcw== RG93bmxvYWQgQ1NW RG93bmxvYWQgRXhwb3J0IEZpbGU= RG93bmxvYWQgTGFuZ3VhZ2UgRXhwb3J0 RHJhZnQ= RHJhZnQgQXZhaWxhYmxl ZHJhZnQgc2F2ZWQgYXQgJXM= Q29udGVudCBFZGl0b3I= WW91IGhhdmUgbm90IHNhdmVkIGNoYW5nZXMgdG8gdGhlIGl0ZW0geW91IGFyZSBlZGl0aW5nITxiciAvPkNsaWNrIE9LIHRvIGxvb3NlIGNoYW5nZXMgYW5kIGdvIHRvIHRoZSBzZWxlY3RlZCBzZWN0aW9uPGJyIC8+b3IgQ2FuY2VsIHRvIHN0YXkgaW4gdGhlIGN1cnJlbnQgc2VjdGlvbi4= RGVmYXVsdCB0ZXh0 RmlsZSBpcyBlbXB0eQ== RmlsZSBpcyBlbXB0eQ== RW5hYmxlZA== Q2FuJ3QgZGVsZXRlIHN5c3RlbSBwZXJtaXNzaW9u Q2FuJ3Qgb3BlbiB0aGUgZmlsZQ== Q2FuJ3Qgc2F2ZSBhIGZpbGU= Q29ubmVjdGlvbiBGYWlsZWQ= RXJyb3IgY29weWluZyBzdWJzZWN0aW9ucw== Q3VzdG9tIGZpZWxkIHdpdGggaWRlbnRpY2FsIG5hbWUgYWxyZWFkeSBleGlzdHM= RW1haWwgRGVzaWduIFRlbXBsYXRlIHNob3VsZCBjb250YWluIGF0IGxlYXN0ICIkYm9keSIgdGFnIGluIGl0Lg== + RmlsZSBub3QgZm91bmQ= RmlsZSBpcyB0b28gbGFyZ2U= Z3JvdXAgbm90IGZvdW5k RmllbGQgZG9lc24ndCBleGlzdCBpbiAiJXMiIHVuaXQgY29uZmln SW52YWxpZCBGaWxlIEZvcm1hdA== VW5pdCBjb25maWcgcHJlZml4IG5vdCBmb3VuZA== aW52YWxpZCBvcHRpb24= TG9naW4gRmFpbGVk UmVjZWl2aW5nIGxpc3Qgb2YgbWVzc2FnZXMgZnJvbSB0aGUgU2VydmVyIGhhcyBmYWlsZWQ= RXJyb3IgbW92aW5nIHN1YnNlY3Rpb24= Q2FuJ3QgaW5oZXJpdCB0ZW1wbGF0ZSBmcm9tIHRvcCBjYXRlZ29yeQ== Tm8gbWF0Y2hpbmcgY29sdW1ucyBhcmUgZm91bmQ= VGhpcyBvcGVyYXRpb24gaXMgbm90IGFsbG93ZWQh VmFsaWRhdGlvbiBlcnJvciwgcGxlYXNlIGRvdWJsZS1jaGVjayBJbi1Qb3J0YWwgdGFncw== UGFzc3dvcmRzIGRvIG5vdCBtYXRjaCE= Q2FuJ3QgRGVsZXRlIE5vbi1FbXB0eSBQcm9tbyBCbG9jayBHcm91cA== UmVxdWlyZWQgZmllbGQoLXMpIG5vdCBmaWxsZWQ= cmVxdWlyZWQgY29sdW1ucyBtaXNzaW5n Um9vdCBzZWN0aW9uIG9mIHRoZSBtb2R1bGUocykgY2FuIG5vdCBiZSBkZWxldGVkIQ== U2VsZWN0IGF0IGxlYXN0IG9uZSBpdGVtIHRvIG1vdmU= VGVtcGxhdGUgZmlsZSBpcyBtaXNzaW5n Q29weWluZyBvcGVyYXRpb24gaW4gVGVtcG9yYXJ5IHRhYmxlcyBoYXMgZmFpbGVkLiBQbGVhc2UgY29udGFjdCB3ZWJzaXRlIGFkbWluaXN0cmF0b3Iu UmVjb3JkIGlzIG5vdCB1bmlxdWU= U2VjdGlvbiBmaWVsZCBub3QgdW5pcXVl VW5rbm93biBzZWN0aW9u VW5rbm93biBzZWN0aW9u VXNlciBCYW5uZWQ= dXNlciBub3QgZm91bmQ= WW91IG11c3Qgc2VsZWN0IG9ubHkgb25lIHVzZXI= SW5jb3JyZWN0IGRhdGUgZm9ybWF0LCBwbGVhc2UgdXNlICglcykgZXguICglcyk= - SW5jb3JyZWN0IGRhdGEgZm9ybWF0LCBwbGVhc2UgdXNlICVz + SW5jb3JyZWN0IGRhdGEgZm9ybWF0LCBwbGVhc2UgdXNlIHt0eXBlfQ== SW52YWxpZCBGb3JtYXQ= - RmllbGQgdmFsdWUgbGVuZ3RoIGlzIG91dCBvZiByYW5nZSwgcG9zc2libGUgdmFsdWUgbGVuZ3RoIGZyb20gJXMgdG8gJXM= + RmllbGQgdmFsdWUgbGVuZ3RoIGlzIG91dCBvZiByYW5nZSwgcG9zc2libGUgdmFsdWUgbGVuZ3RoIGZyb20ge21pbl9sZW5ndGh9IHRvIHttYXhfbGVuZ3RofQ== UHJpbWFyeSBMYW5nLiB2YWx1ZSBSZXF1aXJlZA== RmllbGQgaXMgcmVxdWlyZWQ= RmllbGQgdmFsdWUgbXVzdCBiZSB1bmlxdWU= - RmllbGQgdmFsdWUgaXMgb3V0IG9mIHJhbmdlLCBwb3NzaWJsZSB2YWx1ZXMgZnJvbSAlcyB0byAlcw== + RmllbGQgdmFsdWUgaXMgb3V0IG9mIHJhbmdlLCBwb3NzaWJsZSB2YWx1ZXMgZnJvbSB7bWluX3ZhbHVlfSB0byB7bWF4X3ZhbHVlfQ== RXhwb3J0IGZvbGRlciBpcyBub3Qgd3JpdGFibGU= RXJyb3IgY3JlYXRpbmcgZm9sZGVyLiBFcnJvciBudW1iZXI6 UGxlYXNlIG5hbWUgeW91ciBmaWxlcyB0byBiZSB3ZWItZnJpZW5kbHkuIFdlIHJlY29tbWVuZCB1c2luZyBvbmx5IHRoZXNlIGNoYXJhY3RlcnMgaW4gZmlsZSBuYW1lczogDQpMZXR0ZXJzIGEteiwgQS1aLCBOdW1iZXJzIDAtOSwgIl8iICh1bmRlcnNjb3JlKSwgIi0iIChkYXNoKSwgIiAiIChzcGFjZSksICIuIiAocGVyaW9kKQ0KUGxlYXNlIGF2b2lkIHVzaW5nIGFueSBvdGhlciBjaGFyYWN0ZXJzIGxpa2UgcXVvdGVzLCBicmFja2V0cywgcXVvdGF0aW9uIG1hcmtzLCAiPyIsICIhIiwgIj0iLCBmb3JlaWduIHN5bWJvbHMsIGV0Yy4= RXJyb3Igb24gZmlsZSB1cGxvYWQuIEVycm9yIG51bWJlcjo= QSBmaWxlIHdpdGggdGhlIHNhbWUgbmFtZSBpcyBhbHJlYWR5IGF2YWlsYWJsZQ== RGF0ZQ== RmlsZSBOYW1l U2l6ZQ== Rm9sZGVyIGFscmVhZHkgZXhpc3Rz SW52YWxpZCBmaWxlIHR5cGUgZm9yIHRoaXMgZm9kZXI= SW52YWxpZCBmb2xkZXIgbmFtZQ== WW91IGhhdmUgbm8gcGVybWlzc2lvbnMgdG8gY3JlYXRlIHRoZSBmb2xkZXI= UGxlYXNlIHR5cGUgdGhlIGZvbGRlciBuYW1l VHlwZSB0aGUgbmFtZSBvZiB0aGUgbmV3IGZvbGRlcjo= VW5rbm93biBlcnJvciBjcmVhdGluZyBmb2xkZXI= RmllbGQ= RGlzcGxheSBPcmRlcg== T3JkZXI= QWN0aW9u QWRkcmVzcyBMaW5lIDE= QWRkcmVzcyBMaW5lIDI= TWVzc2FnZXMgZnJvbSBTaXRlIEFkbWluIGFyZSBmcm9t QWRtaW4gUHJpbWFyeQ== TGFuZ3VhZ2U= QWR2YW5jZWQgQ1NT QWR2YW5jZWQgU2VhcmNo QWxsb3cgQ2hhbmdpbmcgIlRvIiBSZWNpcGllbnQ= QWxsb3cgQ2hhbmdpbmcgU2VuZGVy QWx0IFZhbHVl QW5zd2Vy QXNzaWduZWQgdG8gU2VjdGlvbnM= QXR0YWNobWVudA== QXV0byBDcmVhdGUgRmlsZSBOYW1l QXV0b21hdGljIEZpbGVuYW1l QXZhaWxhYmxlIENvbHVtbnM= QmFja2dyb3VuZA== QmFja2dyb3VuZCBBdHRhY2htZW50 QmFja2dyb3VuZCBDb2xvcg== QmFja2dyb3VuZCBJbWFnZQ== QmFja2dyb3VuZCBQb3NpdGlvbg== QmFja2dyb3VuZCBSZXBlYXQ= QmNj QmluZCB0byBTeXN0ZW0gRXZlbnQ= RWxlbWVudCBQb3NpdGlvbg== Qm9yZGVyIEJvdHRvbQ== Qm9yZGVyIExlZnQ= Qm9yZGVyIFJpZ2h0 Qm9yZGVycw== Qm9yZGVyIFRvcA== Qm91bmNlIERhdGU= Qm91bmNlIEVtYWls Qm91bmNlIEluZm8= QnV0dG9uIFRleHQ= U2VjdGlvbg== U2VjdGlvbiBGb3JtYXQ= U2VjdGlvbiBJRA== U2VjdGlvbiBzZXBhcmF0b3I= U2VjdGlvbiBUZW1wbGF0ZQ== Q2M= Q2hhbmdlcw== Q2hhcnNldA== Q2hlY2sgRHVwbGljYXRlcyBieQ== Q2l0eQ== Q29sdW1uIFBocmFzZQ== Q29tbWVudHM= Q29tcGFueQ== Q29uZmlndXJhdGlvbiBIZWFkZXIgTGFiZWw= Q29udGVudCBCbG9jaw== Q1RSLCAl Q29weSBMYWJlbHMgZnJvbSB0aGlzIExhbmd1YWdl Q291bnRyeQ== Q3JlYXRlZCBCeQ== Q3JlYXRlZCBPbg== Q29tbW9uIFNldHRpbmdz RGF5 SG91cg== TWludXRl TW9udGg= V2Vla2RheQ== Q1NTIFRlbXBsYXRl Q1NTIENsYXNzIE5hbWU= Q3Vyc29y Q3VzdG9tIERldGFpbHMgVGVtcGxhdGU= U2VuZCBFbWFpbCBUbw== U2VuZCBFbWFpbCBGcm9t DQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KRGV0YWlscyBUZW1wbGF0ZQ== RGF0ZSBGb3JtYXQ= RGVjaW1hbCBQb2ludA== RGVzY3JpcHRpb24= QWNjZXNzIHdpdGggTGluaw== RGlzcGxheQ== RGlzcGxheSBpbiBHcmlk RmllbGQgTGFiZWw= RGlzcGxheSBzaXRlIG5hbWUgaW4gSGVhZGVy RGlzcGxheSBUbyBQdWJsaWM= UmFuZ2Ugb2YgSVBz RG9tYWluIE5hbWU= QXMgUGxhaW4gVGV4dA== RHVyYXRpb24= RWRpdG9ycyBQaWNr RWxhcHNlZCBUaW1l RS1tYWls RS1tYWlsIENvbW11bmljYXRpb24gUm9sZQ== RS1tYWlsIG9yIFVzZXJuYW1l RS1tYWlsICI8c3Ryb25nPntwYXNzd29yZH08L3N0cm9uZz4iIHBhc3N3b3JkIHRvIHVzZXI= RW1haWxzIGluIFF1ZXVl RW1haWxzIFNlbnQ= RW1haWxzIFRvdGFs RS1tYWlsIFRlbXBsYXRlIE5hbWU= RW1haWwgVmVyaWZpZWQ= RW5hYmxl RW5hYmxlZA== RW5hYmxlIENhY2hpbmcgZm9yIHRoaXMgU2VjdGlvbg== RXJyb3IgTWVzc2FnZQ== RXJyb3IgVGFn RXN0aW1hdGVkIFRpbWU= RXZlbnQ= RXhwaXJl RXhwb3J0IGNvbHVtbnM= RXhwb3J0IFNwZWNpZmllZCBDb3VudHJpZXM= RGF0YSBUeXBlcyB0byBFeHBvcnQ= RXhwb3J0IFNwZWNpZmllZCBFLW1haWwgVGVtcGxhdGVz RXhwb3J0IEZpbGVuYW1l RXhwb3J0IGZvcm1hdA== RXhwb3J0IE1vZHVsZXM= RXhwb3J0IFNwZWNpZmllZCBQaHJhc2Vz RXhwb3J0IFBocmFzZSBUeXBlcw== RXhwb3J0IFByZXNldCBUaXRsZQ== RXhwb3J0IFByZXNldA== U2F2ZS9VcGRhdGUgRXhwb3J0IFByZXNldA== RXh0ZXJuYWwgTGluaw== RXh0ZXJuYWwgVVJM RXh0cmEgSGVhZGVycw== RmF4 TWF0Y2ggVHlwZQ== RmllbGQgTmFtZQ== RmllbGRzIGVuY2xvc2VkIGJ5 RmllbGRzIHNlcGFyYXRlZCBieQ== RmllbGQgVGl0bGVz RmllbGQgVHlwZQ== TWF0Y2ggVmFsdWU= RmlsZSBDb250ZW50cw== RmlsZW5hbWU= RmlsZW5hbWUgUmVwbGFjZW1lbnRz UGF0aA== RmlsdGVyIEZpZWxk RmlsdGVyIFR5cGU= Rmlyc3QgTmFtZQ== Rm9udA== Rm9udCBDb2xvcg== Rm9udCBGYW1pbHk= Rm9udCBTaXpl Rm9udCBTdHlsZQ== Rm9udCBXZWlnaHQ= T25saW5lIEZvcm0= T25saW5lIEZvcm0gU3VibWl0dGVkIFRlbXBsYXRl U2hvcnQgVVJM RnJvbSBFbWFpbA== RnJvbnQtRW5kIE9ubHk= TGFuZ3VhZ2U= QWxsb3cgUmVnaXN0cmF0aW9uIG9uIEZyb250LWVuZA== RnVsbCBOYW1l VXNlciBHcm91cA== R3JvdXAgRGlzcGxheSBPcmRlcg== SUQ= R3JvdXAgTmFtZQ== SGVpZ2h0 UmV2aWV3IFdhcyBIZWxwZnVs SGludCBQaHJhc2U= SGl0cw== SG90 SFRNTCBWZXJzaW9u SFRNTCBWZXJzaW9u SWNvbiBVUkwgKGRpc2FibGVkKQ== SWNvbiBVUkw= SUQ= SW1hZ2U= SW1wb3J0IFNlY3Rpb24= SW1wb3J0IENvbHVtbnM= SW1wb3J0IEZpbGU= SW1wb3J0IEZpbGVuYW1l T3ZlcndyaXRlIEV4aXN0aW5nIFBocmFzZXM= SW1wb3J0IE5ldyBQaHJhc2VzIGFzIFN5bmNlZA== SW5jbHVkZSBmaWVsZCB0aXRsZXM= SW5jbHVkZSBTdWJsZXZlbHM= SW5wdXQgRGF0ZSBGb3JtYXQ= SW5wdXQgVGltZSBGb3JtYXQ= SW5zdGFsbCBNb2R1bGVz SW5zdGFsbCBQaHJhc2UgVHlwZXM= SVAgQWRkcmVzcw== SVAgUmVzdHJpY3Rpb25z VXNlIGN1cnJlbnQgc2VjdGlvbiBhcyByb290IGZvciB0aGUgZXhwb3J0 SVNPIENvZGU= UHJpbWFyeQ== UmVxdWlyZWQ= SXMgU3lzdGVt U3lzdGVtIFRlbXBsYXRl VXNlciBGaWVsZA== SXRlbSBJRA== SXRlbSBOYW1l SXRlbSBQcmVmaXg= SXRlbSBUZW1wbGF0ZQ== TGFuZ3VhZ2U= TGFuZ3VhZ2UgRmlsZQ== TGFuZ3VhZ2UgSUQ= TGFuZ3VhZ2Vz TGFzdCBOYW1l TGFzdCBSdW4gT24= TGFzdCBSdW4gU3RhdHVz TGFzdCBUaW1lb3V0IE9u TGFzdCBVcGRhdGVkIE9u TGVmdA== TGluZSBlbmRpbmdz TGluZSBFbmRpbmdzIEluc2lkZSBGaWVsZHM= TGluayBUeXBl SUQ= TGlzdGluZyBUeXBl TG9jYWxl TG9jYWwgTmFtZQ== TG9jYXRpb24= QmFja3RyYWNl Q29kZQ== RXZlbnQgTmFtZQ== SG9zdG5hbWU= TG9naW4= SW50ZXJmYWNl TG9nIExldmVs TWVtb3J5IFVzZWQ= TWVzc2FnZQ== Tm90aWZpY2F0aW9uIFN0YXR1cw== TG9nbyBpbWFnZQ== Qm90dG9tIExvZ28gSW1hZ2U= TG9nbyBMb2dpbg== UHJvY2VzcyBJRA== UmVxdWVzdCBEYXRh UmVxdWVzdCBTb3VyY2U= UmVxdWVzdCBVUkk= U2Vzc2lvbiBEYXRh U2Vzc2lvbiBLZXk= U291cmNlIEZpbGUgTGluZQ== U291cmNlIEZpbGVuYW1l VGltZXN0YW1w VHlwZQ== VXNlciBEYXRh TWFyZ2luIEJvdHRvbQ== TWFyZ2luIExlZnQ= TWFyZ2luIFJpZ2h0 TWFyZ2lucw== TWFyZ2luIFRvcA== TWFzdGVyIElE TWFzdGVyIFByZWZpeA== TWF4aW11bSBudW1iZXIgb2YgU2VjdGlvbnMgb24gSXRlbSBjYW4gYmUgYWRkZWQgdG8= Q3VzdG9tIE1lbnUgSWNvbiAoaWUuIGltZy9tZW51X3Byb2R1Y3RzLmdpZik= TWVudSBTdGF0dXM= TWVyZ2UgdG8gU3VibWlzc2lvbg== TWVzc2FnZQ== TWVzc2FnZSBCb2R5 UGxhaW4gVGV4dCBWZXJzaW9u TWVzc2FnZSBUeXBl TWV0YSBEZXNjcmlwdGlvbg== TWV0YSBLZXl3b3Jkcw== TWlzc3BlbGxlZCBXb3Jk TW9kZQ== TW9kaWZpZWQ= TW9kdWxl TW9kdWxl TXVsdGlsaW5ndWFs TmFtZQ== TmV3 TmV4dCBSdW4gT24= Tm90ZXM= UmV2aWV3IFdhc24ndCBIZWxwZnVs TnVtYmVyIE9mIENsaWNrcw== TnVtYmVyIE9mIFZpZXdz T2NjdXJlZCBPbg== T3BlbiBJbiBOZXcgV2luZG93 T3B0aW9ucw== T3B0aW9uIFRpdGxl T3JkZXI= T3RoZXIgUmVjaXBpZW50cw== T3V0cHV0 T3ZlcndyaXRlIERlZmF1bHQgQ2FjaGluZyBLZXk= UGFjayBOYW1l UGFkZGluZyBCb3R0b20= UGFkZGluZyBMZWZ0 UGFkZGluZyBSaWdodA== UGFkZGluZ3M= UGFkZGluZyBUb3A= Q3VzdG9tIENhY2hpbmcgS2V5 Jmx0O1RJVExFJmd0OyBUYWc= Q2FjaGUgRXhwaXJhdGlvbiBpbiBzZWNvbmRz VGl0bGUgKE1lbnUgSXRlbSk= U2VjdGlvbiBUaXRsZQ== UGFyZW50IEl0ZW0gSUQ= UGFyZW50IEl0ZW0gTmFtZQ== UGFyZW50IFNlY3Rpb24= UGFzc3dvcmQ= UGVyY2VudHMgQ29tcGxldGVk UGhvbmU= TGFiZWw= UGhyYXNlIFR5cGU= UG9w UG9wdWxhcg== UG9ydA== UG9zaXRpb24= UHJlZml4 UHJpbWFyeQ== UHJpbWFyeSBTZWN0aW9u UHJpbWFyeQ== UHJpbWFyeSBMYW5ndWFnZSBQaHJhc2U= T3JkZXI= Q29udmVydCB1bm1hdGNoZWQgZS1tYWlscyBpbnRvIG5ldyBzdWJtaXNzaW9ucw== UHJvbW8gQmxvY2sgR3JvdXA= UHJvdGVjdGVk UXVhbnRpdHk= UmFuZ2UgQ291bnQ= UmF0aW5n UmVjaXBpZW50 UmVjaXBpZW50J3MgQWRkcmVzcw== UmVjaXBpZW50J3MgQWRkcmVzcyBUeXBl UmVjaXBpZW50J3MgTmFtZQ== UmVjaXBpZW50cw== UmVjaXBpZW50IFR5cGU= UmVjaXBpZW50IFVzZXI= Rm9yY2UgUmVkaXJlY3QgKHdoZW4gdXNlcidzIElQIG1hdGNoZXMp UmVmZXJyZXIgVVJM S2V5d29yZA== VHlwZQ== UmVtb3RlIFVSTA== UmVwbGFjZSBEdXBsaWNhdGVz UmVwbGFjZW1lbnQ= UmVwbGFjZW1lbnQgVGFncw== UmVwbGllZCBPbg== UmVwbHkgQmNj UmVwbHkgQ2M= UmVwbHkgRnJvbSBFLW1haWw= UmVwbHkgRnJvbSBOYW1l UmVwbHkgTWVzc2FnZSBTaWduYXR1cmU= UmVwbGllZA== UmVwb3J0ZWQgQnk= UmVwb3J0ZWQgT24= UmVxdWlyZWQ= UmVxdWlyZSBMb2dpbg== UmVxdWlyZSBTU0w= Q29tbWVudA== UmV2aXNpb24gTnVtYmVy UmV2aXNpb24gVGl0bGU= UHJvbW8gUm90YXRpb24gRGVsYXkgKHNlY29uZHMp UnVsZSBUeXBl UnVuIFNjaGVkdWxl UnVuIFRpbWU= U2FtZSBBcyBUaHVtYg== U2NoZWR1bGUgRGF0ZQ== U2VhcmNoIFRlcm0= U2VuZGVy U2VuZGVyJ3MgQWRkcmVzcw== U2VuZGVyJ3MgTmFtZQ== U2VudCBPbg== U2VudA== U2VydmVy U2Vzc2lvbiBMb2cgSUQ= U2V0dGluZ3M= U2hvcnQgRGF0ZSBGb3JtYXQ= U2hvcnQgSVNPIENvZGU= U2hvcnQgVGltZSBGb3JtYXQ= U2ltcGxlIFNlYXJjaA== U2l0ZSBEb21haW4gTGltaXRhdGlvbg== TmFtZQ== U2tpcCBGaXJzdCBSb3c= U29ydCBWYWx1ZXM= U291cmNlIENvbHVtbiBQaHJhc2UgKGZyb20gJXMp U291cmNlIEhpbnQgUGhyYXNlIChmcm9tICVzKQ== U291cmNlIEhUTUwgVmVyc2lvbiAoZnJvbSAlcyk= U291cmNlIFRleHQgVmVyc2lvbiAoZnJvbSAlcyk= U291cmNlIFN1YmplY3QgKGZyb20gJXMp U291cmNlIFBocmFzZSAoZnJvbSAlcyk= U1NMIERvbWFpbiBOYW1l U3RhcnQgRGF0ZQ== U3RhdGU= U3RhdGUgQ291bnRyeQ== U3RhdHVz U3RpY2t5 U3RvcCBXb3Jk + U3R5bGVzaGVldCBGaWxl U3ViamVjdA== U3VibWl0dGVkIE9u U3VibWlzc2lvbiBOb3RpZmljYXRpb24gRW1haWw= U3Vic2NyaWJlZCBPbg== U3VnZ2VzdGVkIENvcnJlY3Rpb24= UG9pbnRzIHRvIFNlY3Rpb24= U3luY2hyb25pemUgTGFuZ3VhZ2U= U3lzdGVtIEV2ZW50 U2V0dGluZyBIaW50IExhYmVs U2V0dGluZyBOYW1l U2VjdGlvbg== VmFsaWRhdGlvbiBMb2dpYw== U2V0dGluZyBWYWx1ZQ== VGFibGUgTmFtZSBpbiBEYXRhYmFzZSA= VGFn SXRlbQ== VGVtcGxhdGUgRmlsZQ== VGVtcGxhdGUgTmFtZQ== VGVtcGxhdGU= VGV4dA== VGV4dCBBbGlnbg== VGV4dCBEZWNvcmF0aW9u VGV4dCBWZXJzaW9u VGV4dCBWZXJzaW9u VGhlbWU= VGhlbWVz VGhlc2F1cnVzIFRlcm0= VGhlc2F1cnVzIFR5cGU= VGhvdXNhbmRzIFNlcGFyYXRvcg== VGltZSBGb3JtYXQ= VGltZW91dA== VGltZSBab25l VGl0bGU= VG8= VG8gRS1tYWls VG9w QW5hbHl0aWNzIFRyYWNraW5nIENvZGU= UHJvbW8gVHJhbnNpdGlvbiBDb250cm9scw== UHJvbW8gVHJhbnNpdGlvbiBFZmZlY3Q= UHJvbW8gVHJhbnNpdGlvbiBFZmZlY3QgKGN1c3RvbSk= VHJhbnNpdGlvbiBEZWxheSAoc2Vjb25kcyk= VHJhbnNsYXRlIEZyb20gTGFuZ2F1Z2U= UGhyYXNl VHJhbnNsYXRpb24gaW4gU3luYw== VHlwZQ== TWVhc3VyZXMgU3lzdGVt VXBsb2FkIEZpbGUgRnJvbSBMb2NhbCBQQw== QWxsb3dlZCBGaWxlIEV4dGVuc2lvbnM= TWF4aW11bSBGaWxlIFNpemU= VVJM TGluayB0byBFeHRlcm5hbCBVUkw= VXNlIEN1c3RvbSBNZW51IEljb24= VXNlciBEb2N1bWVudGF0aW9uIFVSTA== VXNlciBHcm91cHM= VXNlcm5hbWU= VXNlIFNlY3VyaXR5IEltYWdl UmUtZW50ZXIgUGFzc3dvcmQ= VmVyc2lvbg== VmlzaWJpbGl0eQ== Vm90ZXM= V2lkdGg= Wi1JbmRleA== WklQ Rm9udCBQcm9wZXJ0aWVz RG8geW91IHdhbnQgdG8gc2F2ZSB0aGUgY2hhbmdlcz8= QXJlIHlvdSBzdXJlIHlvdSB3b3VsZCBsaWtlIHRvIGRpc2NhcmQgdGhlIGNoYW5nZXM/ RnJvbQ== RnJvbSBEYXRl R2VuZXJhbCBTZWN0aW9ucw== SGVhZCBGcmFtZQ== SGlkZQ== QWxsIEZpbGVz Q2xpY2sgdG8gZWRpdA== Q1NWIEZpbGVz SW1hZ2UgRmlsZXM= UE9QMyBTZXJ2ZXIgUG9ydC4gRm9yIGV4LiAiMTEwIiBmb3IgcmVndWxhciBjb25uZWN0aW9uLCAiOTk1IiBmb3Igc2VjdXJlIGNvbm5lY3Rpb24u UE9QMyBTZXJ2ZXIgQWRkcmVzcy4gRm9yIGV4LiB1c2UgInNzbDovL3BvcC5nbWFpbC5jb20iIGZvciBHbWFpbCwgInBvcC5tYWlsLnlhaG9vLmNvbSIgZm9yIFlhaG9vLg== Q2FjaGUgS2V5KHMp ZGF0YWJhc2UgY2FjaGU= bWVtb3J5IGNhY2hl VXNpbmcgUmVndWxhciBFeHByZXNzaW9u SG90 SFRNTA== SUQgRmllbGQ= SW52YWxpZCBFLU1haWw= SW5jb3JyZWN0IGRhdGEgZm9ybWF0LCBwbGVhc2UgdXNlIGludGVnZXI= TWlzc2luZyBvciBpbnZhbGlkIEluLVBvcnRhbCBMaWNlbnNl SW5jb3JyZWN0IFVzZXJuYW1lIG9yIFBhc3N3b3Jk SW52YWxpZCBzdGF0ZQ== U2VjdGlvbnM= PCAxIHNlYy4= RGlzcGxheSBlZGl0b3IgUElDS3MgYWJvdmUgcmVndWxhciBsaW5rcw== TnVtYmVyIG9mIGRheXMgZm9yIGEgbGluayB0byBiZSBORVc= TnVtYmVyIG9mIGxpbmtzIHBlciBwYWdl TnVtYmVyIG9mIGxpbmtzIHBlciBwYWdlIG9uIGEgc2hvcnQgbGlzdGluZw== QW5kIHRoZW4gYnk= T3JkZXIgbGlua3MgYnk= TGludXg= TG9jYWw= TG9jYWwgSW1hZ2U= RnVuY3Rpb24= TG9nZ2VkIGluIGFz TG9naW4= TG9nb3V0 KEdNVCk= KEdNVCAtMDE6MDAp KEdNVCAtMTA6MDAp KEdNVCAtMTE6MDAp KEdNVCAtMTI6MDAp KEdNVCAtMDI6MDAp KEdNVCAtMDM6MDAp KEdNVCAtMDQ6MDAp KEdNVCAtMDU6MDAp KEdNVCAtMDY6MDAp KEdNVCAtMDc6MDAp KEdNVCAtMDg6MDAp KEdNVCAtMDk6MDAp TWFyZ2lucw== R3JvdXAgTWVtYmVyc2hpcCBFeHBpcmF0aW9uIFJlbWluZGVyIChkYXlzKQ== TWV0cmlj U2VjdGlvbiBwYXRoIGluIG9uZSBmaWVsZA== TW9kdWxlIG5vdCBsaWNlbnNlZA== TW9uZGF5 Q2hhbmdlIGxvZyBpcyBjdXJyZW50bHkgZGlzYWJsZWQuIFR1cm4gb24gIiVzIiBzZXR0aW5nIHRvIGVuYWJsZSBpdC4= RW5hYmxlIHRyYWNraW5nIGRhdGFiYXNlIGNoYW5nZXMgdG8gY2hhbmdlIGxvZz8= TGFzdCBvcGVyYXRpb24gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGNvbXBsZXRlZCE= QXBwbHkgdG8gYWxsIFN1Yi1zZWN0aW9ucz8= WW91ciAicm9vdCIgcGFzc3dvcmQgaGFzIGJlZW4gcmVzZXQuIFBsZWFzZSByZW1vdmUgREJHX1JFU0VUX1JPT1QgY29uc3RhbnQgYW5kIGNoZWNrIHlvdXIgZS1tYWlsIGFkZHJlc3Mu WW91ciBjaGFuZ2VzIHdlcmUgc3VjY2Vzc2Z1bGx5IHNhdmVkIQ== TmV2ZXI= TmV2ZXIgRXhwaXJlcw== TmV3 TmV4dCBzZWN0aW9u Tm8= Tm9uZQ== Tm8gUGVybWlzc2lvbnM= bmQ= cmQ= c3Q= dGg= T2Zm T24= T25lIFdheQ== b24gbGluZQ== Y3JlYXRlZA== ZGVsZXRlZA== dXBkYXRlZA== QWN0aXZl QWRkcmVzcw== QWZ0ZXI= QWxsb3c= Q3VzdG9t RmFkZQ== U2xpZGU= QXByaWw= QXVndXN0 QXV0by1EZXRlY3Q= QXV0b21hdGlj QmVmb3Jl Qm91bmNlZA== Q2FuY2VsZWQ= Q2l0eQ== Q29sb24= Q29tbWE= Q29tbWVudCBUZXh0 Q29va2llcw== Q291bnRyaWVz Q291bnRyeQ== Q3JlYXRlZCBPbg== LS0gQ29tbW9uIFNldHRpbmdzIC0t LS0gRGF5cyAtLQ== RXZlcnkgZGF5 RXZlcnkgMTUgbWludXRlcw== RXZlcnkgNSBtaW51dGVz RXZlcnkgNCBob3Vycw== RXZlcnkgaG91cg== RXZlcnkgbWludXRl RXZlcnkgbW9udGg= RXZlcnkgb3RoZXIgZGF5 RXZlcnkgb3RoZXIgaG91cg== RXZlcnkgb3RoZXIgbWludXRl RXZlcnkgb3RoZXIgbW9udGg= RXZlcnkgNiBob3Vycw== RXZlcnkgNiBtb250aHM= RXZlcnkgMTAgbWludXRlcw== RXZlcnkgMzAgbWludXRlcw== RXZlcnkgMyBob3Vycw== RXZlcnkgMyBtb250aHM= RXZlcnkgMTIgaG91cnM= RXZlcnkgd2Vla2RheQ== LS0gSG91cnMgLS0= LS0gTWludXRlcyAtLQ== TW9uIHRocnUgRnJp TW9uLCBXZWQsIEZyaQ== LS0gTW9udGhzIC0t T25jZSBhIGRheQ== T25jZSBhIG1vbnRo T25jZSBhbiBob3Vy T25jZSBhIHdlZWs= T25jZSBhIHllYXI= U2F0IGFuZCBTdW4= VHVlcywgVGh1cnM= VHdpY2UgYSBkYXk= MXN0IGFuZCAxNXRo VHdpY2UgYW4gaG91cg== LS0gV2Vla2RheXMgLS0= Q3VycmVudCBEb21haW4= Q3VzdG9tICJUbyIgUmVjaXBpZW50KC1zKQ== Q3VzdG9tIFNlbmRlcg== ZGF5KHMp RGVjZW1iZXI= RGVjbGluZWQ= RGVmYXVsdCBXZWJzaXRlIGFkZHJlc3M= RGVueQ== RGVzY3JpcHRpb24= RGlzYWJsZWQ= RG9lc24ndCBtYXRjaA== RWRpdG9yJ3MgUGljaw== RS1tYWls RS1tYWlsIEJvZHk= SW1tZWRpYXRl RW1haWwgUXVldWU= Rm9yZXZlciAobmV2ZXIgZGVsZXRlZCBhdXRvbWF0aWNhbGx5KQ== RS1tYWlsIFN1YmplY3Q= RS1tYWlsIFRlbXBsYXRlcw== RXJyb3I= RXZlcnlvbmU= RXhhY3Q= RXhwaXJlZA== RXh0ZXJuYWw= RXh0ZXJuYWwgVXJs RmFpbGVk RmVicnVhcnk= Rmlyc3QgTmFtZQ== RnJpZGF5 R3JvdXA= R3Vlc3RzIE9ubHk= aG91cihzKQ== SW5oZXJpdCBmcm9tIFBhcmVudA== SW50ZXJuYWw= SW52YWxpZA== SVAgQWRkcmVzcw== SXMgdW5pcXVl SmFudWFyeQ== SnVseQ== SnVuZQ== TGFzdCBOYW1l TG9nZ2VkIE91dA== RGlzYWJsZWQ= UGVuZGluZw== U2VudA== RGF0YWJhc2U= T3RoZXI= UEhQ TWFudWFs TWFyY2g= TWF5 bWludXRlKHMp TW9kYWwgV2luZG93 TW9uZGF5 bW9udGgocyk= TmV3IEUtbWFpbA== Tm90IGVtcHR5 Tm90IGxpa2U= Tm90IFByb2Nlc3NlZA== Tm90IFJlcGxpZWQ= Tm92ZW1iZXI= T2N0b2Jlcg== MSBkYXk= MSBtb250aA== MSB3ZWVr MSB5ZWFy UGFydGlhbGx5IFByb2Nlc3NlZA== UGVuZGluZw== UGhvbmU= TGFiZWxz UG9wdXAgV2luZG93 UHJvY2Vzc2Vk UHVibGlzaGVk UXVlcnkgU3RyaW5nIChTSUQp UmF0aW5n UmVjaXBpZW50IEUtbWFpbA== UmVjaXBpZW50IE5hbWU= UmVwbGllZA== UnVubmluZw== U2FtZSBXaW5kb3c= U2F0dXJkYXk= c2Vjb25kKHMp U2VtaS1jb2xvbg== U2VudA== U2VwdGVtYmVy U2lsZW50 U2tpcHBlZA== U3BhY2U= U3RhdGU= U3ViLW1hdGNo U3VjY2Vzcw== U3VuZGF5 RnJvbSBvdGhlcnM= VG8gb3RoZXJz U3lzdGVt Rm9yZXZlciAobmV2ZXIgZGVsZXRlZCBhdXRvbWF0aWNhbGx5KQ== VGFi VGVtcGxhdGU= MyBtb250aHM= VGh1cnNkYXk= VGl0bGU= VHVlc2RheQ== MiB3ZWVrcw== VXNlcg== RW1haWwgQWN0aXZhdGlvbg== SW1tZWRpYXRlIA== VXNlcm5hbWU= Tm90IEFsbG93ZWQ= VXBvbiBBcHByb3ZhbA== VmlydHVhbA== V2VkbmVzZGF5 d2VlayhzKQ== eWVhcihzKQ== Wmlw T3RoZXIgRmllbGRz b3V0IG9m KEdNVCArMDE6MDAp KEdNVCArMTA6MDAp KEdNVCArMTE6MDAp KEdNVCArMTI6MDAp KEdNVCArMTM6MDAp KEdNVCArMDI6MDAp KEdNVCArMDM6MDAp KEdNVCArMDQ6MDAp KEdNVCArMDU6MDAp KEdNVCArMDY6MDAp KEdNVCArMDc6MDAp KEdNVCArMDg6MDAp KEdNVCArMDk6MDAp UGFkZGluZ3M= UGFnZQ== QXR0ZW50aW9uOiAlcyBpcyBjdXJyZW50bHkgZWRpdGluZyB0aGlzIHNlY3Rpb24h QXR0ZW50aW9uOiAlcyBhcmUgY3VycmVudGx5IGVkaXRpbmcgdGhpcyBzZWN0aW9uISA= QXR0ZW50aW9uOiAlcyBhcmUgY3VycmVudGx5IGVkaXRpbmcgdGhpcyBzZWN0aW9uIQ== UGFzc3dvcmRzIGRvIG5vdCBtYXRjaA== UGFzc3dvcmQgaXMgdG9vIHNob3J0LCBwbGVhc2UgZW50ZXIgYXQgbGVhc3QgJXMgY2hhcmFjdGVycw== UGVuZGluZw== UGVyZm9ybWluZyBCYWNrdXA= UGVyZm9ybWluZyBJbXBvcnQ= UGVyZm9ybWluZyBSZXN0b3Jl RXhwb3J0IExhbmd1YWdlIHBhY2s= SW1wb3J0IExhbmd1YWdlIHBhY2s= U2V0IFByaW1hcnkgTGFuZ3VhZ2U= RW5hYmxlIE1vZHVsZXM= RGlzYWJsZSBNb2R1bGVz TWFuYWdlIFBlcm1pc3Npb25z U2VuZCBFLW1haWwgdG8gR3JvdXBzIGluIEFkbWlu QmFuIFVzZXJz U2VuZCBFLW1haWwgdG8gVXNlcnMgaW4gQWRtaW4= QWRtaW4gTG9naW4= QWRkIFBlbmRpbmcgQ2F0ZWdvcnk= QWRkIENhdGVnb3J5 RGVsZXRlIENhdGVnb3J5 TW9kaWZ5IENhdGVnb3J5 QWxsb3cgQWRkaW5nIFBlbmRpbmcgQ29udGVudCBSZXZpc2lvbnM= QWxsb3cgQWRkaW5nIENvbnRlbnQgUmV2aXNpb25z QWxsb3cgUmVzdG9yaW5nIENvbnRlbnQgUmV2aXNpb25zIGZyb20gSGlzdG9yeQ== QWxsb3cgVmlld2luZyBIaXN0b3J5IG9mIENvbnRlbnQgUmV2aXNpb25z QWxsb3cgTW9kZXJhdGluZyAoQXBwcm92ZS9EZWNsaW5lKSBDb250ZW50IFJldmlzaW9ucw== VmlldyBDYXRlZ29yeQ== QXBwZW5kIHBocGluZm8gdG8gYWxsIHBhZ2VzIChEZWJ1Zyk= RGlzcGxheSBJdGVtIFF1ZXJpZXMgKERlYnVnKQ== RGlzcGxheSBJdGVtIExpc3QgUXVlcmllcyAoRGVidWcp QWxsb3cgZmF2b3JpdGVz QWxsb3cgTG9naW4= Q2hhbmdlIFVzZXIgUHJvZmlsZXM= U2hvdyBMYW5ndWFnZSBUYWdz UmVhZC1Pbmx5IEFjY2VzcyBUbyBEYXRhYmFzZQ== Tm90IFRyYW5zbGF0ZWQ= VHJhbnNsYXRlZA== QWRtaW4= Qm90aA== RnJvbnQ= UGljaw== U2VsZWN0ZWQgQ29sdW1ucw== UG9wdWxhcg== UG9zaXRpb24gQW5kIFZpc2liaWxpdHk= UHJldmlvdXMgc2VjdGlvbg== UHJpbWFyeQ== QWN0aXZlIFNlY3Rpb25z QWN0aXZlIFVzZXJz U2VudCBUbw== TWVzc2FnZXMgZnJvbSBTaXRlIEFkbWluIGFyZSBmcm9t QWR2YW5jZWQgU2VhcmNo QWR2YW5jZWQgVXNlciBNYW5hZ2VtZW50 QWxsb3cgcGFzc3dvcmQgcmVzZXQgYWZ0ZXI= R2VuZXJhdGUgZnJvbSB0aGUgYXJ0aWNsZSBib2R5 RGF0ZSBvZiBCYWNrdXA6 QmFja3VwIFBhdGg= QmFja3VwIHN0YXR1cw== QmFubmVkIFVzZXJz RGF0ZSBvZiBCaXJ0aA== RWRpdG9yJ3MgUGljayBTZWN0aW9ucw== Q3VycmVudCBTZXNzaW9ucw== VG90YWwgU2l6ZSBvZiB0aGUgRGF0YWJhc2U= RGVmYXVsdA== VXNlciBJRCBmb3IgRGVmYXVsdCBQZXJzaXN0ZW50IFNldHRpbmdz RGVmYXVsdCBWYWx1ZQ== RGlzYWJsZWQgU2VjdGlvbnM= RGlzcGxheSBpbiBHcmlk RGlzcGxheSBPcmRlcg== QWxsb3cgRHVwbGljYXRlIFJhdGluZyBWb3Rlcw== QWxsb3cgRHVwbGljYXRlIFJldmlld3M= RWRpdG9yJ3MgUGljaw== VHlwZQ== VGhlIEVtYWlsIE1lc3NhZ2UgaGFzIGJlZW4gc2VudA== RXhwb3J0IENvbXBsZXRlIQ== RmllbGQgSWQ= RmllbGQgTGFiZWw= RmllbGQgTmFtZQ== RmllbGQgUHJvbXB0 RnJlcXVlbmN5 SGVhZGluZw== KE1pbmltdW0gNCk= SW1wb3J0IFNvdXJjZQ== SW5wdXQgVHlwZQ== S2VlcCBTZXNzaW9uIFdoZW4gQnJvc3dlciBJcyBDbG9zZWQ= TGFuZ3VhZ2UgQ2FjaGUgVGltZW91dA== TGFzdCBTZWN0aW9uIFVwZGF0ZQ== TGFzdCBVcGRhdGVkIExpbms= U2VydmVyIFJlcXVpcmVzIEF1dGhlbnRpY2F0aW9u UG9ydCAoZS5nLiBwb3J0IDI1KQ== TWFpbCBTZXJ2ZXIgQWRkcmVzcw== TWF4aW1hbCBpbXBvcnRlZCBzZWN0aW9uIGxldmVs TWVtYmVyc2hpcCBFeHBpcmVz TGVmdCBNZW51IChUcmVlKSBXaWR0aA== TW92ZSBkb3du TW92ZSB1cA== U2hvdyBtdWx0aXBsZQ== TmV3IFNlY3Rpb25z TmV3ZXN0IFNlY3Rpb24gRGF0ZQ== TmV3ZXN0IExpbmsgRGF0ZQ== TmV3ZXN0IFVzZXIgRGF0ZQ== Q3VycmVudGx5IEFjdGl2ZSBVc2VyIFNlc3Npb25z UGVuZGluZyBTZWN0aW9ucw== UGVuZGluZyBJdGVtcw== UGVyZm9ybSB0aGlzIG9wZXJhdGlvbiBub3c/ UGVyIFBhZ2U= UGVyc29uYWwgSW5mb3JtYXRpb24= UHJpbWFyeSBHcm91cA== UHJpb3JpdHk= UmF0aW5n KE1pbmltdW0gMCwgTWF4aW11bSA1KQ== TnVtYmVyIG9mIERhdGFiYXNlIFJlY29yZHM= TnVtYmVyIG9mIFJlZ2lvbiBQYWNrcw== U2VhcmNoIFJlbGV2YW5jZSBkZXBlbmRzIG9u U2VhcmNoIFJlbGV2ZW5jZSBTZXR0aW5ncw== UmVxdWlyZWQ= SW5jcmVhc2UgaW1wb3J0YW5jZSBpZiBmaWVsZCBjb250YWlucyBhIHJlcXVpcmVkIGtleXdvcmQgYnk= UmVzdG9yZSBoYXMgZmFpbGVkIGFuIGVycm9yIG9jY3VyZWQ6 Q2hvb3NlIG9uZSBvZiB0aGUgZm9sbG93aW5nIGJhY2t1cCBkYXRlcyB0byByZXN0b3JlIG9yIGRlbGV0ZQ== UmVzdG9yZSBTdGF0dXM= UmVzdG9yZSBoYXMgYmVlbiBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5 U2VsZWN0IE1vZHVsZSBSb290IFNlY3Rpb246 Um9vdCBQYXNzd29yZA== U2VhcmNoIFR5cGU= U2VsZWN0IFNvdXJjZSBMYW5ndWFnZQ== U2VudCBPbg== U2Vzc2lvbiBDb29raWUgTmFtZQ== U2Vzc2lvbiBNYW5hZ2VtZW50IE1ldGhvZA== U2Vzc2lvbiBJbmFjdGl2aXR5IFRpbWVvdXQgKHNlY29uZHMp U2hvdyBvbiB0aGUgZ2VuZXJhbCB0YWI= U2ltcGxlIFNlYXJjaA== QWRkaXRpb25hbCBNZXNzYWdlIEhlYWRlcnM= TWFpbCBTZXJ2ZXIgUGFzc3dvcmQ= TWFpbCBTZXJ2ZXIgVXNlcm5hbWU= VXNlIG5vbi1ibG9ja2luZyBzb2NrZXQgbW9kZQ== U1FMIFF1ZXJ5Og== UGVyZm9ybSBTUUwgUXVlcnk= U3RlcCBPbmU= U3VibWl0dGVkIE9u RW5hYmxlIFRhZyBDYWNoaW5n VG90YWwgU2l6ZSBvZiBTeXN0ZW0gRmlsZXM= TnVtYmVyIG9mIERhdGFiYXNlIFRhYmxlcw== TnVtYmVyIG9mIFRoZW1lcw== VG90YWwgU2VjdGlvbnM= VG90YWwgVXNlciBHcm91cHM= QWN0aXZlIFVzZXJz RGlzYWJsZWQgVXNlcnM= UGVuZGluZyBVc2Vycw== TnVtYmVyIG9mIFVuaXF1ZSBDb3VudHJpZXMgb2YgVXNlcnM= TnVtYmVyIG9mIFVuaXF1ZSBTdGF0ZXMgb2YgVXNlcnM= VmFsaWRhdGlvbg== TGlzdCBvZiBWYWx1ZXM= KE1pbmltdW0gMSk= V2FybmluZyE= V2VpZ2h0 U2luZ2xlLVF1b3RlcyAoaWUuICcp UmVjaXByb2NhbA== UmVjb3Jkcw== VGhpcyByZWNvcmQgaXMgYmVpbmcgZWRpdGVkIGJ5IHRoZSBmb2xsb3dpbmcgdXNlcnM6DQolcw== VXNlIENhcHRjaGEgY29kZSBvbiBSZWdpc3RyYXRpb24= UmVndWxhcg== UmVtb3ZlIEZyb20= Tm90IGFsbCByZXF1aXJlZCBmaWVsZHMgYXJlIGZpbGxlZC4gUGxlYXNlIGZpbGwgdGhlbSBmaXJzdC4= Q29tbWVudHMgcGVyIFBhZ2U= Q29tbWVudHMgcGVyIFBhZ2UgKHNob3J0LWxpc3Qp UmV2aXNpb24gIyVz SG9tZQ== U2FtcGxlIFRleHQ= c2F2ZWQgYXQgJXM= U2F2ZSBVc2VybmFtZSBvbiBUaGlzIENvbXB1dGVy U2VhcmNo QmFzaWMgUGVybWlzc2lvbnM= U2VjdGlvbg== Q29uZmlnIEZpbGVz Q291bnRlcnM= Q3VzdG9tIEZpZWxkcw== U3VibWlzc2lvbiBEYXRh RS1tYWlsIERlc2lnbiBUZW1wbGF0ZXM= RmlsZQ== RnJvbnQtZW5k RnVsbCBTaXplIEltYWdl R2VuZXJhbA== SW1hZ2U= SW1hZ2UgU2V0dGluZ3M= SW1wb3J0IENvbXBsZXRlZA== VXNlciBJdGVtcw== TWVtb3J5IENhY2hl TWVzc2FnZQ== U2VjdGlvbiBPdmVydmlldw== U2VjdGlvbiBQcm9wZXJ0aWVz U2VjdGlvbiBDYWNoaW5n UHJvamVjdCBEZXBsb3ltZW50 UHJvcGVydGllcw== UXVpY2sgTGlua3M= UmVjaXBpZW50cyBJbmZvcm1hdGlvbg== UmVsYXRpb24= UmVwbGFjZW1lbnQgVGFncw== U2VuZGVyIEluZm9ybWF0aW9u U2V0dGluZ3M= M3JkIFBhcnR5IEFQSSBTZXR0aW5ncw== QWRtaW4gQ29uc29sZSBTZXR0aW5ncw== Q1NWIEV4cG9ydCBTZXR0aW5ncw== TG9ncyBTZXR0aW5ncw== TWFpbGluZyBTZXR0aW5ncw== TWFpbnRlbmFuY2UgU2V0dGluZ3M= U2Vzc2lvbiBTZXR0aW5ncw== U1NMIFNldHRpbmdz U3lzdGVtIFNldHRpbmdz V2Vic2l0ZSBTZXR0aW5ncw== U3VibWlzc2lvbiBOb3Rlcw== VGVtcGxhdGVz VGh1bWJuYWlsIEltYWdl VHJhbnNsYXRpb24= U2VhcmNoIFVzZXJz VmFsdWVz U2VsZWN0IENvbHVtbnM= U2VsZWN0ZWQgSXRlbXM= U2VsZWN0aW5nIFNlY3Rpb25z T25lIGZpZWxkIGZvciBlYWNoIHNlY3Rpb24gbGV2ZWw= Q2xvbmU= Q2xvbmU= Q29udGludWU= RWRpdA== RXhwb3J0 R28gVXA= SW1wb3J0 RG93bg== VXA= TmV3 UmVidWlsZA== UmVzY2FuIFRoZW1lcw== UmVzZXQ= UHJpbWFyeQ== U3luY2hyb25pemU= Vmlldw== U2hvdw== QWZmZWN0ZWQgcm93cw== RXhlY3V0ZWQgaW46 U3RlcA== RGVmaW5pdGlvbg== UHJldmlldw== U3VuZGF5 U3lzdGVt QWRtaW5pc3RyYXRpb24gUGFuZWwgVUk= QWR2YW5jZWQgVmlldw== QmFja3Vw QmFuIFJ1bGVz QmFzZSBTdHlsZXM= QmxvY2sgU3R5bGVz Q2F0YWxvZw== QnJvd3NlIFdlYnNpdGU= U2VjdGlvbnM= Q2hhbmdlcyBMb2c= Rm9ybXM= VXNlciBNYW5hZ2VtZW50 Q3VzdG9tIEZpZWxkcw== RS1tYWlsIEV2ZW50cw== R2VuZXJhbCBTZXR0aW5ncw== T3V0cHV0 U2VhcmNo R2VuZXJhbA== Q3VzdG9t RS1tYWlsIENvbW11bmljYXRpb24= RS1tYWlsIExvZw== RW1haWwgUXVldWU= RS1tYWlsIFRlbXBsYXRlcw== RmllbGRz RmlsZXM= Rm9ybXMgQ29uZmlndXJhdGlvbg== R2VuZXJhbA== R2VuZXJhbA== R3JvdXBz SGVscA== SW1hZ2Vz SW1wb3J0IERhdGE= SXRlbXM= TGFiZWxz TG9ncyAmIFJlcG9ydHM= TWVzc2FnZXM= UGFja2FnZSBDb250ZW50 UGVybWlzc2lvbnM= UGVybWlzc2lvbiBUeXBlcw== UHJvbW8gQmxvY2tz UHJvcGVydGllcw== UXVlcnkgRGF0YWJhc2U= UmVnaW9uYWw= UmVsYXRlZCBTZWFyY2hlcw== UmVsYXRpb25z UmVzdG9yZQ== Q29tbWVudHM= U2VhcmNo U2VhcmNoIExvZw== UEhQIEluZm9ybWF0aW9u U3lzdGVtIFRvb2xz U2Vzc2lvbiBMb2c= U2Vzc2lvbiBMb2c= U2V0dGluZ3M= U2hvdyBBbGw= U2hvdyBTdHJ1Y3R1cmU= V2Vic2l0ZSAmIENvbnRlbnQ= QWRtaW4gU2tpbnM= U3VtbWFyeQ== U3lzdGVtIExvZw== Q29uZmlndXJhdGlvbg== VGFnIGxpYnJhcnk= VGhlbWVz VG9vbHM= VXNlcnM= R3JvdXBz VXNlcnM= VmlzaXRvciBMb2c= VmlzaXRz dGV4dA== QWRtaW4= QWR2YW5jZWQ= QWxs QXV0by1SZWZyZXNo QmFjayB1cCBoYXMgYmVlbiBjb21wbGV0ZWQuIFRoZSBiYWNrdXAgZmlsZSBpczo= SW4tUG9ydGFsIGRvZXMgbm90IGhhdmUgYWNjZXNzIHRvIHdyaXRlIHRvIHRoaXMgZGlyZWN0b3J5 VGhpcyB1dGlsaXR5IGFsbG93cyB5b3UgdG8gYmFja3VwIHlvdXIgSW4tUG9ydGFsIGRhdGFiYXNlIHNvIGl0IGNhbiBiZSByZXN0b3JlZCBhdCBsYXRlciBpbiBuZWVkZWQu Ynl0ZXM= Q2F0YWxvZw== U2VjdGlvbnM= U2VjdGlvbg== WW91IGFyZSBhYm91dCB0byBjbGVhciBjbGlwYm9hcmQgY29udGVudCENClByZXNzIE9LIHRvIGNvbnRpbnVlIG9yIENhbmNlbCB0byByZXR1cm4gdG8gcHJldmlvdXMgc2NyZWVuLg== Q3VzdG9tIEZpZWxkcw== c2VjdGlvbnM= RGF0ZS9UaW1lIFNldHRpbmdz UnVubmluZyB0aGlzIHV0aWxpdHkgd2lsbCBhZmZlY3QgeW91ciBkYXRhYmFzZS4gUGxlYXNlIGJlIGFkdmlzZWQgdGhhdCB5b3UgY2FuIHVzZSB0aGlzIHV0aWxpdHkgYXQgeW91ciBvd24gcmlzay4gSW4tUG9ydGFsIG9yIGl0J3MgZGV2ZWxvcGVycyBjYW4gbm90IGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgY29ycnVwdCBkYXRhIG9yIGRhdGEgbG9zcy4= RGVmYXVsdA== RGVsZXRl RGlzYWJsZQ== UnVubmluZyB0aGlzIHV0aWxpdHkgd2lsbCBhZmZlY3QgeW91ciBkYXRhYmFzZS4gUGxlYXNlIGJlIGFkdmlzZWQgdGhhdCB5b3UgY2FuIHVzZSB0aGlzIHV0aWxpdHkgYXQgeW91ciBvd24gcmlzay4gSW4tUG9ydGFsIG9yIGl0J3MgZGV2ZWxvcGVycyBjYW4gbm90IGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgY29ycnVwdCBkYXRhIG9yIGRhdGEgbG9zcy4= UGxlYXNlIG1ha2Ugc3VyZSB0byBCQUNLVVAgeW91ciBkYXRhYmFzZShzKSBiZWZvcmUgcnVubmluZyB0aGlzIHV0aWxpdHkh RWRpdA== RW1haWw= Rm9sbG93aW5nIGxpbmVzIHdlcmUgTk9UIGltcG9ydGVk RnJvbnQtRW5kIE9ubHk= R2VuZXJhbA== SG90 SSBhZ3JlZSB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnM= SW1wb3J0IFJlc3VsdHM= SW4gRGV2ZWxvcG1lbnQ= SW52ZXJ0 S2V5d29yZA== TGluaw== RGVmYXVsdCBNRVRBIGtleXdvcmRz TWluaW11bSBwYXNzd29yZCBsZW5ndGg= VXNlciBuYW1lIGxlbmd0aCAobWluIC0gbWF4KQ== U2hvdyBtdWx0aXBsZQ== TmV3 Tm9uZQ== Tm8gUGVybWlzc2lvbg== b3I= UGhvbmU= UG9wdWxhcg== UG9wdWxhcml0eQ== UmVhZHkgdG8gSW5zdGFsbA== cmVjb3JkcyBhZGRlZA== cmVjb3JkcyB1cGRhdGVk UmVxdWlyZWQgZmllbGRz SGVyZSB5b3UgY2FuIHJlc3RvcmUgeW91ciBkYXRhYmFzZSBmcm9tIGEgcHJldmlvdXNseSBiYWNrZWQgdXAgc25hcHNob3QuIFJlc3RvcmluZyB5b3VyIGRhdGFiYXNlIHdpbGwgZGVsZXRlIGFsbCBvZiB5b3VyIGN1cnJlbnQgZGF0YSBhbmQgbG9nIHlvdSBvdXQgb2YgdGhlIHN5c3RlbS4= Q29tbWVudA== Q29tbWVudHM= TW9kdWxlIFJvb3QgU2VjdGlvbg== U2F2ZQ== U2VsZWN0 U2Vzc2lvbiBFeHBpcmVk U2ltcGxl U29ydA== VW5zZWxlY3Q= VXNlcg== VXNlcnM= VmVyc2lvbg== Vmlldw== QWRkaW5nIEFkbWluaXN0cmF0b3I= QWRkaW5nIEJhbiBSdWxl QWRkaW5nIENvdW50cnkvU3RhdGU= QWRkaW5nIEN1c3RvbSBGaWVsZA== QWRkaW5nIEUtbWFpbCBUZW1wbGF0ZQ== QWRkaW5nIEZpbGU= QWRkaW5nIEl0ZW0gRmlsdGVy QWRkaW5nIE1haWxpbmcgTGlzdA== QWRkaW5nIFBlcm1pc3Npb24gVHlwZQ== QWRkaW5nIFByb21vIEJsb2Nr QWRkaW5nIFByb21vIEJsb2NrIEdyb3Vw QWRkaW5nIFNjaGVkdWxlZCBUYXNr QWRkaW5nIFNpdGUgRG9tYWlu QWRkaW5nIFNraW4= QWRkaW5nIFNwZWxsaW5nIERpY3Rpb25hcnk= QWRkaW5nIFN0b3AgV29yZA== QWRkaW5nIFN5c3RlbSBFdmVudCBTdWJzY3JpcHRpb24= QWRkaW5nIFN5c3RlbSBTZXR0aW5n QWRkaW5nIFRoZW1lIFRlbXBsYXRl QWRkaW5nIFRoZXNhdXJ1cw== QWRkaW5nIEJhc2UgU3R5bGU= QWRkaW5nIEJsb2NrIFN0eWxl QWRkaW5nIFNlY3Rpb24= QWRkaW5nIFNlYXJjaCBGaWVsZA== QWRkaW5nIENNUyBCbG9jaw== QWRkaW5nIEZvcm0= QWRkaW5nIEZvcm0gRmllbGQ= QWRkaW5nIEdyb3Vw QWRkaW5nIEltYWdl QWRkaW5nIExhbmd1YWdl QWRkaW5nIFBocmFzZQ== QWRkaW5nIEtleXdvcmQ= QWRkaW5nIFJlbGF0aW9uc2hpcA== QWRkaW5nIENvbW1lbnQ= QWRkaW5nIFRoZW1l QWRkaW5nIFVzZXI= QWRkaXRpb25hbCBQZXJtaXNzaW9ucw== QWRtaW5pc3RyYXRvcnM= QWR2YW5jZWQ= U2hvd2luZyBhbGwgcmVnYXJkbGVzcyBvZiBTdHJ1Y3R1cmU= QmFzZSBTdHlsZXM= QmxvY2sgU3R5bGVz Qm91bmNlIFBPUDMgU2VydmVyIFNldHRpbmdz U2VjdGlvbnM= U2VsZWN0IHNlY3Rpb24= Q29sdW1uIFBpY2tlcg== Q29uZmlndXJhdGlvbg== Q29udGFjdCBJbmZvcm1hdGlvbg== Q291bnRyaWVzICYgU3RhdGVz Q1NWIEV4cG9ydA== Q1NWIEltcG9ydA== Q3VzdG9t Q3VzdG9tIEZpZWxkcw== RGVwbG95bWVudA== RWRpdGluZyBBZG1pbmlzdHJhdG9y RWRpdGluZyBCYW4gUnVsZQ== RWRpdGluZyBDaGFuZ2VzIExvZw== Q29udGVudCBFZGl0b3IgLSBBdXRvLXNhdmVkIGF0ICVz RWRpdGluZyBDb3VudHJ5L1N0YXRl RWRpdGluZyBEcmFmdCAoJTIkcyk= RWRpdGluZyBFLW1haWwgVGVtcGxhdGU= RWRpdGluZyBGaWxl RWRpdGluZyBJdGVtIEZpbHRlcg== RWRpdGluZyBNZW1iZXJzaGlw RWRpdGluZyBQZXJtaXNzaW9uIFR5cGU= RWRpdGluZyBQcm9tbyBCbG9jaw== RWRpdGluZyBQcm9tbyBCbG9jayBHcm91cA== RWRpdGluZyBTY2hlZHVsZWQgVGFzaw== RWRpdGluZyBTaXRlIERvbWFpbg== RWRpdGluZyBTa2lu RWRpdGluZyBTUEFNIFJlcG9ydA== RWRpdGluZyBTcGVsbGluZyBEaWN0aW9uYXJ5 RWRpdGluZyBTdG9wIFdvcmQ= RWRpdGluZyBTdHlsZQ== RWRpdGluZyBTeXN0ZW0gRXZlbnQgU3Vic2NyaXB0aW9u RWRpdGluZyBTeXN0ZW0gU2V0dGluZw== RWRpdGluZyBUaGVtZSBGaWxl RWRpdGluZyBUaGVzYXVydXM= RWRpdGluZyBUcmFuc2xhdGlvbg== RWRpdGluZyBCYXNlIFN0eWxl RWRpdGluZyBCbG9jayBTdHlsZQ== RWRpdGluZyBTZWN0aW9u RWRpdGluZyBDTVMgQmxvY2s= RWRpdGluZyBDdXN0b20gRmllbGQ= RWRpdGluZyBGb3Jt RWRpdGluZyBGb3JtIEZpZWxk RWRpdGluZyBHcm91cA== RWRpdGluZyBJbWFnZQ== RWRpdGluZyBMYW5ndWFnZQ== RWRpdGluZyBQaHJhc2U= RWRpdGluZyBLZXl3b3Jk RWRpdGluZyBSZWxhdGlvbnNoaXA= RWRpdGluZyBDb21tZW50 RWRpdGluZyBUaGVtZQ== RWRpdGluZyBVc2Vy RS1tYWlsIENvbW11bmljYXRpb24= RS1tYWlsIFNldHRpbmdz RS1tYWlsIFRlbXBsYXRlcw== RXhwb3J0IExhbmd1YWdlIFBhY2sgLSBSZXN1bHRz RXhwb3J0IExhbmd1YWdlIFBhY2sgLSBTdGVwMQ== RmllbGRz RmlsZXM= Rm9ybXM= Rm9ybSBTdWJtaXNzaW9ucw== R2VuZXJhbA== R3JvdXBz SW1hZ2Vz SW5zdGFsbCBMYW5ndWFnZSBQYWNrIC0gU3RlcCAx SW5zdGFsbCBMYW5ndWFnZSBQYWNrIC0gU3RlcCAy SXRlbSBGaWx0ZXJz SXRlbXM= TGFiZWxz TGFuZy4gTWFuYWdlbWVudA== TGFuZ3VhZ2UgUGFja3M= TGFuZ3VhZ2VzIE1hbmFnZW1lbnQ= TG9hZGluZyAuLi4= T3RoZXI= UmVxdWVzdA== U2Vzc2lvbg== U291cmNl TWFpbGluZ3M= TWVzc2FnZXM= TW9kdWxlIERlcGxveW1lbnQgTG9n TW9kdWxlcw== TmV3IEUtbWFpbCBUZW1wbGF0ZQ== TmV3IEZpbGU= TmV3IFJlcGx5 TmV3IFNjaGVkdWxlZCBUYXNr TmV3IFRoZW1l TmV3IFRoZW1lIFRlbXBsYXRl TmV3IEJhc2UgU3R5bGU= TmV3IEJsb2NrIFN0eWxl TmV3IFNlY3Rpb24= TmV3IEZpZWxk TmV3IEltYWdl TmV3IFJlbGF0aW9uc2hpcA== TmV3IENvbW1lbnQ= Tm8gUGVybWlzc2lvbnM= UGVybWlzc2lvbnM= TGFiZWxzICYgUGhyYXNlcw== UGxlYXNlIFdhaXQ= UHJvbW8gQmxvY2sgR3JvdXBz UHJvbW8gQmxvY2tz UHJvcGVydGllcw== UmVsYXRlZCBTZWFyY2hlcw== UmVsYXRpb25z UmVwbHkgUE9QMyBTZXJ2ZXIgU2V0dGluZ3M= Q29tbWVudHM= UnVuIFNjaGVkdWxl UnVuIFNldHRpbmdz U2NoZWR1bGVkIFRhc2tz U2VsZWN0IEdyb3VwKHMp U2VsZWN0IFVzZXI= U2VuZCBFLW1haWw= U2VuZGluZyBQcmVwYXJlZCBFLW1haWxz TWFpbCBoYXMgYmVlbiBzZW50IFN1Y2Nlc3NmdWxseQ== U2l0ZSBEb21haW5z U1BBTSBSZXBvcnRz U3BlbGxpbmcgRGljdGlvbmFyeQ== U3RvcCBXb3Jkcw== U3RydWN0dXJlICYgRGF0YQ== U3lzdGVtIEN1c3RvbSBGaWVsZHM= VXNlciBTdWJzY3JpcHRpb25z U3lzdGVtIFRvb2xz Q2xlYXIgVGVtcGxhdGVzIENhY2hl Q29tbW9ubHkgVXNlZCBLZXlz RGVwbG95IENoYW5nZXM= S2V5IE5hbWU= S2V5IFZhbHVl TG9jYXRlIFVuaXQgQ29uZmlnIEZpbGU= UmVidWlsZCBNdWx0aWxpbmd1YWwgRmllbGRz UmVjb21waWxlIFRlbXBsYXRlcw== UmVmcmVzaCBUaGVtZSBGaWxlcw== UmVzZXQgQWRtaW4gQ29uc29sZSBTZWN0aW9ucw== UmVzZXQgQWxsIEtleXM= UmVzZXQgQ29uZmlncyBGaWxlcyBDYWNoZSBhbmQgUGFyc2VkIFN5c3RlbSBEYXRh UmVzZXQgTW9kUmV3cml0ZSBDYWNoZQ== UmVzZXQgUGFyc2VkIGFuZCBDYWNoZWQgU3lzdGVtIERhdGE= UmVzZXQgU01TIE1lbnUgQ2FjaGU= U2hvdyBEYXRhYmFzZSBUYWJsZSBTdHJ1Y3R1cmU= U3luY2hyb25pemUgRGF0YWJhc2UgUmV2aXNpb25z VGhlbWUgRmlsZXM= VGhlc2F1cnVz VXBkYXRpbmcgU2VjdGlvbnM= VXNlcnM= Vmlld2luZyBFbWFpbCBMb2c= Vmlld2luZyBmb3JtIHN1Ym1pc3Npb24= Vmlld2luZyBNYWlsaW5nIExpc3Q= Vmlld2luZyBNb2R1bGUgRGVwbG95bWVudCBMb2c= Vmlld2luZyBSZXBseQ== Vmlld2luZyBSZXZpc2lvbiAjJXMgKCVzKQ== Vmlld2luZyBTeXN0ZW0gTG9n VmlzaXRz V2Vic2l0ZQ== dG8= Q3Vyci4gU2VjdGlvbg== RG93bg== VXA= QWRk QWRkIFVzZXIgdG8gR3JvdXA= QWRkIFVzZXIgVG8gR3JvdXA= QXBwcm92ZQ== QmFjaw== Q2FuY2Vs Q2xlYXIgQ2xpcGJvYXJk Q2xvbmU= Q2xvbmUgVXNlcnM= Q2xvc2U= Q29weQ== Q3V0 RGVjbGluZQ== RGVsZXRl RGVsZXRlIEFsbA== RGVsZXRlIFJldmlldw== RGVsZXRlIFJlcG9ydCBPbmx5 RGVueQ== RGV0YWlscw== RGlzYWJsZQ== RGlzY2FyZA== RWRpdA== RWRpdCBDdXJyZW50IFNlY3Rpb24= RnJvbnQtRW5kIE9ubHk= RW5hYmxl RXhwb3J0 RXhwb3J0IExhbmd1YWdl SGlkZSBNZW51 SGlzdG9yeQ== SG9tZQ== SW1wb3J0 SW1wb3J0IExhbmd1YWdl TG9naW4gQXM= TW92ZSBEb3du TW92ZSBVcA== TmV3IEJhc2UgU3R5bGU= TmV3IEJsb2NrIFN0eWxl TmV3IENvdW50cnkvU3RhdGU= TmV3IEdyb3Vw TmV3IGxhYmVs TmV3IExhbmd1YWdl TmV3IFBlcm1pc3Npb24= TmV3IFBocmFzZQ== TmV3IENvbW1lbnQ= TmV3IFNjaGVkdWxlZCBUYXNr TmV3IFNlYXJjaCBGaWVsZA== TmV3IFNpdGUgRG9tYWlu TmV3IFN0b3AgV29yZA== TmV3IFN5c3RlbSBTZXR0aW5n TmV3IFRlcm0= TmV3IFRoZW1l TmV3IFVzZXI= TmV3IFNlY3Rpb24= TmV3IEN1c3RvbSBGaWVsZA== TmV3IEZvcm0= TmV3IEZvcm0gRmllbGQ= TmV3IEltYWdlcw== QWRkIEtleXdvcmQ= TmV3IFJlbGF0aW9u TmV3IFRlbXBsYXRl TmV4dA== UGFzdGU= UHJldmlvdXM= UHJldmlldw== U2V0IFByaW1hcnkgR3JvdXA= UHJpbnQ= UHJvY2VzcyBRdWV1ZQ== UHVibGlzaA== UmVidWlsZCBTZWN0aW9uIENhY2hl UmVjYWxjdWxhdGUgUHJpb3JpdGllcw== UmVmcmVzaA== UmVwbHk= UmVzY2FuIFRoZW1lcw== UmVzZW5k UmVzZXQ= UmVzZXQgQ291bnRlcnM= UmVzZXQgUGVyc2lzdGVudCBTZXR0aW5ncw== UmVzZXQgVG8gQmFzZQ== UnVu UnVuIFNRTA== U2F2ZQ== U2F2ZSBhcyBEcmFmdA== U2VhcmNo UmVzZXQ= U2VsZWN0IFVzZXI= U2VuZA== U2VuZCBFLW1haWw= U2VuZCBFLW1haWw= U2V0IFByaW1hcnk= U2V0IFByaW1hcnkgU2VjdGlvbg== U2V0IFByaW1hcnkgTGFuZ3VhZ2U= VXNlIGFzIFByaW1hcnk= U2V0IFN0aWNreQ== U2V0dGluZ3M= U2hvdyBNZW51 U3luY2hyb25pemUgTGFuZ3VhZ2Vz VG9vbHM= VXAgYSBTZWN0aW9u VmFsaWRhdGU= Vmlldw== VmlldyBEZXRhaWxz Vmlldw== VG8gRGF0ZQ== VHJhbnNsYXRl VHJhbnNsYXRlZA== VHJlZQ== Q2hlY2tib3hlcw== RGF0ZQ== RGF0ZSAmIFRpbWU= TGFiZWw= TXVsdGlwbGUgU2VsZWN0 UGFzc3dvcmQgZmllbGQ= UmFkaW8gYnV0dG9ucw== UmFuZ2UgU2xpZGVy RHJvcCBkb3duIGZpZWxk Q2hlY2tib3g= VGV4dCBmaWVsZA== VGV4dCBhcmVh RmlsZSBVcGxvYWQ= VW5jaGFuZ2Vk VW5pY29kZQ== VXBkYXRpbmcgQ29uZmlndXJhdGlvbg== VXBsb2Fk VXNlIENyb24gdG8gcnVuIFNjaGVkdWxlZCBUYXNrcw== QXNzaWduIGFkbWluaXN0cmF0b3JzIHRvIGdyb3Vw QWxsb3cgbmV3IHVzZXIgcmVnaXN0cmF0aW9u QXNzaWduIEFsbCBVc2VycyBUbyBHcm91cA== QXNzaWduIHVzZXJzIG5vdCBsb2dnZWQgaW4gdG8gZ3JvdXA= QXNzaWduIHJlZ2lzdGVyZWQgdXNlcnMgdG8gZ3JvdXA= QXNzaWduIHBhc3N3b3JkIGF1dG9tYXRpY2FsbHk= QXNzaWduIG1haWxpbmcgbGlzdCBzdWJzY3JpYmVycyB0byBncm91cA== VVMvVUs= RS1tYWlsIGFkZHJlc3M= VmFsdWU= RGlyZWN0IGFjY2VzcyBvciBib29rbWFyaw== V2FybmluZzogRW5hYmxpbmcgSFRNTCBpcyBhIHNlY3VyaXR5IHJpc2sgYW5kIGNvdWxkIGRhbWFnZSB0aGUgc3lzdGVtIGlmIHVzZWQgaW1wcm9wZXJseSE= QSBzZWFyY2ggb3IgYSBmaWx0ZXIgaXMgaW4gZWZmZWN0LiBZb3UgbWF5IG5vdCBiZSBzZWVpbmcgYWxsIG9mIHRoZSBkYXRhLg== T25lIG9yIG1vcmUgZmllbGRzIG9uIHRoaXMgZm9ybSBoYXMgYW4gZXJyb3IuPGJyLz4NCjxzbWFsbD5QbGVhc2UgbW92ZSB5b3VyIG1vdXNlIG92ZXIgdGhlIGZpZWxkcyBtYXJrZWQgd2l0aCByZWQgdG8gc2VlIHRoZSBlcnJvciBkZXRhaWxzLjwvc21hbGw+ TW9kaWZpY2F0aW9ucyB3aWxsIG5vdCB0YWtlIGVmZmVjdCB1bnRpbCB5b3UgY2xpY2sgdGhlIFNhdmUgYnV0dG9uIQ== d2Vlaw== V2luZG93cw== eWVhcg== WWVz U3ViLXNlY3Rpb25zIFF1YW50aXR5 TmF2aWdhdGlvbiBCYXI= UmF0aW5n TnVtYmVyIG9mIFJldmlld3M= TnVtYmVyIG9mIFJhdGluZyBWb3Rlcw== U2VjdGlvbiBJRA== Q3JlYXRlZCBCeSBVc2VyIElE RGF0ZSBDcmVhdGVk RGVzY3JpcHRpb24= RWRpdG9ycyBQaWNr SGl0cw== SXRlbSBJcyBIb3Q= TGluayBJRA== TWV0YSBEZXNjcmlwdGlvbg== TWV0YSBLZXl3b3Jkcw== TGFzdCBNb2RpZmllZCBEYXRl TW9kaWZpZWQgQnkgVXNlciBJRA== TmFtZQ== SXRlbSBJcyBOZXc= Tm90aWZ5IE93bmVyIG9mIENoYW5nZXM= T3JpZ2luYWwgSXRlbSBJRA== T3duZXIgVXNlciBJRA== UGFyZW50IElE UGFyZW50IFBhdGg= SXRlbSBJcyBQb3B1bGFy UHJpb3JpdHk= UXR5IFNvbGQ= UmVzb3VyY2UgSUQ= U3RhdHVz SXRlbSBJcyBhIFRvcCBTZWxsZXI= VVJM b2Y= SW52YWxpZA== Tm90IFZhbGlkYXRlZA== VmFsaWQ= TmV3IENhdGVnb3J5ICI8aW5wMjpjX0ZpZWxkIG5hbWU9Ik5hbWUiLz4iIC0gQWRkZWQ= WW91ciBzdWdnZXN0ZWQgY2F0ZWdvcnkgIjxpbnAyOmNfRmllbGQgbmFtZT0iTmFtZSIvPiIgaGFzIGJlZW4gYWRkZWQu TmV3IENhdGVnb3J5ICI8aW5wMjpjX0ZpZWxkIG5hbWU9Ik5hbWUiLz4iIFN1Ym1pdHRlZCBieSBVc2Vycw== QSBjYXRlZ29yeSAiPGlucDI6Y19GaWVsZCBuYW1lPSJOYW1lIi8+IiBoYXMgYmVlbiBhZGRlZC4= U3VnZ2VzdGVkIENhdGVnb3J5ICI8aW5wMjpjX0ZpZWxkIG5hbWU9Ik5hbWUiLz4iIGlzIFBlbmRpbmc= VGhlIGNhdGVnb3J5IHlvdSBzdWdnZXN0ZWQgIjxpbnAyOmNfRmllbGQgbmFtZT0iTmFtZSIvPiIgaXMgcGVuZGluZyBmb3IgYWRtaW5pc3RyYXRpdmUgYXBwcm92YWwuDQoNClRoYW5rIHlvdSE= U3VnZ2VzdGVkIENhdGVnb3J5ICI8aW5wMjpjX0ZpZWxkIG5hbWU9Ik5hbWUiLz4iIGlzIFBlbmRpbmc= QSBjYXRlZ29yeSAiPGlucDI6Y19GaWVsZCBuYW1lPSJOYW1lIi8+IiBoYXMgYmVlbiBhZGRlZCwgcGVuZGluZyB5b3VyIGNvbmZpcm1hdGlvbi4gIFBsZWFzZSByZXZpZXcgdGhlIGNhdGVnb3J5IGFuZCBhcHByb3ZlIG9yIGRlbnkgaXQu QSBjYXRlZ29yeSBoYXMgYmVlbiBhcHByb3ZlZA== WW91ciBzdWdnZXN0ZWQgY2F0ZWdvcnkgIjxpbnAyOmNfRmllbGQgbmFtZT0iTmFtZSIvPiIgaGFzIGJlZW4gYXBwcm92ZWQu WW91ciBDYXRlZ29yeSAiPGlucDI6Y19GaWVsZCBuYW1lPSJOYW1lIi8+IiBoYXMgYmVlbiBEZW5pZWQ= WW91ciBjYXRlZ29yeSBzdWdnZXN0aW9uICI8aW5wMjpjX0ZpZWxkIG5hbWU9Ik5hbWUiLz4iIGhhcyBiZWVuIGRlbmllZC4= TmV3IEVtYWlsIFJFUExZIFJlY2VpdmVkIGluICJGZWVkYmFjayBNYW5hZ2VyIiAoPGlucDI6Zm9ybXN1YnMuLWl0ZW1fRmllbGQgbmFtZT0iRm9ybVN1Ym1pc3Npb25JZCIvPik= TmV3IEVtYWlsIFJFUExZIFJlY2VpdmVkIGluICZxdW90O0ZlZWRiYWNrIE1hbmFnZXImcXVvdDsuPGJyIC8+DQo8YnIgLz4NCk9yaWdpbmFsIEZlZWRiYWNrSWQ6IDxpbnAyOmZvcm1zdWJzLi1pdGVtX0ZpZWxkIG5hbWU9IkZvcm1TdWJtaXNzaW9uSWQiLz4gPGJyIC8+DQpPcmlnaW5hbCBTdWJqZWN0OiA8aW5wMjpmb3Jtc3Vicy4taXRlbV9Gb3JtRmllbGQgcm9sZT0ic3ViamVjdCIvPiA8YnIgLz4NCjxiciAvPg0KUGxlYXNlIHByb2NlZWQgdG8gdGhlIEFkbWluIENvbnNvbGUgaW4gb3JkZXIgdG8gcmV2aWV3IGFuZCByZXBseSB0byB0aGUgdXNlci4= TmV3IEVtYWlsIC0gRGVsaXZlcnkgRmFpbHVyZSBSZWNlaXZlZCBpbiAiRmVlZGJhY2sgTWFuYWdlciIgKDxpbnAyOmZvcm1zdWJzLi1pdGVtX0ZpZWxkIG5hbWU9IkZvcm1TdWJtaXNzaW9uSWQiLz4p TmV3IEVtYWlsIERlbGl2ZXJ5IEZhaWx1cmUgUmVjZWl2ZWQgaW4gJnF1b3Q7RmVlZGJhY2sgTWFuYWdlciZxdW90Oy48YnIgLz4NCjxiciAvPg0KT3JpZ2luYWwgRmVlZGJhY2tJZDogPGlucDI6Zm9ybXN1YnMuLWl0ZW1fRmllbGQgbmFtZT0iRm9ybVN1Ym1pc3Npb25JZCIvPiA8YnIgLz4NCk9yaWdpbmFsIFN1YmplY3Q6IDxpbnAyOmZvcm1zdWJzLi1pdGVtX0Zvcm1GaWVsZCByb2xlPSJzdWJqZWN0Ii8+IDxiciAvPg0KPGJyIC8+DQpQbGVhc2UgcHJvY2VlZCB0byB0aGUgQWRtaW4gQ29uc29sZSBpbiBvcmRlciB0byByZXZpZXcgYW5kIHJlcGx5IHRvIHRoZSB1c2VyLg== PGlucDI6bV9QYXJhbSBuYW1lPSJzdWJqZWN0Ii8+ICN2ZXJpZnk8aW5wMjpzdWJtaXNzaW9uLWxvZ19GaWVsZCBuYW1lPSJWZXJpZnlDb2RlIi8+ PGlucDI6bV9QYXJhbSBuYW1lPSJtZXNzYWdlIi8+ VGhhbmsgWW91IGZvciBDb250YWN0aW5nIFVzIQ== PHA+VGhhbmsgeW91IGZvciBjb250YWN0aW5nIHVzLiBXZSdsbCBiZSBpbiB0b3VjaCB3aXRoIHlvdSBzaG9ydGx5ITwvcD4= TmV3IGZvcm0gc3VibWlzc2lvbg== PHA+Rm9ybSBoYXMgYmVlbiBzdWJtaXR0ZWQuIFBsZWFzZSBwcm9jZWVkIHRvIHRoZSBBZG1pbiBDb25zb2xlIHRvIHJldmlldyB0aGUgc3VibWlzc2lvbiE8L3A+ Um9vdCBSZXNldCBQYXNzd29yZA== WW91ciBuZXcgcGFzc3dvcmQgaXM6IDxpbnAyOm1fUGFyYW0gbmFtZT0icGFzc3dvcmQiLz4= U3lzdGVtIExvZyBOb3RpZmljYXRpb25zICg8aW5wMjpzeXN0ZW0tbG9nLmVtYWlsX1RvdGFsUmVjb3Jkcy8+KQ== PGlucDI6bV9EZWZpbmVFbGVtZW50IG5hbWU9ImJhY2t0cmFjZV9lbGVtZW50Ij4NCgk8bGk+PGlucDI6bV9QaHJhc2UgbmFtZT0ibGFfTG9nQmFja3RyYWNlRnVuY3Rpb24iLz46IDxpbnAyOm1fUGFyYW0gbmFtZT0iZmlsZV9pbmZvIi8+PC9saT4NCjwvaW5wMjptX0RlZmluZUVsZW1lbnQ+DQoNCjxpbnAyOm1fRGVmaW5lRWxlbWVudCBuYW1lPSJzeXN0ZW1fbG9nX2VsZW1lbnQiPg0KCTxoND48aW5wMjpGaWVsZCBuYW1lPSJMb2dUaW1lc3RhbXAiIGZvcm1hdD0iTSBkIEg6aTpzIi8+IDxpbnAyOkZpZWxkIG5hbWU9IkxvZ0hvc3RuYW1lIi8+IDxpbnAyOlJlcXVlc3RVUkkgaHRtbF9lc2NhcGU9IjEiLz5bUElEPTxpbnAyOkZpZWxkIG5hbWU9IkxvZ1Byb2Nlc3NJZCIvPixVSUQ9PGlucDI6RmllbGQgbmFtZT0iTG9nVW5pcXVlSWQiLz5dPC9oND4NCglbPGlucDI6RmllbGQgbmFtZT0iTG9nTGV2ZWwiLz5dICM8aW5wMjpGaWVsZCBuYW1lPSJMb2dDb2RlIi8+OiA8aW5wMjpGaWVsZCBuYW1lPSJMb2dNZXNzYWdlIiBub19zcGVjaWFsPSIxIi8+IGluIDxpbnAyOkZpbGVuYW1lLz4gb24gbGluZSA8aW5wMjpGaWVsZCBuYW1lPSJMb2dTb3VyY2VGaWxlTGluZSIvPjxici8+DQoNCgk8aW5wMjptX2lmIGNoZWNrPSJGaWVsZCIgbmFtZT0iTG9nQmFja3RyYWNlIiBkYj0iZGIiPg0KCQk8YnIvPkJhY2t0cmFjZToNCg0KCQk8b2wgc3R5bGU9Im1hcmdpbjogMDsgcGFkZGluZy1sZWZ0OiAyNXB4OyBmb250LXNpemU6IDEycHg7Ij4NCgkJCTxpbnAyOlByaW50QmFja3RyYWNlIHJlbmRlcl9hcz0iYmFja3RyYWNlX2VsZW1lbnQiLz4NCgkJPC9vbD4NCgk8L2lucDI6bV9pZj4NCg0KCTxpbnAyOm1faWZub3QgY2hlY2s9Im1fUGFyYW0iIG5hbWU9ImlzX2xhc3QiPjxoci8+PC9pbnAyOm1faWZub3Q+DQo8L2lucDI6bV9EZWZpbmVFbGVtZW50Pg0KDQo8aW5wMjpzeXN0ZW0tbG9nLmVtYWlsX1ByaW50TGlzdCByZW5kZXJfYXM9InN5c3RlbV9sb2dfZWxlbWVudCIvPg== PGlucDI6bV9EZWZpbmVFbGVtZW50IG5hbWU9ImJhY2t0cmFjZV9wbGFpbl9lbGVtZW50Ij4NCjxpbnAyOkJhY2t0cmFjZUluZGV4Lz4uIDxpbnAyOm1fUGhyYXNlIG5hbWU9ImxhX0xvZ0JhY2t0cmFjZUZ1bmN0aW9uIi8+OiA8aW5wMjptX1BhcmFtIG5hbWU9ImZpbGVfaW5mbyIvPg0KPGlucDI6bV9pZm5vdCBjaGVjaz0ibV9QYXJhbSIgbmFtZT0iaXNfbGFzdCI+DQoNCjwvaW5wMjptX2lmbm90Pg0KPC9pbnAyOm1fRGVmaW5lRWxlbWVudD4NCjxpbnAyOm1fRGVmaW5lRWxlbWVudCBuYW1lPSJzeXN0ZW1fbG9nX3BsYWluX2VsZW1lbnQiPg0KPGlucDI6RmllbGQgbmFtZT0iTG9nVGltZXN0YW1wIiBmb3JtYXQ9Ik0gZCBIOmk6cyIvPiA8aW5wMjpGaWVsZCBuYW1lPSJMb2dIb3N0bmFtZSIvPiA8aW5wMjpSZXF1ZXN0VVJJLz5bUElEPTxpbnAyOkZpZWxkIG5hbWU9IkxvZ1Byb2Nlc3NJZCIvPixVSUQ9PGlucDI6RmllbGQgbmFtZT0iTG9nVW5pcXVlSWQiLz5dDQpbPGlucDI6RmllbGQgbmFtZT0iTG9nTGV2ZWwiLz5dICM8aW5wMjpGaWVsZCBuYW1lPSJMb2dDb2RlIi8+OiA8aW5wMjpGaWVsZCBuYW1lPSJMb2dNZXNzYWdlIiBub19zcGVjaWFsPSIxIi8+IGluIDxpbnAyOkZpbGVuYW1lLz4gb24gbGluZSA8aW5wMjpGaWVsZCBuYW1lPSJMb2dTb3VyY2VGaWxlTGluZSIvPg0KPGlucDI6bV9pZiBjaGVjaz0iRmllbGQiIG5hbWU9IkxvZ0JhY2t0cmFjZSIgZGI9ImRiIj4NCg0KQmFja3RyYWNlOg0KPGlucDI6UHJpbnRCYWNrdHJhY2UgcmVuZGVyX2FzPSJiYWNrdHJhY2VfcGxhaW5fZWxlbWVudCIgc3RyaXBfdGFncz0iMSIvPjwvaW5wMjptX2lmPg0KPGlucDI6bV9pZm5vdCBjaGVjaz0ibV9QYXJhbSIgbmFtZT0iaXNfbGFzdCI+DQotLS0tLS0tLS0tLS0tDQoNCjwvaW5wMjptX2lmbm90Pg0KPC9pbnAyOm1fRGVmaW5lRWxlbWVudD4NCjxpbnAyOnN5c3RlbS1sb2cuZW1haWxfUHJpbnRMaXN0IHJlbmRlcl9hcz0ic3lzdGVtX2xvZ19wbGFpbl9lbGVtZW50Ii8+ SW4tcG9ydGFsIHJlZ2lzdHJhdGlvbg== RGVhciA8aW5wMjp1LnJlZ2lzdGVyX0ZpZWxkIG5hbWU9IkZpcnN0TmFtZSIgLz4gPGlucDI6dS5yZWdpc3Rlcl9GaWVsZCBuYW1lPSJMYXN0TmFtZSIgLz4sDQoNClRoYW5rIHlvdSBmb3IgcmVnaXN0ZXJpbmcgb24gPGlucDI6bV9MaW5rIHRlbXBsYXRlPSJpbmRleCIvPi4gWW91ciByZWdpc3RyYXRpb24gaXMgbm93IGFjdGl2ZS4NCjxpbnAyOm1faWYgY2hlY2s9InUucmVnaXN0ZXJfRmllbGQiIG5hbWU9IkVtYWlsIj4NCjxici8+PGJyLz4NClBsZWFzZSBjbGljayBoZXJlIHRvIHZlcmlmeSB5b3VyIEUtbWFpbCBhZGRyZXNzOg0KPGEgaHJlZj0iPGlucDI6dS5yZWdpc3Rlcl9Db25maXJtUGFzc3dvcmRMaW5rIHQ9InBsYXRmb3JtL215X2FjY291bnQvdmVyaWZ5X2VtYWlsIiBub19hbXA9IjEiLz4iPjxpbnAyOnUucmVnaXN0ZXJfQ29uZmlybVBhc3N3b3JkTGluayB0PSJwbGF0Zm9ybS9teV9hY2NvdW50L3ZlcmlmeV9lbWFpbCIgbm9fYW1wPSIxIi8+PC9hPjxici8+PGJyLz4NCjwvaW5wMjptX2lmPg== TmV3IFVzZXIgUmVnaXN0cmF0aW9uICg8aW5wMjp1LnJlZ2lzdGVyX0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+KQ== QSBuZXcgdXNlciAiPGlucDI6dS5yZWdpc3Rlcl9GaWVsZCBuYW1lPSdVc2VybmFtZScvPiIgaGFzIGJlZW4gYWRkZWQu TmV3IHVzZXIgaGFzIGJlZW4gY3JlYXRlZA== RGVhciA8aW5wMjp1X0ZpZWxkIG5hbWU9IkZpcnN0TmFtZSIvPiwNCg0KQSBuZXcgdXNlciBoYXMgYmVlbiBjcmVhdGVkIGFuZCBhc3NpZ25lZCB0byB5b3UNCg0KTm93IHlvdSBjYW4gbG9naW4gdXNpbmcgdGhlIGZvbGxvd2luZyBjcmVkZW50aWFsczoNCg0KPGlucDI6bV9pZiBjaGVjaz0idV9GaWVsZCIgbmFtZT0iVXNlcm5hbWUiPlVzZXJuYW1lOiA8aW5wMjp1X0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+PGlucDI6bV9lbHNlLz5FLW1haWw6IDxpbnAyOnVfRmllbGQgbmFtZT0iRW1haWwiLz48L2lucDI6bV9pZj4gDQpQYXNzd29yZDogPGlucDI6dV9GaWVsZCBuYW1lPSJQYXNzd29yZF9wbGFpbiIvPiANCg== TmV3IFVzZXIgUmVnaXN0cmF0aW9uICg8aW5wMjp1LnJlZ2lzdGVyX0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+PGlucDI6bV9pZiBjaGVjaz0ibV9HZXRDb25maWciIG5hbWU9IlVzZXJfQWxsb3dfTmV3IiBlcXVhbHNfdG89IjQiPiAtIEFjdGl2YXRpb24gRW1haWw8L2lucDI6bV9pZj4p RGVhciA8aW5wMjp1LnJlZ2lzdGVyX0ZpZWxkIG5hbWU9IkZpcnN0TmFtZSIgLz4gPGlucDI6dS5yZWdpc3Rlcl9GaWVsZCBuYW1lPSJMYXN0TmFtZSIgLz4sPGJyIC8+DQo8YnIgLz4NCjxpbnAyOm1faWYgY2hlY2s9Im1fR2V0Q29uZmlnIiBuYW1lPSJVc2VyX0FsbG93X05ldyIgZXF1YWxzX3RvPSI0Ij4NCglUaGFuayB5b3UgZm9yIHJlZ2lzdGVyaW5nIG9uIDxpbnAyOm1fTGluayB0ZW1wbGF0ZT0iaW5kZXgiLz4gd2Vic2l0ZS4gVG8gYWN0aXZhdGUgeW91ciByZWdpc3RyYXRpb24gcGxlYXNlIGZvbGxvdyBsaW5rIGJlbG93LiA8aW5wMjp1LnJlZ2lzdGVyX0FjdGl2YXRpb25MaW5rIHRlbXBsYXRlPSJwbGF0Zm9ybS9sb2dpbi9hY3RpdmF0ZV9jb25maXJtIi8+DQo8aW5wMjptX2Vsc2UvPg0KCVRoYW5rIHlvdSBmb3IgcmVnaXN0ZXJpbmcgb24gPGlucDI6bV9MaW5rIHRlbXBsYXRlPSJpbmRleCIvPiB3ZWJzaXRlLiBZb3VyIHJlZ2lzdHJhdGlvbiB3aWxsIGJlIGFjdGl2ZSBhZnRlciBhcHByb3ZhbC4gDQoJDQoJPGlucDI6bV9pZiBjaGVjaz0idS5yZWdpc3Rlcl9GaWVsZCIgbmFtZT0iRW1haWwiPg0KCQk8YnIvPjxici8+DQoJCVBsZWFzZSBjbGljayBoZXJlIHRvIHZlcmlmeSB5b3VyIEUtbWFpbCBhZGRyZXNzOg0KCQk8YSBocmVmPSI8aW5wMjp1LnJlZ2lzdGVyX0NvbmZpcm1QYXNzd29yZExpbmsgdD0icGxhdGZvcm0vbXlfYWNjb3VudC92ZXJpZnlfZW1haWwiIG5vX2FtcD0iMSIvPiI+PGlucDI6dS5yZWdpc3Rlcl9Db25maXJtUGFzc3dvcmRMaW5rIHQ9InBsYXRmb3JtL215X2FjY291bnQvdmVyaWZ5X2VtYWlsIiBub19hbXA9IjEiLz48L2E+PGJyLz48YnIvPg0KCTwvaW5wMjptX2lmPg0KPC9pbnAyOm1faWY+ TmV3IFVzZXIgUmVnaXN0ZXJlZA== QSBuZXcgdXNlciAiPGlucDI6dS5yZWdpc3Rlcl9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiIgaGFzIHJlZ2lzdGVyZWQgYW5kIGlzIHBlbmRpbmcgYWRtaW5pc3RyYXRpdmUgYXBwcm92YWwu WW91ciBBY2NvdW50IGlzIEFjdGl2ZQ== V2VsY29tZSB0byA8aW5wMjptX0xpbmsgdGVtcGxhdGU9ImluZGV4Ii8+IQ0KDQpZb3VyIHVzZXIgcmVnaXN0cmF0aW9uIGhhcyBiZWVuIGFwcHJvdmVkLiBZb3VyIHVzZXIgbmFtZSBpczogIjxpbnAyOnVfRmllbGQgbmFtZT0iVXNlcm5hbWUiLz4iLg== TmV3IFVzZXIgQWNjb3VudCAiPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiIgd2FzIEFwcHJvdmVk VXNlciAiPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiIgaGFzIGJlZW4gYXBwcm92ZWQu WW91ciBSZWdpc3RyYXRpb24gaGFzIGJlZW4gRGVuaWVk WW91ciByZWdpc3RyYXRpb24gb24gPGEgaHJlZj0iPGlucDI6bV9MaW5rIHRlbXBsYXRlPSJpbmRleCIvPiI+PGlucDI6bV9MaW5rIHRlbXBsYXRlPSJpbmRleCIvPjwvYT4gd2Vic2l0ZSBoYXMgYmVlbiBkZW5pZWQu VXNlciBSZWdpc3RyYXRpb24gZm9yICAiPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiIgaGFzIGJlZW4gRGVuaWVk VXNlciAiPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiIgaGFzIGJlZW4gZGVuaWVkLg== Q2hhbmdlZCBFLW1haWwgUm9sbGJhY2s= SGVsbG8sPGJyLz48YnIvPg0KDQpJdCBzZWVtcyB0aGF0IHlvdSBoYXZlIGNoYW5nZWQgZS1tYWlsIGluIHlvdXIgSW4tcG9ydGFsIGFjY291bnQuIFlvdSBtYXkgdW5kbyB0aGlzIGNoYW5nZSBieSBjbGlja2luZyBvbiB0aGUgbGluayBiZWxvdzo8YnIvPjxici8+DQoNCjxhIGhyZWY9IjxpbnAyOnVfVW5kb0VtYWlsQ2hhbmdlTGluayB0ZW1wbGF0ZT0icGxhdGZvcm0vbXlfYWNjb3VudC9yZXN0b3JlX2VtYWlsIi8+Ij48aW5wMjp1X1VuZG9FbWFpbENoYW5nZUxpbmsgdGVtcGxhdGU9InBsYXRmb3JtL215X2FjY291bnQvcmVzdG9yZV9lbWFpbCIvPjwvYT48YnIvPjxici8+DQoNCklmIHlvdSBiZWxpZXZlIHlvdSBoYXZlIHJlY2VpdmVkIHRoaXMgZW1haWwgaW4gZXJyb3IsIHBsZWFzZSBpZ25vcmUgdGhpcyBlbWFpbC4gWW91ciBhY2NvdW50IHdpbGwgYmUgbGlua2VkIHRvIGFub3RoZXIgZS1tYWlsIHVubGVzcyB5b3UgaGF2ZSBjbGlja2VkIG9uIHRoZSBhYm92ZSBsaW5rLg== Q2hhbmdlZCBFLW1haWwgVmVyaWZpY2F0aW9u SGVsbG8sPGJyLz48YnIvPg0KDQpJdCBzZWVtcyB0aGF0IHlvdSBoYXZlIGNoYW5nZWQgZS1tYWlsIGluIHlvdXIgSW4tcG9ydGFsIGFjY291bnQuIFBsZWFzZSB2ZXJpZnkgdGhpcyBuZXcgZS1tYWlsIGJ5IGNsaWNraW5nIG9uIHRoZSBsaW5rIGJlbG93Ojxici8+PGJyLz4NCg0KPGEgaHJlZj0iPGlucDI6dV9Db25maXJtUGFzc3dvcmRMaW5rIHQ9InBsYXRmb3JtL215X2FjY291bnQvdmVyaWZ5X2VtYWlsIiBub19hbXA9IjEiLz4iPjxpbnAyOnVfQ29uZmlybVBhc3N3b3JkTGluayB0PSJwbGF0Zm9ybS9teV9hY2NvdW50L3ZlcmlmeV9lbWFpbCIgbm9fYW1wPSIxIi8+PC9hPjxici8+PGJyLz4NCg0KSWYgeW91IGJlbGlldmUgeW91IGhhdmUgcmVjZWl2ZWQgdGhpcyBlbWFpbCBpbiBlcnJvciwgcGxlYXNlIGlnbm9yZSB0aGlzIGVtYWlsLiBZb3VyIGVtYWlsIHdpbGwgbm90IGdldCB2ZXJpZmllZCBzdGF0dXMgdW5sZXNzIHlvdSBoYXZlIGNsaWNrZWQgb24gdGhlIGFib3ZlIGxpbmsuDQo= TWVtYmVyc2hpcCBFeHBpcmF0aW9uIE5vdGljZQ== WW91ciBtZW1iZXJzaGlwIG9uIDxpbnAyOm1fTGluayB0ZW1wbGF0ZT0iaW5kZXgiLz4gd2Vic2l0ZSB3aWxsIHNvb24gZXhwaXJlLg== TWVtYmVyc2hpcCBFeHBpcmF0aW9uIE5vdGljZSBmb3IgIjxpbnAyOnVfRmllbGQgbmFtZT0iVXNlcm5hbWUiLz4iIFNlbnQ= VXNlciA8aW5wMjp1X0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+IG1lbWJlcnNoaXAgd2lsbCBleHBpcmUgc29vbi4= WW91ciBNZW1iZXJzaGlwIEV4cGlyZWQ= WW91ciBtZW1iZXJzaGlwIG9uIDxpbnAyOm1fTGluayB0ZW1wbGF0ZT0iaW5kZXgiLz4gd2Vic2l0ZSBoYXMgZXhwaXJlZC4= VXNlcidzIE1lbWJlcnNoaXAgRXhwaXJlZCAgKCA8aW5wMjp1X0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+KQ== VXNlcidzICg8aW5wMjp1X0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+KSBtZW1iZXJzaGlwIG9uIDxpbnAyOm1fTGluayB0ZW1wbGF0ZT0iaW5kZXgiLz4gd2Vic2l0ZSBoYXMgZXhwaXJlZC4= TmV3IHBhc3N3b3JkIGdlbmVyYXRlZA== RGVhciA8aW5wMjp1X0ZpZWxkIG5hbWU9IkZpcnN0TmFtZSIvPiwNCg0KQSBuZXcgcGFzc3dvcmQgaGFzIGJlZW4gZ2VuZXJhdGVkIGZvciB5b3VyIHVzZXIuDQoNCk5vdyB5b3UgY2FuIGxvZ2luIHVzaW5nIHRoZSBmb2xsb3dpbmcgY3JlZGVudGlhbHM6DQoNCjxpbnAyOm1faWYgY2hlY2s9InVfRmllbGQiIG5hbWU9IlVzZXJuYW1lIj5Vc2VybmFtZTogPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPjxpbnAyOm1fZWxzZS8+RS1tYWlsOiA8aW5wMjp1X0ZpZWxkIG5hbWU9IkVtYWlsIi8+PC9pbnAyOm1faWY+IA0KUGFzc3dvcmQ6IDxpbnAyOnVfRmllbGQgbmFtZT0iUGFzc3dvcmRfcGxhaW4iLz4g UmVzZXQgUGFzc3dvcmQgQ29uZmlybWF0aW9u SGVsbG8sPGJyLz48YnIvPg0KDQpJdCBzZWVtcyB0aGF0IHlvdSBoYXZlIHJlcXVlc3RlZCBhIHBhc3N3b3JkIHJlc2V0IGZvciB5b3VyIEluLXBvcnRhbCBhY2NvdW50LiBJZiB5b3Ugd291bGQgbGlrZSB0byBwcm9jZWVkIGFuZCBjaGFuZ2UgdGhlIHBhc3N3b3JkLCBwbGVhc2UgY2xpY2sgb24gdGhlIGxpbmsgYmVsb3c6PGJyLz48YnIvPg0KDQo8YSBocmVmPSI8aW5wMjp1X0NvbmZpcm1QYXNzd29yZExpbmsgbm9fYW1wPSIxIi8+Ij48aW5wMjp1X0NvbmZpcm1QYXNzd29yZExpbmsgbm9fYW1wPSIxIi8+PC9hPjxici8+PGJyLz4NCg0KWW91IHdpbGwgcmVjZWl2ZSBhIHNlY29uZCBlbWFpbCB3aXRoIHlvdXIgbmV3IHBhc3N3b3JkIHNob3J0bHkuPGJyLz48YnIvPg0KDQpJZiB5b3UgYmVsaWV2ZSB5b3UgaGF2ZSByZWNlaXZlZCB0aGlzIGVtYWlsIGluIGVycm9yLCBwbGVhc2UgaWdub3JlIHRoaXMgZW1haWwuIFlvdXIgcGFzc3dvcmQgd2lsbCBub3QgYmUgY2hhbmdlZCB1bmxlc3MgeW91IGhhdmUgY2xpY2tlZCBvbiB0aGUgYWJvdmUgbGluay4NCg== U3Vic2NyaWJlZCB0byBhIE1haWxpbmcgTGlzdCBvbiA8aW5wMjptX0xpbmsgdGVtcGxhdGU9ImluZGV4Ii8+ WW91IGhhdmUgc3Vic2NyaWJlZCB0byBhIG1haWxpbmcgbGlzdCBvbiA8aW5wMjptX0xpbmsgdGVtcGxhdGU9ImluZGV4Ii8+IHdlYnNpdGUu TmV3IFVzZXIgaGFzIFN1YnNjcmliZWQgdG8gYSBNYWxsaW5nIExpc3Q= TmV3IHVzZXIgPGlucDI6RmllbGQgbmFtZT0iRW1haWwiLz4gaGFzIHN1YnNjcmliZWQgdG8gYSBtYWlsaW5nIGxpc3Qgb24gPGEgaHJlZj0iPGlucDI6bV9MaW5rIHRlbXBsYXRlPSJpbmRleCIvPiI+PGlucDI6bV9MaW5rIHRlbXBsYXRlPSJpbmRleCIvPjwvYT4gd2Vic2l0ZS4= Q2hlY2sgb3V0IHRoaXMgV2Vic2l0ZQ== SGVsbG8sPC9icj48L2JyPg0KDQpUaGlzIG1lc3NhZ2UgaGFzIGJlZW4gc2VudCB0byB5b3UgZnJvbSBvbmUgb2YgeW91ciBmcmllbmRzLjwvYnI+PC9icj4NCkNoZWNrIG91dCB0aGlzIHNpdGU6IDxhIGhyZWY9IjxpbnAyOm1fTGluayB0ZW1wbGF0ZT0iaW5kZXgiLz4iPjxpbnAyOm1fTGluayB0ZW1wbGF0ZT0iaW5kZXgiLz48L2E+IQ== V2Vic2l0ZSBTdWdnZXN0ZWQgdG8gYSBGcmllbmQ= QSB2aXNpdG9yIHN1Z2dlc3RlZCA8YSBocmVmPSI8aW5wMjptX0xpbmsgdGVtcGxhdGU9ImluZGV4Ii8+Ij48aW5wMjptX0xpbmsgdGVtcGxhdGU9ImluZGV4Ii8+PC9hPiB3ZWJzaXRlIHRvIGEgZnJpZW5kLg== WW91IGhhdmUgYmVlbiB1bnN1YnNjcmliZWQ= WW91IGhhdmUgc3VjY2Vzc2Z1bGx5IHVuc3Vic2NyaWJlZCBmcm9tIHRoZSBtYWlsaW5nIGxpc3Qgb24gPGEgaHJlZj0iPGlucDI6bV9CYXNlVXJsIC8+Ij48aW5wMjptX0Jhc2VVcmwgLz48L2E+IHdlYnNpdGUu VXNlciBVbnN1YnNyaWJlZCBmcm9tIE1haWxpbmcgTGlzdA== QSB1c2VyICI8aW5wMjpGaWVsZCBuYW1lPSJFbWFpbCIvPiIgaGFzIHVuc3Vic2NyaWJlZCBmcm9tIHRoZSBtYWlsaW5nIGxpc3Qgb24gPGEgaHJlZj0iPGlucDI6bV9MaW5rIHRlbXBsYXRlPSJpbmRleCIvPiI+PGlucDI6bV9MaW5rIHRlbXBsYXRlPSJpbmRleCIvPjwvYT4u VXNlciBSZWdpc3RyYXRpb24gaXMgVmFsaWRhdGVk V2VsY29tZSB0byBJbi1wb3J0YWwhPGJyLz48YnIvPg0KDQpZb3VyIHVzZXIgcmVnaXN0cmF0aW9uIGhhcyBiZWVuIGFwcHJvdmVkLiBZb3UgY2FuIGxvZ2luIG5vdyA8YSBocmVmPSI8aW5wMjptX0xpbmsgdGVtcGxhdGU9ImluZGV4Ii8+Ij48aW5wMjptX0xpbmsgdGVtcGxhdGU9ImluZGV4Ii8+PC9hPiB1c2luZyB0aGUgZm9sbG93aW5nIGluZm9ybWF0aW9uOjxici8+PGJyLz4NCg0KPT09PT09PT09PT09PT09PT09PGJyLz4NClVzZXJuYW1lOiAiPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiI8YnIvPg0KUGFzc3dvcmQ6ICI8aW5wMjp1X0ZpZWxkIG5hbWU9IlBhc3N3b3JkX3BsYWluIi8+Ijxici8+DQo9PT09PT09PT09PT09PT09PT08YnIvPjxici8+DQo= TmV3IFVzZXIgUmVnaXN0cmF0aW9uIGlzIFZhbGlkYXRlZA== VXNlciAiPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiIgaGFzIGJlZW4gdmFsaWRhdGVkLg== Index: branches/5.3.x/core/install.php =================================================================== --- branches/5.3.x/core/install.php (revision 16123) +++ branches/5.3.x/core/install.php (revision 16124) @@ -1,1777 +1,1777 @@ Init(); $install_engine->Run(); $install_engine->Done(); class kInstallator { /** * Reference to kApplication class object * * @var kApplication */ var $Application = null; /** * Connection to database * * @var IDBConnection */ var $Conn = null; /** * XML file containing steps information * * @var string */ var $StepDBFile = ''; /** * Step name, that currently being processed * * @var string */ var $currentStep = ''; /** * Steps list (preset) to use for current installation * * @var string */ var $stepsPreset = ''; /** * Installation steps to be done * * @var Array */ var $steps = Array ( 'fresh_install' => Array ('sys_requirements', 'check_paths', 'db_config', 'select_license', /*'download_license',*/ 'select_domain', 'root_password', 'choose_modules', 'post_config', 'sys_config', 'select_theme', 'security', 'finish'), 'clean_reinstall' => Array ('install_setup', 'sys_requirements', 'check_paths', 'clean_db', 'db_config', 'select_license', /*'download_license',*/ 'select_domain', 'root_password', 'choose_modules', 'post_config', 'sys_config', 'select_theme', 'security', 'finish'), 'already_installed' => Array ('check_paths', 'install_setup'), 'upgrade' => Array ('check_paths', 'install_setup', 'sys_config', 'upgrade_modules', 'skin_upgrade', 'security', 'finish'), 'update_license' => Array ('check_paths', 'install_setup', 'select_license', /*'download_license',*/ 'select_domain', 'security', 'finish'), 'update_config' => Array ('check_paths', 'install_setup', 'sys_config', 'security', 'finish'), 'db_reconfig' => Array ('check_paths', 'install_setup', 'db_reconfig', 'security', 'finish'), 'sys_requirements' => Array ('check_paths', 'install_setup', 'sys_requirements', 'security', 'finish') ); /** * Steps, that doesn't required admin to be logged-in to proceed * * @var Array */ var $skipLoginSteps = Array ('sys_requirements', 'check_paths', 'select_license', /*'download_license',*/ 'select_domain', 'root_password', 'choose_modules', 'post_config', 'select_theme', 'security', 'finish', -1); /** * Steps, on which kApplication should not be initialized, because of missing correct db table structure * * @var Array */ var $skipApplicationSteps = Array ('sys_requirements', 'check_paths', 'clean_db', 'db_config', 'db_reconfig' /*, 'install_setup'*/); // remove install_setup when application will work separately from install /** * Folders that should be writeable to continue installation. $1 - main writeable folder from config.php ("/system" by default) * * @var Array */ var $writeableFolders = Array ( '$1', '$1/.restricted', '$1/images', '$1/images/pending', '$1/images/emoticons', // for "In-Bulletin" '$1/user_files', '$1/cache', ); /** * Contains last error message text * * @var string */ var $errorMessage = ''; /** * Base path for includes in templates * * @var string */ var $baseURL = ''; /** * Holds number of last executed query in the SQL * * @var int */ var $LastQueryNum = 0; /** * Dependencies, that should be used in upgrade process * * @var Array */ var $upgradeDepencies = Array (); /** * Log of upgrade - list of upgraded modules and their versions * * @var Array */ var $upgradeLog = Array (); /** * Common tools required for installation process * * @var kInstallToolkit */ var $toolkit = null; function Init() { include_once(FULL_PATH . REL_PATH . '/kernel/kbase.php'); // required by kDBConnection class include_once(FULL_PATH . REL_PATH . '/kernel/utility/multibyte.php'); // emulating multi-byte php extension include_once(FULL_PATH . REL_PATH . '/kernel/utility/system_config.php'); require_once(FULL_PATH . REL_PATH . '/install/install_toolkit.php'); // toolkit required for module installations to installator $this->toolkit = new kInstallToolkit(); $this->toolkit->setInstallator($this); $this->StepDBFile = FULL_PATH.'/'.REL_PATH.'/install/steps_db.xml'; $this->baseURL = 'http://' . $_SERVER['HTTP_HOST'] . $this->toolkit->systemConfig->get('WebsitePath', 'Misc') . '/core/install/'; set_error_handler( Array(&$this, 'ErrorHandler') ); if ( $this->toolkit->systemConfigFound() ) { // if config.php found, then check his write permission too $this->writeableFolders[] = $this->toolkit->systemConfig->get('WriteablePath', 'Misc') . '/config.php'; } $this->currentStep = $this->GetVar('step'); // can't check login on steps where no application present anyways :) $this->skipLoginSteps = array_unique(array_merge($this->skipLoginSteps, $this->skipApplicationSteps)); $this->SelectPreset(); if (!$this->currentStep) { $this->SetFirstStep(); // sets first step of current preset } $this->InitStep(); } function SetFirstStep() { reset($this->steps[$this->stepsPreset]); $this->currentStep = current($this->steps[$this->stepsPreset]); } /** * Selects preset to proceed based on various criteria * */ function SelectPreset() { $preset = $this->GetVar('preset'); if ($this->toolkit->systemConfigFound()) { // only at installation first step $status = $this->CheckDatabase(false); if ($status && $this->AlreadyInstalled()) { // if already installed, then all future actions need login to work $this->skipLoginSteps = Array ('check_paths', -1); if (!$preset) { $preset = 'already_installed'; $this->currentStep = ''; } } } if ($preset === false) { $preset = 'fresh_install'; // default preset } $this->stepsPreset = $preset; } /** * Returns variable from request * * @param string $name * @param mixed $default * @return string|bool * @access private */ private function GetVar($name, $default = false) { if ( array_key_exists($name, $_COOKIE) ) { return $_COOKIE[$name]; } if ( array_key_exists($name, $_POST) ) { return $_POST[$name]; } return array_key_exists($name, $_GET) ? $_GET[$name] : $default; } /** * Sets new value for request variable * * @param string $name * @param mixed $value * @return void * @access private */ private function SetVar($name, $value) { $_POST[$name] = $value; } /** * Performs needed intialization of data, that step requires * */ function InitStep() { $require_login = !in_array($this->currentStep, $this->skipLoginSteps); $this->InitApplication($require_login); if ($require_login) { // step require login to proceed if (!$this->Application->LoggedIn()) { $this->stepsPreset = 'already_installed'; $this->currentStep = 'install_setup'; // manually set 2nd step, because 'check_paths' step doesn't contain login form // $this->SetFirstStep(); } } switch ($this->currentStep) { case 'sys_requirements': $required_checks = Array ( - 'php_version', 'curl', 'simplexml', 'freetype', 'gd_version', + 'php_version', 'composer', 'curl', 'simplexml', 'freetype', 'gd_version', 'jpeg', 'mysql', 'json', 'date.timezone', 'output_buffering', ); $check_results = $this->toolkit->CallPrerequisitesMethod('core/', 'CheckSystemRequirements'); $required_checks = array_diff($required_checks, array_keys( array_filter($check_results) )); if ( $required_checks ) { // php-based checks failed - show error $this->errorMessage = '
Installation can not continue until all required environment parameters are set correctly'; } elseif ( $this->GetVar('js_enabled') === false ) { // can't check JS without form submit - set some fake error, so user stays on this step $this->errorMessage = ' '; } elseif ( !$this->GetVar('js_enabled') || !$this->GetVar('cookies_enabled') ) { // js/cookies disabled $this->errorMessage = '
Installation can not continue until all required environment parameters are set correctly'; } break; case 'check_paths': $writeable_base = $this->toolkit->systemConfig->get('WriteablePath', 'Misc'); foreach ($this->writeableFolders as $folder_path) { $file_path = FULL_PATH . str_replace('$1', $writeable_base, $folder_path); if (file_exists($file_path) && !is_writable($file_path)) { $this->errorMessage = '
Installation can not continue until all required permissions are set correctly'; break; } } break; case 'clean_db': // don't use Application, because all tables will be erased and it will crash $sql = 'SELECT Path FROM ' . TABLE_PREFIX . 'Modules'; $modules = $this->Conn->GetCol($sql); foreach ($modules as $module_folder) { $remove_file = '/' . $module_folder . 'install/remove_schema.sql'; if (file_exists(FULL_PATH . $remove_file)) { $this->toolkit->RunSQL($remove_file); } } $this->toolkit->deleteEditTables(); $this->currentStep = $this->GetNextStep(); break; case 'db_config': case 'db_reconfig': $fields = Array ( 'DBType', 'DBHost', 'DBName', 'DBUser', 'DBUserPassword', 'DBCollation', 'TablePrefix' ); // set fields foreach ($fields as $field_name) { $submit_value = $this->GetVar($field_name); if ($submit_value !== false) { $this->toolkit->systemConfig->set($field_name, 'Database', $submit_value); } /*else { $this->toolkit->systemConfig->set($field_name, 'Database', ''); }*/ } break; case 'download_license': $license_source = $this->GetVar('license_source'); if ($license_source !== false && $license_source != 1) { // previous step was "Select License" and not "Download from Intechnic" option was selected $this->currentStep = $this->GetNextStep(); } break; case 'choose_modules': // if no modules found, then proceed to next step $modules = $this->ScanModules(); if (!$modules) { $this->currentStep = $this->GetNextStep(); } break; case 'select_theme': // put available theme list in database $this->toolkit->rebuildThemes(); break; case 'upgrade_modules': // get installed modules from db and compare their versions to upgrade script $modules = $this->GetUpgradableModules(); if (!$modules) { $this->currentStep = $this->GetNextStep(); } break; case 'skin_upgrade': if ($this->Application->RecallVar('SkinUpgradeLog') === false) { // no errors during skin upgrade -> skip this step $this->currentStep = $this->GetNextStep(); } break; case 'install_setup': if ( $this->Application->TableFound(TABLE_PREFIX . 'UserSession', true) ) { // update to 5.2.0 -> rename session table before using it // don't rename any other table here, since their names could be used in upgrade script $this->Conn->Query('RENAME TABLE ' . TABLE_PREFIX . 'UserSession TO ' . TABLE_PREFIX . 'UserSessions'); $this->Conn->Query('RENAME TABLE ' . TABLE_PREFIX . 'SessionData TO ' . TABLE_PREFIX . 'UserSessionData'); } $next_preset = $this->Application->GetVar('next_preset'); if ($next_preset !== false) { $user_helper = $this->Application->recallObject('UserHelper'); /* @var $user_helper UserHelper */ $username = $this->Application->GetVar('login'); $password = $this->Application->GetVar('password'); if ($username == 'root') { // verify "root" user using configuration settings $login_result = $user_helper->loginUser($username, $password); if ($login_result != LoginResult::OK) { $error_phrase = $login_result == LoginResult::NO_PERMISSION ? 'la_no_permissions' : 'la_invalid_password'; $this->errorMessage = $this->Application->Phrase($error_phrase) . '. If you don\'t know your username or password, contact Intechnic Support'; } } else { // non "root" user -> verify using licensing server $url_params = Array ( 'login' => md5($username), 'password' => md5($password), 'action' => 'check', 'license_code' => base64_encode( $this->toolkit->systemConfig->get('LicenseCode', 'Intechnic') ), 'version' => '4.3.0',//$this->toolkit->GetMaxModuleVersion('core/'), 'domain' => base64_encode($_SERVER['HTTP_HOST']), ); $curl_helper = $this->Application->recallObject('CurlHelper'); /* @var $curl_helper kCurlHelper */ $curl_helper->SetRequestData($url_params); $file_data = $curl_helper->Send(GET_LICENSE_URL); if ( !$curl_helper->isGoodResponseCode() ) { $this->errorMessage = 'In-Portal servers temporarily unavailable. Please contact In-Portal support personnel directly.'; } elseif (substr($file_data, 0, 5) == 'Error') { $this->errorMessage = substr($file_data, 6) . ' If you don\'t know your username or password, contact Intechnic Support'; } if ($this->errorMessage == '') { $user_helper->loginUserById(USER_ROOT); } } if ($this->errorMessage == '') { // processed with redirect to selected step preset if (!isset($this->steps[$next_preset])) { $this->errorMessage = 'Preset "'.$next_preset.'" not yet implemented'; } else { $this->stepsPreset = $next_preset; } } } else { // if preset was not choosen, then raise error $this->errorMessage = 'Please select action to perform'; } break; case 'security': // perform write check if ($this->Application->GetVar('skip_security_check')) { // administrator intensionally skips security checks break; } $write_check = true; $check_paths = Array ('/', '/index.php', $this->toolkit->systemConfig->get('WriteablePath', 'Misc') . '/config.php', ADMIN_DIRECTORY . '/index.php'); foreach ($check_paths as $check_path) { $path_check_status = $this->toolkit->checkWritePermissions(FULL_PATH . $check_path); if (is_bool($path_check_status) && $path_check_status) { $write_check = false; break; } } // script execute check if (file_exists(WRITEABLE . '/install_check.php')) { unlink(WRITEABLE . '/install_check.php'); } $fp = fopen(WRITEABLE . '/install_check.php', 'w'); fwrite($fp, "Application->recallObject('CurlHelper'); /* @var $curl_helper kCurlHelper */ $output = $curl_helper->Send($this->Application->BaseURL() . ltrim(WRITEBALE_BASE, '/') . '/install_check.php'); unlink(WRITEABLE . '/install_check.php'); $execute_check = ($output !== 'OK'); $directive_check = true; $ini_vars = Array ('register_globals' => false, 'open_basedir' => true, 'allow_url_fopen' => false); foreach ($ini_vars as $var_name => $var_value) { $current_value = ini_get($var_name); if (($var_value && !$current_value) || (!$var_value && $current_value)) { $directive_check = false; break; } } if (!$write_check || !$execute_check || !$directive_check) { $this->errorMessage = true; } /*else { $this->currentStep = $this->GetNextStep(); }*/ break; } $this->PerformValidation(); // returns validation status (just in case) } /** * Validates data entered by user * * @return bool */ function PerformValidation() { if ($this->GetVar('step') != $this->currentStep) { // just redirect from previous step, don't validate return true; } $status = true; switch ($this->currentStep) { case 'db_config': case 'db_reconfig': // 1. check if required fields are filled $section_name = 'Database'; $required_fields = Array ('DBType', 'DBHost', 'DBName', 'DBUser', 'DBCollation'); foreach ($required_fields as $required_field) { if (!$this->toolkit->systemConfig->get($required_field, $section_name)) { $status = false; $this->errorMessage = 'Please fill all required fields'; break; } } if ( !$status ) { break; } // 2. check permissions, that use have in this database $status = $this->CheckDatabase(($this->currentStep == 'db_config') && !$this->GetVar('UseExistingSetup')); break; case 'select_license': $license_source = $this->GetVar('license_source'); if ($license_source == 2) { // license from file -> file must be uploaded $upload_error = $_FILES['license_file']['error']; if ($upload_error != UPLOAD_ERR_OK) { $this->errorMessage = 'Missing License File'; } } elseif (!is_numeric($license_source)) { $this->errorMessage = 'Please select license'; } $status = $this->errorMessage == ''; break; case 'root_password': // check, that password & verify password match $password = $this->Application->GetVar('root_password'); $password_verify = $this->Application->GetVar('root_password_verify'); if ($password != $password_verify) { $this->errorMessage = 'Passwords does not match'; } elseif (mb_strlen($password) < 4) { $this->errorMessage = 'Root Password must be at least 4 characters'; } $status = $this->errorMessage == ''; break; case 'choose_modules': break; case 'upgrade_modules': $modules = $this->Application->GetVar('modules'); if (!$modules) { $modules = Array (); $this->errorMessage = 'Please select module(-s) to ' . ($this->currentStep == 'choose_modules' ? 'install' : 'upgrade'); } // check interface module $upgrade_data = $this->GetUpgradableModules(); if (array_key_exists('core', $upgrade_data) && !in_array('core', $modules)) { // core can be upgraded, but isn't selected $this->errorMessage = 'Please select "Core" as interface module'; } $status = $this->errorMessage == ''; break; } return $status; } /** * Perform installation step actions * */ function Run() { if ($this->errorMessage) { // was error during data validation stage return ; } switch ($this->currentStep) { case 'db_config': case 'db_reconfig': // store db configuration $sql = 'SHOW COLLATION LIKE \''.$this->toolkit->systemConfig->get('DBCollation', 'Database').'\''; $collation_info = $this->Conn->Query($sql); if ($collation_info) { $this->toolkit->systemConfig->set('DBCharset', 'Database', $collation_info[0]['Charset']); // database is already connected, that's why set collation on the fly $this->Conn->Query('SET NAMES \''.$this->toolkit->systemConfig->get('DBCharset', 'Database').'\' COLLATE \''.$this->toolkit->systemConfig->get('DBCollation', 'Database').'\''); } $this->toolkit->systemConfig->save(); if ($this->currentStep == 'db_config') { if ($this->GetVar('UseExistingSetup')) { // abort clean install and redirect to already_installed $this->stepsPreset = 'already_installed'; break; } // import base data into new database, not for db_reconfig $this->toolkit->RunSQL('/core/install/install_schema.sql'); $this->toolkit->RunSQL('/core/install/install_data.sql'); // create category using sql, because Application is not available here $table_name = $this->toolkit->systemConfig->get('TablePrefix', 'Database') . 'IdGenerator'; $this->Conn->Query('UPDATE ' . $table_name . ' SET lastid = lastid + 1'); $resource_id = $this->Conn->GetOne('SELECT lastid FROM ' . $table_name); if ($resource_id === false) { $this->Conn->Query('INSERT INTO '.$table_name.' (lastid) VALUES (2)'); $resource_id = 2; } // can't use USER_ROOT constant, since Application isn't available here $fields_hash = Array ( 'l1_Name' => 'Content', 'l1_MenuTitle' => 'Content', 'Filename' => 'Content', 'AutomaticFilename' => 0, 'CreatedById' => -1, 'CreatedOn' => time(), 'ResourceId' => $resource_id - 1, 'l1_Description' => 'Content', 'Status' => 4, ); $this->Conn->doInsert($fields_hash, $this->toolkit->systemConfig->get('TablePrefix', 'Database') . 'Categories'); $this->toolkit->SetModuleRootCategory('Core', $this->Conn->getInsertID()); // set module "Core" version after install (based on upgrade scripts) $this->toolkit->SetModuleVersion('Core', 'core/'); // for now we set "In-Portal" module version to "Core" module version (during clean install) $this->toolkit->SetModuleVersion('In-Portal', 'core/'); } break; case 'select_license': // reset memory cache, when application is first available (on fresh install and clean reinstall steps) $this->Application->HandleEvent(new kEvent('adm:OnResetMemcache')); $license_source = $this->GetVar('license_source'); switch ($license_source) { case 1: // Download from Intechnic break; case 2: // Upload License File $file_data = array_map('trim', file($_FILES['license_file']['tmp_name'])); if ((count($file_data) == 3) && $file_data[1]) { $modules_helper = $this->Application->recallObject('ModulesHelper'); /* @var $modules_helper kModulesHelper */ if ($modules_helper->verifyLicense($file_data[1])) { $this->toolkit->systemConfig->set('License', 'Intechnic', $file_data[1]); $this->toolkit->systemConfig->set('LicenseCode', 'Intechnic', $file_data[2]); $this->toolkit->systemConfig->save(); } else { $this->errorMessage = 'Invalid License File'; } } else { $this->errorMessage = 'Invalid License File'; } break; case 3: // Use Existing License $license_hash = $this->toolkit->systemConfig->get('License', 'Intechnic'); if ($license_hash) { $modules_helper = $this->Application->recallObject('ModulesHelper'); /* @var $modules_helper kModulesHelper */ if (!$modules_helper->verifyLicense($license_hash)) { $this->errorMessage = 'Invalid or corrupt license detected'; } } else { // happens, when browser's "Back" button is used $this->errorMessage = 'Missing License File'; } break; case 4: // Skip License (Local Domain Installation) if ($this->toolkit->sectionFound('Intechnic')) { // remove any previous license information $this->toolkit->systemConfig->set('License', 'Intechnic'); $this->toolkit->systemConfig->set('LicenseCode', 'Intechnic'); $this->toolkit->systemConfig->save(); } break; } break; case 'download_license': $license_login = $this->GetVar('login'); $license_password = $this->GetVar('password'); $license_id = $this->GetVar('licenses'); $curl_helper = $this->Application->recallObject('CurlHelper'); /* @var $curl_helper kCurlHelper */ if (strlen($license_login) && strlen($license_password) && !$license_id) { // Here we determine weather login is ok & check available licenses $url_params = Array ( 'login' => md5($license_login), 'password' => md5($license_password), 'version' => $this->toolkit->GetMaxModuleVersion('core/'), 'domain' => base64_encode($_SERVER['HTTP_HOST']), ); $curl_helper->SetRequestData($url_params); $file_data = $curl_helper->Send(GET_LICENSE_URL); if (!$file_data) { // error connecting to licensing server $this->errorMessage = 'Unable to connect to the Intechnic server! Please try again later!'; } else { if (substr($file_data, 0, 5) == 'Error') { // after processing data server returned error $this->errorMessage = substr($file_data, 6); } else { // license received if (substr($file_data, 0, 3) == 'SEL') { // we have more, then one license -> let user choose $this->SetVar('license_selection', base64_encode( substr($file_data, 4) )); // we received html with radio buttons with names "licenses" $this->errorMessage = 'Please select which license to use'; } else { // we have one license $this->toolkit->processLicense($file_data); } } } } else if (!$license_id) { // licenses were not queried AND user/password missing $this->errorMessage = 'Incorrect Username or Password. If you don\'t know your username or password, contact Intechnic Support'; } else { // Here we download license $url_params = Array ( 'license_id' => md5($license_id), 'dlog' => md5($license_login), 'dpass' => md5($license_password), 'version' => $this->toolkit->GetMaxModuleVersion('core/'), 'domain' => base64_encode($_SERVER['HTTP_HOST']), ); $curl_helper->SetRequestData($url_params); $file_data = $curl_helper->Send(GET_LICENSE_URL); if (!$file_data) { // error connecting to licensing server $this->errorMessage = 'Unable to connect to the Intechnic server! Please try again later!'; } else { if (substr($file_data, 0, 5) == 'Error') { // after processing data server returned error $this->errorMessage = substr($file_data, 6); } else { $this->toolkit->processLicense($file_data); } } } break; case 'select_domain': $modules_helper = $this->Application->recallObject('ModulesHelper'); /* @var $modules_helper kModulesHelper */ // get domain name as entered by user on the form $domain = $this->GetVar('domain') == 1 ? $_SERVER['HTTP_HOST'] : str_replace(' ', '', $this->GetVar('other')); $license_hash = $this->toolkit->systemConfig->get('License', 'Intechnic'); if ($license_hash) { // when license present, then extract domain from it $license_hash = base64_decode($license_hash); list ( , , $license_keys) = $modules_helper->_ParseLicense($license_hash); $license_domain = $license_keys[0]['domain']; } else { // when license missing, then use current domain or domain entered by user $license_domain = $domain; } if ($domain != '') { if (strstr($domain, $license_domain) || $modules_helper->_IsLocalSite($domain)) { $this->toolkit->systemConfig->set('Domain', 'Misc', $domain); $this->toolkit->systemConfig->save(); } else { $this->errorMessage = 'Domain name entered does not match domain name in the license!'; } } else { $this->errorMessage = 'Please enter valid domain!'; } break; case 'sys_config': $config_data = $this->GetVar('system_config'); foreach ($config_data as $section => $section_vars) { foreach ($section_vars as $var_name => $var_value) { $this->toolkit->systemConfig->set($var_name, $section, $var_value); } } $this->toolkit->systemConfig->save(); break; case 'root_password': // update root password in database $password_formatter = $this->Application->recallObject('kPasswordFormatter'); /* @var $password_formatter kPasswordFormatter */ $config_values = Array ( 'RootPass' => $password_formatter->hashPassword($this->Application->GetVar('root_password')), 'Backup_Path' => FULL_PATH . $this->toolkit->systemConfig->get('WriteablePath', 'Misc') . DIRECTORY_SEPARATOR . 'backupdata', 'DefaultEmailSender' => 'portal@' . $this->toolkit->systemConfig->get('Domain', 'Misc') ); $site_timezone = date_default_timezone_get(); if ($site_timezone) { $config_values['Config_Site_Time'] = $site_timezone; } $this->toolkit->saveConfigValues($config_values); $user_helper = $this->Application->recallObject('UserHelper'); /* @var $user_helper UserHelper */ // login as "root", when no errors on password screen $user_helper->loginUser('root', $this->Application->GetVar('root_password')); // import base language for core (english) $this->toolkit->ImportLanguage('/core/install/english'); // make sure imported language is set as active in session, created during installation $this->Application->Session->SetField('Language', 1); // set imported language as primary $lang = $this->Application->recallObject('lang.-item', null, Array('skip_autoload' => true)); /* @var $lang LanguagesItem */ $lang->Load(1); // fresh install => ID=1 $lang->setPrimary(true); // for Front-End break; case 'choose_modules': // run module install scripts $modules = $this->Application->GetVar('modules'); if ($modules) { foreach ($modules as $module) { $install_file = MODULES_PATH.'/'.$module.'/install.php'; if (file_exists($install_file)) { include_once($install_file); } } } // update category cache $updater = $this->Application->makeClass('kPermCacheUpdater'); /* @var $updater kPermCacheUpdater */ $updater->OneStepRun(); break; case 'post_config': $this->toolkit->saveConfigValues( $this->GetVar('config') ); break; case 'select_theme': // 1. mark theme, that user is selected $theme_id = $this->GetVar('theme'); $theme_config = $this->Application->getUnitConfig('theme'); $theme_table = $theme_config->getTableName(); $theme_id_field = $theme_config->getIDField(); $sql = 'UPDATE ' . $theme_table . ' SET Enabled = 1, PrimaryTheme = 1 WHERE ' . $theme_id_field . ' = ' . $theme_id; $this->Conn->Query($sql); $this->toolkit->rebuildThemes(); // rescan theme to create structure after theme is enabled !!! // install theme dependent demo data if ($this->Application->GetVar('install_demo_data')) { $sql = 'SELECT Name FROM ' . $theme_table . ' WHERE ' . $theme_id_field . ' = ' . $theme_id; $theme_name = $this->Conn->GetOne($sql); $site_path = $this->toolkit->systemConfig->get('WebsitePath','Misc') . '/'; $file_helper = $this->Application->recallObject('FileHelper'); /* @var $file_helper FileHelper */ foreach ($this->Application->ModuleInfo as $module_name => $module_info) { if ($module_name == 'In-Portal') { continue; } $template_path = '/themes' . '/' . $theme_name . '/' . $module_info['TemplatePath']; $this->toolkit->RunSQL( $template_path . '_install/install_data.sql', Array('{ThemeId}', '{SitePath}'), Array($theme_id, $site_path) ); if ( file_exists(FULL_PATH . $template_path . '_install/images') ) { // copy theme demo images into writable path accessible by FCKEditor $file_helper->copyFolderRecursive(FULL_PATH . $template_path . '_install/images' . DIRECTORY_SEPARATOR, WRITEABLE . '/user_files/Images'); } } } break; case 'upgrade_modules': // get installed modules from db and compare their versions to upgrade script $modules = $this->Application->GetVar('modules'); if ($modules) { $upgrade_data = $this->GetUpgradableModules(); $start_from_query = $this->Application->GetVar('start_from_query'); $this->upgradeDepencies = $this->getUpgradeDependencies($modules, $upgrade_data); if ($start_from_query !== false) { $this->upgradeLog = unserialize( $this->Application->RecallVar('UpgradeLog') ); } else { $start_from_query = 0; $this->upgradeLog = Array ('ModuleVersions' => Array ()); // remember each module version, before upgrade scripts are executed foreach ($modules as $module_name) { $module_info = $upgrade_data[$module_name]; $this->upgradeLog['ModuleVersions'][$module_name] = $module_info['FromVersion']; } $this->Application->RemoveVar('UpgradeLog'); } // 1. perform "php before", "sql", "php after" upgrades foreach ($modules as $module_name) { $module_info = $upgrade_data[$module_name]; /*echo '

Upgrading "' . $module_info['Name'] . '" to "' . $module_info['ToVersion'] . '"

' . "\n"; flush();*/ if (!$this->RunUpgrade($module_info['Name'], $module_info['ToVersion'], $upgrade_data, $start_from_query)) { $this->Application->StoreVar('UpgradeLog', serialize($this->upgradeLog)); $this->Done(); } // restore upgradable module version (makes sense after sql error processing) $upgrade_data[$module_name]['FromVersion'] = $this->upgradeLog['ModuleVersions'][$module_name]; } // 2. import language pack, perform "languagepack" upgrade for all upgraded versions foreach ($modules as $module_name) { $module_info = $upgrade_data[$module_name]; $sqls =& $this->getUpgradeQueriesFromVersion($module_info['Path'], $module_info['FromVersion']); preg_match_all('/' . VERSION_MARK . '/s', $sqls, $regs); // import module language pack $this->toolkit->ImportLanguage('/' . $module_info['Path'] . 'install/english', true); // perform advanced language pack upgrade foreach ($regs[1] as $version) { $this->RunUpgradeScript($module_info['Path'], $version, 'languagepack'); } } // 3. update all theme language packs $themes_helper = $this->Application->recallObject('ThemesHelper'); /* @var $themes_helper kThemesHelper */ $themes_helper->synchronizeModule(false); // 4. upgrade admin skin if (in_array('core', $modules)) { $skin_upgrade_log = $this->toolkit->upgradeSkin($upgrade_data['core']); if ($skin_upgrade_log === true) { $this->Application->RemoveVar('SkinUpgradeLog'); } else { $this->Application->StoreVar('SkinUpgradeLog', serialize($skin_upgrade_log)); } // for now we set "In-Portal" module version to "Core" module version (during upgrade) $this->toolkit->SetModuleVersion('In-Portal', false, $upgrade_data['core']['ToVersion']); } } break; case 'finish': // delete cache $this->toolkit->deleteCache(); $this->toolkit->rebuildThemes(); // compile admin skin, so it will be available in 3 frames at once $skin_helper = $this->Application->recallObject('SkinHelper'); /* @var $skin_helper SkinHelper */ $skin = $this->Application->recallObject('skin', null, Array ('skip_autoload' => true)); /* @var $skin kDBItem */ $skin->Load(1, 'IsPrimary'); $skin_helper->compile($skin); // set installation finished mark if ($this->Application->ConfigValue('InstallFinished') === false) { $fields_hash = Array ( 'VariableName' => 'InstallFinished', 'VariableValue' => 1, ); $this->Conn->doInsert($fields_hash, TABLE_PREFIX.'SystemSettings'); } $random_string = $this->Application->ConfigValue('RandomString'); if ( !$random_string ) { $user_helper = $this->Application->recallObject('UserHelper'); /* @var $user_helper UserHelper */ $random_string = $user_helper->generateRandomString(64, true, true); $this->Application->SetConfigValue('RandomString', $random_string); } break; } if ($this->errorMessage) { // was error during run stage return ; } $this->currentStep = $this->GetNextStep(); $this->InitStep(); // init next step (that will be shown now) $this->InitApplication(); if ($this->currentStep == -1) { // step after last step -> redirect to admin $user_helper = $this->Application->recallObject('UserHelper'); /* @var $user_helper UserHelper */ $user_helper->logoutUser(); $this->Application->Redirect($user_helper->event->redirect, $user_helper->event->getRedirectParams(), '', 'index.php'); } } function getUpgradeDependencies($modules, &$upgrade_data) { $dependencies = Array (); foreach ($modules as $module_name) { $module_info = $upgrade_data[$module_name]; $upgrade_object =& $this->getUpgradeObject($module_info['Path']); if (!is_object($upgrade_object)) { continue; } foreach ($upgrade_object->dependencies as $dependent_version => $version_dependencies) { if (!$version_dependencies) { // module is independent -> skip continue; } list ($parent_name, $parent_version) = each($version_dependencies); if (!array_key_exists($parent_name, $dependencies)) { // parent module $dependencies[$parent_name] = Array (); } if (!array_key_exists($parent_version, $dependencies[$parent_name])) { // parent module versions, that are required by other module versions $dependencies[$parent_name][$parent_version] = Array (); } $dependencies[$parent_name][$parent_version][] = Array ($module_info['Name'] => $dependent_version); } } return $dependencies; } /** * Returns database queries, that should be executed to perform upgrade from given to lastest version of given module path * * @param string $module_path * @param string $from_version * @return string */ function &getUpgradeQueriesFromVersion($module_path, $from_version) { $upgrades_file = sprintf(UPGRADES_FILE, $module_path, 'sql'); $sqls = file_get_contents($upgrades_file); $version_mark = preg_replace('/(\(.*?\))/', $from_version, VERSION_MARK); // get only sqls from next (relative to current) version to end of file $start_pos = strpos($sqls, $version_mark); $sqls = substr($sqls, $start_pos); return $sqls; } function RunUpgrade($module_name, $to_version, &$upgrade_data, &$start_from_query) { $module_info = $upgrade_data[ strtolower($module_name) ]; $sqls =& $this->getUpgradeQueriesFromVersion($module_info['Path'], $module_info['FromVersion']); preg_match_all('/(' . VERSION_MARK . ')/s', $sqls, $matches, PREG_SET_ORDER + PREG_OFFSET_CAPTURE); foreach ($matches as $index => $match) { // upgrade version $version = $match[2][0]; if ($this->toolkit->ConvertModuleVersion($version) > $this->toolkit->ConvertModuleVersion($to_version)) { // only upgrade to $to_version, not further break; } if (!in_array($module_name . ':' . $version, $this->upgradeLog)) { if ($this->Application->isDebugMode()) { $this->Application->Debugger->appendHTML('Upgrading "' . $module_name . '" to "' . $version . '" version: BEGIN.'); } /*echo 'Upgrading "' . $module_name . '" to "' . $version . '".
' . "\n"; flush();*/ // don't upgrade same version twice $start_pos = $match[0][1] + strlen($match[0][0]); $end_pos = array_key_exists($index + 1, $matches) ? $matches[$index + 1][0][1] : strlen($sqls); $version_sqls = substr($sqls, $start_pos, $end_pos - $start_pos); if ($start_from_query == 0) { $this->RunUpgradeScript($module_info['Path'], $version, 'before'); } if (!$this->toolkit->RunSQLText($version_sqls, null, null, $start_from_query)) { $this->errorMessage .= ''; $this->errorMessage .= '
Module "' . $module_name . '" upgrade to "' . $version . '" failed.'; $this->errorMessage .= '
Click Continue button below to skip this query and go further
'; return false; } else { // reset query counter, when all queries were processed $start_from_query = 0; } $this->RunUpgradeScript($module_info['Path'], $version, 'after'); if ($this->Application->isDebugMode()) { $this->Application->Debugger->appendHTML('Upgrading "' . $module_name . '" to "' . $version . '" version: END.'); } // remember, that we've already upgraded given version $this->upgradeLog[] = $module_name . ':' . $version; } if (array_key_exists($module_name, $this->upgradeDepencies) && array_key_exists($version, $this->upgradeDepencies[$module_name])) { foreach ($this->upgradeDepencies[$module_name][$version] as $dependency_info) { list ($dependent_module, $dependent_version) = each($dependency_info); if (!$this->RunUpgrade($dependent_module, $dependent_version, $upgrade_data, $start_from_query)) { return false; } } } // only mark module as updated, when all it's dependent modules are upgraded $this->toolkit->SetModuleVersion($module_name, false, $version); } return true; } /** * Run upgrade PHP scripts for module with specified path * * @param string $module_path * @param Array $version * @param string $mode upgrade mode = {before,after,languagepack} */ function RunUpgradeScript($module_path, $version, $mode) { $upgrade_object =& $this->getUpgradeObject($module_path); if (!is_object($upgrade_object)) { return ; } $upgrade_method = 'Upgrade_' . str_replace(Array ('.', '-'), '_', $version); if (method_exists($upgrade_object, $upgrade_method)) { $upgrade_object->$upgrade_method($mode); } } /** * Returns upgrade class for given module path * * @param string $module_path * @return kUpgradeHelper */ function &getUpgradeObject($module_path) { static $upgrade_classes = Array (); $upgrades_file = sprintf(UPGRADES_FILE, $module_path, 'php'); if (!file_exists($upgrades_file)) { $false = false; return $false; } if (!isset($upgrade_classes[$module_path])) { require_once(FULL_PATH . REL_PATH . '/install/upgrade_helper.php'); // save class name, because 2nd time (in after call) // $upgrade_class variable will not be present include_once $upgrades_file; $upgrade_classes[$module_path] = $upgrade_class; } $upgrade_object = new $upgrade_classes[$module_path](); /* @var $upgrade_object CoreUpgrades */ $upgrade_object->setToolkit($this->toolkit); return $upgrade_object; } /** * Initialize kApplication * * @param bool $force initialize in any case */ function InitApplication($force = false) { if (($force || !in_array($this->currentStep, $this->skipApplicationSteps)) && !isset($this->Application)) { // step is allowed for application usage & it was not initialized in previous step global $start, $debugger, $dbg_options; include_once(FULL_PATH.'/core/kernel/startup.php'); $this->Application =& kApplication::Instance(); $this->toolkit->Application =& kApplication::Instance(); $this->includeModuleConstants(); $this->Application->Init(); $this->Conn =& $this->Application->GetADODBConnection(); $this->toolkit->Conn =& $this->Application->GetADODBConnection(); } } /** * When no modules installed, then pre-include all modules contants, since they are used in unit configs * */ function includeModuleConstants() { $modules = $this->ScanModules(); foreach ($modules as $module_path) { $constants_file = MODULES_PATH . '/' . $module_path . '/constants.php'; if ( file_exists($constants_file) ) { kUtil::includeOnce($constants_file); } } } /** * Show next step screen * * @param string $error_message * @return void */ function Done($error_message = null) { if ( isset($error_message) ) { $this->errorMessage = $error_message; } include_once (FULL_PATH . '/' . REL_PATH . '/install/incs/install.tpl'); if ( isset($this->Application) ) { $this->Application->Done(); } exit; } function ConnectToDatabase() { include_once FULL_PATH . '/core/kernel/db/i_db_connection.php'; include_once FULL_PATH . '/core/kernel/db/db_connection.php'; $required_keys = Array ('DBType', 'DBUser', 'DBName'); foreach ($required_keys as $required_key) { if (!$this->toolkit->systemConfig->get($required_key, 'Database')) { // one of required db connection settings missing -> abort connection return false; } } $this->Conn = new kDBConnection($this->toolkit->systemConfig->get('DBType', 'Database'), Array(&$this, 'DBErrorHandler')); $this->Conn->setup($this->toolkit->systemConfig->getData()); // setup toolkit too $this->toolkit->Conn =& $this->Conn; return !$this->Conn->hasError(); } /** * Checks if core is already installed * * @return bool */ function AlreadyInstalled() { $table_prefix = $this->toolkit->systemConfig->get('TablePrefix', 'Database'); $settings_table = $this->TableExists('ConfigurationValues') ? 'ConfigurationValues' : 'SystemSettings'; $sql = 'SELECT VariableValue FROM ' . $table_prefix . $settings_table . ' WHERE VariableName = "InstallFinished"'; return $this->TableExists($settings_table) && $this->Conn->GetOne($sql); } function CheckDatabase($check_installed = true) { // perform various check type to database specified // 1. user is allowed to connect to database // 2. user has all types of permissions in database // 3. database environment settings met minimum requirements if (mb_strlen($this->toolkit->systemConfig->get('TablePrefix', 'Database')) > 7) { $this->errorMessage = 'Table prefix should not be longer than 7 characters'; return false; } // connect to database $status = $this->ConnectToDatabase(); if ($status) { // if connected, then check if all sql statements work $sql_tests[] = 'DROP TABLE IF EXISTS test_table'; $sql_tests[] = 'CREATE TABLE test_table(test_col mediumint(6))'; $sql_tests[] = 'LOCK TABLES test_table WRITE'; $sql_tests[] = 'INSERT INTO test_table(test_col) VALUES (5)'; $sql_tests[] = 'UPDATE test_table SET test_col = 12'; $sql_tests[] = 'UNLOCK TABLES'; $sql_tests[] = 'ALTER TABLE test_table ADD COLUMN new_col varchar(10)'; $sql_tests[] = 'SELECT * FROM test_table'; $sql_tests[] = 'DELETE FROM test_table'; $sql_tests[] = 'DROP TABLE IF EXISTS test_table'; foreach ($sql_tests as $sql_test) { $this->Conn->Query($sql_test); if ($this->Conn->getErrorCode() != 0) { $status = false; break; } } if ($status) { // if statements work & connection made, then check table existance if ($check_installed && $this->AlreadyInstalled()) { $this->errorMessage = 'An In-Portal Database already exists at this location'; return false; } $requirements_error = Array (); $db_check_results = $this->toolkit->CallPrerequisitesMethod('core/', 'CheckDBRequirements'); if ( !$db_check_results['version'] ) { $requirements_error[] = '- MySQL Version is below 5.0'; } if ( !$db_check_results['packet_size'] ) { $requirements_error[] = '- MySQL Packet Size is below 1 MB'; } if ( $requirements_error ) { $this->errorMessage = 'Connection successful, but following system requirements were not met:
' . implode('
', $requirements_error); return false; } } else { // user has insufficient permissions in database specified $this->errorMessage = 'Permission Error: ('.$this->Conn->getErrorCode().') '.$this->Conn->getErrorMsg(); return false; } } else { // was error while connecting if (!$this->Conn) return false; $this->errorMessage = 'Connection Error: ('.$this->Conn->getErrorCode().') '.$this->Conn->getErrorMsg(); return false; } return true; } /** * Checks if all passed tables exists * * @param string $tables comma separated tables list * @return bool */ function TableExists($tables) { $prefix = $this->toolkit->systemConfig->get('TablePrefix', 'Database'); $all_found = true; $tables = explode(',', $tables); foreach ($tables as $table_name) { $sql = 'SHOW TABLES LIKE "'.$prefix.$table_name.'"'; if (count($this->Conn->Query($sql)) == 0) { $all_found = false; break; } } return $all_found; } /** * Returns modules list found in modules folder * * @return Array */ function ScanModules() { static $modules = null; if ( !isset($modules) ) { // use direct include, because it's called before kApplication::Init, that creates class factory kUtil::includeOnce( KERNEL_PATH . kApplication::MODULE_HELPER_PATH ); $modules_helper = new kModulesHelper(); $modules = $modules_helper->getModules(); } return $modules; } /** * Virtually place module under "modules" folder or it won't be recognized during upgrade to 5.1.0 version * * @param string $name * @param string $path * @param string $version * @return string */ function getModulePath($name, $path, $version) { if ($name == 'Core') { // don't transform path for Core module return $path; } if (!preg_match('/^modules\//', $path)) { // upgrade from 5.0.x/1.0.x to 5.1.x/1.1.x return 'modules/' . $path; } return $path; } /** * Returns list of modules, that can be upgraded * */ function GetUpgradableModules() { $ret = Array (); foreach ($this->Application->ModuleInfo as $module_name => $module_info) { if ($module_name == 'In-Portal') { // don't show In-Portal, because it shares upgrade scripts with Core module continue; } $module_info['Path'] = $this->getModulePath($module_name, $module_info['Path'], $module_info['Version']); $upgrades_file = sprintf(UPGRADES_FILE, $module_info['Path'], 'sql'); if (!file_exists($upgrades_file)) { // no upgrade file continue; } $sqls = file_get_contents($upgrades_file); $versions_found = preg_match_all('/'.VERSION_MARK.'/s', $sqls, $regs); if (!$versions_found) { // upgrades file doesn't contain version definitions continue; } $to_version = end($regs[1]); $this_version = $this->toolkit->ConvertModuleVersion($module_info['Version']); if ($this->toolkit->ConvertModuleVersion($to_version) > $this_version) { // destination version is greather then current foreach ($regs[1] as $version) { if ($this->toolkit->ConvertModuleVersion($version) > $this_version) { $from_version = $version; break; } } $version_info = Array ( 'FromVersion' => $from_version, 'ToVersion' => $to_version, ); $ret[ strtolower($module_name) ] = array_merge($module_info, $version_info); } } return $ret; } /** * Returns content to show for current step * * @return string */ function GetStepBody() { $step_template = FULL_PATH.'/core/install/step_templates/'.$this->currentStep.'.tpl'; if (file_exists($step_template)) { ob_start(); include_once ($step_template); return ob_get_clean(); } return '{step template "'.$this->currentStep.'" missing}'; } /** * Parses step information file, cache result for current step ONLY & return it * * @return Array */ function &_getStepInfo() { static $info = Array('help_title' => null, 'step_title' => null, 'help_body' => null, 'queried' => false); if (!$info['queried']) { $fdata = file_get_contents($this->StepDBFile); $parser = xml_parser_create(); xml_parse_into_struct($parser, $fdata, $values, $index); xml_parser_free($parser); foreach ($index['STEP'] as $section_index) { $step_data =& $values[$section_index]; if ($step_data['attributes']['NAME'] == $this->currentStep) { $info['step_title'] = $step_data['attributes']['TITLE']; if (isset($step_data['attributes']['HELP_TITLE'])) { $info['help_title'] = $step_data['attributes']['HELP_TITLE']; } else { // if help title not set, then use step title $info['help_title'] = $step_data['attributes']['TITLE']; } $info['help_body'] = trim($step_data['value']); break; } } $info['queried'] = true; } return $info; } /** * Returns particular information abou current step * * @param string $info_type * @return string */ function GetStepInfo($info_type) { $step_info =& $this->_getStepInfo(); if (isset($step_info[$info_type])) { return $step_info[$info_type]; } return '{step "'.$this->currentStep.'"; param "'.$info_type.'" missing}'; } /** * Returns passed steps titles * * @param Array $steps * @return Array * @see kInstaller:PrintSteps */ function _getStepTitles($steps) { $fdata = file_get_contents($this->StepDBFile); $parser = xml_parser_create(); xml_parse_into_struct($parser, $fdata, $values, $index); xml_parser_free($parser); $ret = Array (); foreach ($index['STEP'] as $section_index) { $step_data =& $values[$section_index]; if (in_array($step_data['attributes']['NAME'], $steps)) { $ret[ $step_data['attributes']['NAME'] ] = $step_data['attributes']['TITLE']; } } return $ret; } /** * Returns current step number in active steps_preset. * Value can't be cached, because same step can have different number in different presets * * @return int */ function GetStepNumber() { return array_search($this->currentStep, $this->steps[$this->stepsPreset]) + 1; } /** * Returns step name to process next * * @return string */ function GetNextStep() { $next_index = $this->GetStepNumber(); if ($next_index > count($this->steps[$this->stepsPreset]) - 1) { return -1; } return $this->steps[$this->stepsPreset][$next_index]; } /** * Returns step name, that was processed before this step * * @return string */ function GetPreviousStep() { $next_index = $this->GetStepNumber() - 1; if ($next_index < 0) { $next_index = 0; } return $this->steps[$this->stepsPreset][$next_index]; } /** * Prints all steps from active steps preset and highlights current step * * @param string $active_tpl * @param string $passive_tpl * @return string */ function PrintSteps($active_tpl, $passive_tpl) { $ret = ''; $step_titles = $this->_getStepTitles($this->steps[$this->stepsPreset]); foreach ($this->steps[$this->stepsPreset] as $step_name) { $template = $step_name == $this->currentStep ? $active_tpl : $passive_tpl; $ret .= sprintf($template, $step_titles[$step_name]); } return $ret; } /** * Installation error handler for sql errors * * @param int $code * @param string $msg * @param string $sql * @return bool * @access private */ function DBErrorHandler($code, $msg, $sql) { $this->errorMessage = 'Query:
'.htmlspecialchars($sql, ENT_QUOTES, 'UTF-8').'
execution result is error:
['.$code.'] '.$msg; return true; } /** * Installation error handler * * @param int $errno * @param string $errstr * @param string $errfile * @param int $errline * @param Array|string $errcontext */ function ErrorHandler($errno, $errstr, $errfile = '', $errline = 0, $errcontext = '') { if ($errno == E_USER_ERROR) { // only react on user fatal errors $this->Done($errstr); } } /** * Checks, that given button should be visible on current installation step * * @param string $name * @return bool */ function buttonVisible($name) { $button_visibility = Array ( 'continue' => $this->GetNextStep() != -1 || ($this->stepsPreset == 'already_installed'), 'refresh' => in_array($this->currentStep, Array ('sys_requirements', 'check_paths', 'security')), 'back' => in_array($this->currentStep, Array (/*'select_license',*/ 'download_license', 'select_domain')), ); if ($name == 'any') { foreach ($button_visibility as $button_name => $button_visible) { if ($button_visible) { return true; } } return false; } return array_key_exists($name, $button_visibility) ? $button_visibility[$name] : true; } } Property changes on: branches/5.3.x/CREDITS ___________________________________________________________________ Modified: svn:mergeinfo Merged /in-portal/branches/5.2.x/CREDITS:r16067-16123 Property changes on: branches/5.3.x/README ___________________________________________________________________ Modified: svn:mergeinfo Merged /in-portal/branches/5.2.x/README:r16067-16123 Property changes on: branches/5.3.x/index.php ___________________________________________________________________ Modified: svn:mergeinfo Merged /in-portal/branches/5.2.x/index.php:r16067-16123 Index: branches/5.3.x/composer.json =================================================================== --- branches/5.3.x/composer.json (revision 0) +++ branches/5.3.x/composer.json (revision 16124) @@ -0,0 +1,5 @@ +{ + "require-dev": { + "aik099/coding-standard": "dev-in-portal" + } +} Index: branches/5.3.x/tools/configure_profile.php =================================================================== --- branches/5.3.x/tools/configure_profile.php (revision 0) +++ branches/5.3.x/tools/configure_profile.php (revision 16124) @@ -0,0 +1,138 @@ +checkPrerequisites(); + + if ( !chdir(FULL_PATH) ) { + throw new Exception('Unable to change working directory to "' . FULL_PATH . '"'); + } + + $xml = $this->runSvnCommand('info --xml'); + $info = new SimpleXMLElement($xml); + + $url = 'http://www.in-portal.com/rest/profiles.json'; + $url_params = array( + 'name' => $this->getArgument(1, 'in-portal.community'), + 'version' => basename($info->entry->url), + ); + + $json = file_get_contents($url . '?' . http_build_query($url_params)); + $profile_data = json_decode($json, true); + + if ( is_null($profile_data) ) { + throw new Exception('Something went wrong, while queering for profile information. Please try again later.', 104); + } + + if ( isset($profile_data['errors']) ) { + $first_error = reset($profile_data['errors']); + + throw new Exception($first_error['message'], 105); + } + + $svn_property_file = tempnam(sys_get_temp_dir(), 'svn_externals'); + file_put_contents($svn_property_file, $profile_data['svn:externals']); + + $this->runSvnCommand('propset svn:externals -F ' . escapeshellarg($svn_property_file) . ' .'); + echo 'Please run "svn update" on the working copy to finish the process.' . PHP_EOL; + } + + /** + * Checks prerequisites. + * + * @return void + * @throws Exception When one of prerequisites are not met. + */ + protected function checkPrerequisites() + { + if ( PHP_SAPI !== 'cli' ) { + throw new Exception('This script is intended to be used from command-line only !', 100); + } + + try { + $this->runSvnCommand('info ' . escapeshellarg(FULL_PATH)); + } + catch ( Exception $e ) { + throw new Exception('The "' . FULL_PATH . '" must be an SVN working copy or "svn" binary is not in the PATH', 102); + } + + $allow_url_fopen = ini_get('allow_url_fopen'); + + if ( strtolower($allow_url_fopen) === 'off' || (int)$allow_url_fopen === 0 ) { + throw new Exception('Temporarily enable "allow_url_fopen" setting in "php.ini" for script to work', 103); + } + } + + /** + * Executes SVN command and returns the result. + * + * @param string $arguments Command arguments. + * + * @return string + * @throws Exception If something goes wrong. + */ + protected function runSvnCommand($arguments) + { + $exit_code = 0; + $output = array(); + $command = 'svn ' . $arguments . ' 2>&1'; + + exec($command, $output, $exit_code); + + if ( $exit_code !== 0 ) { + throw new Exception('Command "' . $command . '" failed with ' . $exit_code . ' exit code'); + } + + return implode("\n", $output); + } + + /** + * Returns passed argument value. + * + * @param integer $index Argument index. + * @param mixed $default Default value. + * + * @return mixed + */ + protected function getArgument($index, $default = null) + { + if ( $index < $_SERVER['argc'] ) { + return $_SERVER['argv'][$index]; + } + + return $default; + } + +} + + +try { + $workflow = new ConfigureProfileWorkflow(); + $workflow->run(); +} +catch ( Exception $e ) { + echo $e->getMessage().PHP_EOL; + exit($e->getCode()); +} Property changes on: branches/5.3.x/tools/configure_profile.php ___________________________________________________________________ Added: svn:eol-style + LF Property changes on: branches/5.3.x/LICENSES ___________________________________________________________________ Modified: svn:mergeinfo Merged /in-portal/branches/5.2.x/LICENSES:r16067-16123 Property changes on: branches/5.3.x/INSTALL ___________________________________________________________________ Modified: svn:mergeinfo Merged /in-portal/branches/5.2.x/INSTALL:r16067-16123 Property changes on: branches/5.3.x/COPYRIGHT ___________________________________________________________________ Modified: svn:mergeinfo Merged /in-portal/branches/5.2.x/COPYRIGHT:r16067-16123 Index: branches/5.3.x/.arcconfig =================================================================== --- branches/5.3.x/.arcconfig (revision 0) +++ branches/5.3.x/.arcconfig (revision 16124) @@ -0,0 +1,6 @@ +{ + "project.name" : "in-portal", + "repository.callsign": "INP", + "phabricator.uri" : "http://qa.in-portal.org/", + "lint.phpcs.standard" : "vendor/aik099/coding-standard/CodingStandard" +} Index: branches/5.3.x/.arclint =================================================================== --- branches/5.3.x/.arclint (revision 0) +++ branches/5.3.x/.arclint (revision 16124) @@ -0,0 +1,8 @@ +{ + "linters": { + "checkstyle": { + "type": "phpcs", + "include": "(\\.php$)" + } + } +} Property changes on: branches/5.3.x/.htaccess ___________________________________________________________________ Modified: svn:mergeinfo Merged /in-portal/branches/5.2.x/.htaccess:r16067-16123 Index: branches/5.3.x/composer.lock =================================================================== --- branches/5.3.x/composer.lock (revision 0) +++ branches/5.3.x/composer.lock (revision 16124) @@ -0,0 +1,59 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "4c8225aabf36f626240d5615afd5c66b", + "packages": [], + "packages-dev": [ + { + "name": "aik099/coding-standard", + "version": "dev-in-portal", + "source": { + "type": "git", + "url": "https://github.com/aik099/CodingStandard.git", + "reference": "e389596b9b1fc8f67f1cca34a1c8bdd9d85104d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aik099/CodingStandard/zipball/e389596b9b1fc8f67f1cca34a1c8bdd9d85104d0", + "reference": "e389596b9b1fc8f67f1cca34a1c8bdd9d85104d0", + "shasum": "" + }, + "require-dev": { + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Alexander Obuhovich", + "email": "aik.bold@gmail.com" + } + ], + "description": "The PHP_CodeSniffer coding standard I'm using on all of my projects.", + "keywords": [ + "PHP_CodeSniffer", + "codesniffer" + ], + "time": "2014-12-29 12:08:25" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "aik099/coding-standard": 20 + }, + "prefer-stable": false, + "platform": [], + "platform-dev": [] +} Property changes on: branches/5.3.x ___________________________________________________________________ Modified: svn:ignore - .idea atlassian-ide-plugin.xml + testing .buildpath .idea vendor atlassian-ide-plugin.xml .project .settings Modified: svn:mergeinfo Merged /in-portal/branches/5.2.x:r16067-16123