Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Sun, Jul 20, 5:36 AM

in-portal

Index: branches/RC/core/units/custom_fields/custom_fields_event_handler.php
===================================================================
--- branches/RC/core/units/custom_fields/custom_fields_event_handler.php (revision 11177)
+++ branches/RC/core/units/custom_fields/custom_fields_event_handler.php (revision 11178)
@@ -1,233 +1,238 @@
<?php
class CustomFieldsEventHandler extends kDBEventHandler {
/**
* Changes permission section to one from REQUEST, not from config
*
* @param kEvent $event
*/
function CheckPermission(&$event)
{
$sql = 'SELECT Prefix
FROM '.TABLE_PREFIX.'ItemTypes
WHERE ItemType = '.$this->Conn->qstr( $this->Application->GetVar('cf_type') );
$main_prefix = $this->Conn->GetOne($sql);
$section = $this->Application->getUnitOption($main_prefix.'.custom', 'PermSection');
$event->setEventParam('PermSection', $section);
return parent::CheckPermission($event);
}
/**
* Apply any custom changes to list's sql query
*
* @param kEvent $event
* @access protected
* @see OnListBuild
*/
function SetCustomQuery(&$event)
{
$object =& $event->getObject();
$item_type = $this->Application->GetVar('cf_type');
if (!$item_type) {
$prefix = $event->getEventParam('SourcePrefix');
$item_type = $this->Application->getUnitOption($prefix, 'ItemType');
}
if ($event->Special == 'general') {
$object->addFilter('generaltab_filter', '%1$s.OnGeneralTab = 1');
}
if ($item_type) {
$object->addFilter('itemtype_filter', '%1$s.Type = '.$item_type);
}
if (!($this->Application->isDebugMode() && $this->Application->IsAdmin())) {
$object->addFilter('user_filter', '%1$s.IsSystem = 0');
}
}
/**
* Prevents from duplicate item creation
*
* @param kEvent $event
*/
function OnBeforeItemCreate(&$event)
{
$object =& $event->getObject();
$live_table = $this->Application->getUnitOption($event->Prefix, 'TableName');
$sql = 'SELECT COUNT(*)
FROM '.$live_table.'
WHERE FieldName = '.$this->Conn->qstr($object->GetDBField('FieldName')).' AND Type = '.$object->GetDBField('Type');
$found = $this->Conn->GetOne($sql);
if ($found) {
$event->status = erFAIL;
$object->SetError('FieldName', 'duplicate', 'la_error_CustomExists');
}
}
/**
* Occurse after deleting item, id of deleted item
* is stored as 'id' param of event
*
* @param kEvent $event
* @access public
*/
function OnAfterItemDelete(&$event)
{
$object =& $event->getObject();
$main_prefix = $this->getPrefixByItemType($object->GetDBField('Type'));
$ml_helper =& $this->Application->recallObject('kMultiLanguageHelper');
/* @var $ml_helper kMultiLanguageHelper */
// call main item config to clone cdata table
$this->Application->getUnitOption($main_prefix, 'TableName');
$ml_helper->deleteField($main_prefix.'-cdata', $event->getEventParam('id'));
}
/**
* Get config prefix based on item type
*
* @param unknown_type $item_type
* @return unknown
*/
function getPrefixByItemType($item_type)
{
$sql = 'SELECT Prefix
FROM '.TABLE_PREFIX.'ItemTypes
WHERE ItemType = '.$item_type;
return $this->Conn->GetOne($sql);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnSaveCustomField(&$event)
{
if ($event->MasterEvent->status != erSUCCESS) {
return false;
}
$object =& $event->getObject();
$main_prefix = $this->getPrefixByItemType($object->GetDBField('Type'));
$ml_helper =& $this->Application->recallObject('kMultiLanguageHelper');
/* @var $ml_helper kMultiLanguageHelper */
// call main item config to clone cdata table
$this->Application->getUnitOption($main_prefix, 'TableName');
$ml_helper->createFields($main_prefix.'-cdata');
}
function OnMassDelete(&$event)
{
parent::OnMassDelete($event);
$event->redirect_params = Array('opener' => 's');
}
/**
* Prepare temp tables for creating new item
* but does not create it. Actual create is
* done in OnPreSaveCreated
*
* @param kEvent $event
*/
function OnPreCreate(&$event)
{
parent::OnPreCreate($event);
$object =& $event->getObject();
$object->SetDBField('Type', $this->Application->GetVar('cf_type'));
}
/**
* Prepares ValueList field's value as xml for editing
*
* @param kEvent $event
*/
function OnAfterItemLoad(&$event)
{
parent::OnAfterItemLoad($event);
$object =& $event->getObject();
/* @var $object kDBItem */
if (!in_array($object->GetDBField('ElementType'), $this->_getMultiElementTypes())) {
return ;
}
$custom_field_helper =& $this->Application->recallObject('InpCustomFieldsHelper');
/* @var $custom_field_helper InpCustomFieldsHelper */
- $options = $custom_field_helper->GetValuesHash( $object->GetDBField('ValueList') );
+ $options = $custom_field_helper->GetValuesHash( $object->GetDBField('ValueList'), VALUE_LIST_SEPARATOR, false );
$records = Array ();
+
+ $option_key = key($options);
+ if ($option_key === '' || $option_key == 0) {
+ // remove 1st empty option, and add it later, when options will be saved, but allow string option keys
+ unset($options[$option_key]); // keep index, don't use array_unshift!
+ }
+
foreach ($options as $option_key => $option_title) {
- if ($option_key > 0) {
- $records[] = Array ('OptionKey' => $option_key, 'OptionTitle' => $option_title);
- }
+ $records[] = Array ('OptionKey' => $option_key, 'OptionTitle' => $option_title);
}
$minput_helper =& $this->Application->recallObject('MInputHelper');
/* @var $minput_helper MInputHelper */
$xml = $minput_helper->prepareMInputXML($records, Array ('OptionKey', 'OptionTitle'));
$object->SetDBField('Options', $xml);
}
/**
* Returns custom field element types, that will use minput control
*
* @return unknown
*/
function _getMultiElementTypes()
{
return Array ('select', 'multiselect', 'radio');
}
/**
* Saves minput content to ValueList field
*
* @param kEvent $event
*/
function OnBeforeItemUpdate(&$event)
{
parent::OnBeforeItemUpdate($event);
$object =& $event->getObject();
/* @var $object kDBItem */
if (!in_array($object->GetDBField('ElementType'), $this->_getMultiElementTypes())) {
return ;
}
$minput_helper =& $this->Application->recallObject('MInputHelper');
/* @var $minput_helper MInputHelper */
$ret = $object->GetDBField('ElementType') == 'multiselect' ? Array () : Array ('' => '=+');
$records = $minput_helper->parseMInputXML($object->GetDBField('Options'));
if ($object->GetDBField('SortValues')) {
usort($records, Array (&$this, '_sortValues'));
ksort($records);
}
foreach ($records as $record) {
$ret[] = $record['OptionKey'] . '=+' . $record['OptionTitle'];
}
$object->SetDBField('ValueList', implode(VALUE_LIST_SEPARATOR, $ret));
}
function _sortValues($record_a, $record_b)
{
return strcasecmp($record_a['OptionTitle'], $record_b['OptionTitle']);
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/custom_fields/custom_fields_event_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.17.2.1
\ No newline at end of property
+1.17.2.2
\ No newline at end of property
Index: branches/RC/core/units/general/custom_fields.php
===================================================================
--- branches/RC/core/units/general/custom_fields.php (revision 11177)
+++ branches/RC/core/units/general/custom_fields.php (revision 11178)
@@ -1,106 +1,131 @@
<?php
/**
* Enter description here...
*
* @todo rewrite
*/
class InpCustomFieldsHelper extends kHelper {
/**
* Parses given option string and returns associative array
*
* @param string $values_list
* @param string $separator
+ * @param bool $parse_sqls
* @return Array
*/
- function GetValuesHash($values_list, $separator = VALUE_LIST_SEPARATOR)
+ function GetValuesHash($values_list, $separator = VALUE_LIST_SEPARATOR, $parse_sqls = true)
{
- $optionValuesStr = trim($this->ParseConfigSQL($values_list), $separator);
- if (!$optionValuesStr) {
+ $values_list = trim($this->ParseConfigSQL($values_list, $separator, $parse_sqls), $separator);
+
+ if (!$values_list) {
// no options, then return empty array
return Array();
}
- $optionValuesTmp = explode($separator, $optionValuesStr);
+ $optionValuesTmp = explode($separator, $values_list);
$optionValues = Array();
- if (substr_count($optionValuesStr, '=') != count($optionValuesTmp)) {
- trigger_error('Invalid symbol in ValueList field [' . substr($optionValuesStr, 0, 100) . ' ...]' , E_USER_NOTICE);
+ if (substr_count($values_list, '=') != count($optionValuesTmp)) {
+ if ($this->Application->isDebugMode()) {
+ $this->Application->Debugger->appendTrace();
+ }
+
+ trigger_error('Invalid symbol in ValueList field [' . substr($values_list, 0, 100) . ' ...]' , E_USER_NOTICE);
return Array ();
}
foreach ($optionValuesTmp as $optionValue) {
- list($key, $val) = explode('=', $optionValue);
+ list ($key, $val) = explode('=', $optionValue);
$val = (substr($val,0,1) == '+') ? substr($val, 1) : $this->Application->Phrase($val);
+
+ if (substr($key, 0, 3) == 'SQL') {
+ $val = base64_decode( str_replace('_', '=', $val) );
+ }
$optionValues[$key] = $val;
}
return $optionValues;
}
/**
* Replace SQL's in valueList with appropriate queried values
*
* @param string $valueString
+ * @param string $separator
* @return string
* @todo Apply refactoring to embedded vars stuff
*/
- function ParseConfigSQL($valueString)
+ function ParseConfigSQL($valueString, $separator = VALUE_LIST_SEPARATOR, $parse_sqls = true)
{
$string = trim( str_replace(Array('<PREFIX>', '%3$s'), Array (TABLE_PREFIX, $this->Application->GetVar('m_lang')), $valueString) );
preg_match_all("|\{(.*)\}|U", $string, $embedded_vars, PREG_SET_ORDER);
/*
<SQL> in ValueList now can use globally available variables.
Usage: {$_POST['variable']|what to output if $_POST['variable'] is set}
e.g. $_POST['variable']='Hello'
Will output: what to output if Hello is set
*/
if ($embedded_vars) {
for ($i = 0; $i < count($embedded_vars); $i++) {
$embedded_var = $embedded_vars[$i][1];
$embedded_var_src = $embedded_vars[$i][0];
list($var_name, $pattern) = explode('|', $embedded_var);
eval('$var_value = (isset('.$var_name.')?'.$var_name.':false);');
if ($var_value !== false) {
$pattern = str_replace($var_name, $var_value, $pattern);
$string = str_replace($embedded_var_src, $pattern, $string);
}
else {
$string = str_replace($embedded_var_src, '', $string);
}
}
}
if (preg_match_all('/<SQL([+]{0,1})>(.*?)<\/SQL>/', $string, $regs)) {
$i = 0;
$sql_count = count($regs[0]);
while ($i < $sql_count) {
- $string = str_replace('<SQL'.$regs[1][$i].'>'.$regs[2][$i].'</SQL>', $this->QueryConfigSQL($regs[2][$i], $regs[1][$i]), $string);
+ if ($parse_sqls) {
+ $replacement = $this->_queryConfigSQL($regs[2][$i], $regs[1][$i], $separator);
+ }
+ else {
+ $sql = base64_encode('<SQL'.$regs[1][$i].'>'.$regs[2][$i].'</SQL>');
+ $replacement = 'SQL' . $i . '=+' . str_replace('=', '_', $sql);
+ }
+
+ $string = str_replace('<SQL'.$regs[1][$i].'>'.$regs[2][$i].'</SQL>', $replacement, $string);
$i++;
}
- $string = preg_replace('/(,){2,}/', ',', $string); // trim trailing commas inside string
+
+ $string = preg_replace('/[' . preg_quote($separator, '/') . ']+/', $separator, $string); // trim trailing separators inside string
}
return $string;
}
- function QueryConfigSQL($sql, $plus = '')
+ /**
+ * Transforms given sql into value list string
+ *
+ * @param string $sql
+ * @param string $plus
+ * @param string $separator
+ * @return string
+ */
+ function _queryConfigSQL($sql, $plus = '', $separator = VALUE_LIST_SEPARATOR)
{
- $valArray = $this->Conn->Query($sql);
- for($i=0; $i<sizeof($valArray); $i++)
- {
- $valArray[$i] = $valArray[$i]['OptionValue'].'='.$plus.$valArray[$i]['OptionName'];
- $valArray[$i] = str_replace(',', ';', $valArray[$i]);
+ $values = $this->Conn->Query($sql);
+ foreach ($values as $index => $value) {
+ $values[$index] = $value['OptionValue'] . '=' . $plus . $value['OptionName'];
}
- return implode(',', $valArray);
- }
-
+ return implode($separator, $values);
+ }
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/general/custom_fields.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.9.2.3
\ No newline at end of property
+1.9.2.4
\ No newline at end of property
Index: branches/RC/core/admin_templates/custom_fields/custom_fields_edit.tpl
===================================================================
--- branches/RC/core/admin_templates/custom_fields/custom_fields_edit.tpl (revision 11177)
+++ branches/RC/core/admin_templates/custom_fields/custom_fields_edit.tpl (revision 11178)
@@ -1,152 +1,152 @@
<inp2:m_RequireLogin perm_event="cf:OnLoad" system="1"/>
<inp2:m_include t="incs/header" nobody="yes"/>
<body topmargin="0" leftmargin="8" marginheight="0" marginwidth="8" bgcolor="#FFFFFF">
-<inp2:m_RenderElement name="section_header" prefix="cf" icon="icon46_settings_custom" title="!la_title_CustomFields!"/>
+<inp2:m_RenderElement name="section_header" prefix="cf" module="in-portal" icon="icon46_settings_custom" title="!la_title_CustomFields!"/>
-<inp2:m_RenderElement name="blue_bar" prefix="cf" title_preset="custom_fields_edit" module="in-portal" icon="icon46_settings_custom"/>
+<inp2:m_RenderElement name="blue_bar" prefix="cf" title_preset="custom_fields_edit" icon="icon46_settings_custom"/>
<!-- ToolBar --->
<table class="toolbar" height="30" cellspacing="0" cellpadding="0" width="100%" border="0">
<tbody>
<tr>
<td>
<script type="text/javascript">
a_toolbar = new ToolBar();
a_toolbar.AddButton( new ToolBarButton('select', '<inp2:m_phrase label="la_ToolTip_Save" escape="1"/>', function() {
submit_event('cf','<inp2:cf_SaveEvent/>');
}
) );
a_toolbar.AddButton( new ToolBarButton('cancel', '<inp2:m_phrase label="la_ToolTip_Cancel" escape="1"/>', function() {
submit_event('cf','OnCancelEdit');
}
) );
a_toolbar.AddButton( new ToolBarSeparator('sep1') );
a_toolbar.AddButton( new ToolBarButton('prev', '<inp2:m_phrase label="la_ToolTip_Prev" escape="1"/>', function() {
go_to_id('cf', '<inp2:cf_PrevId/>');
}
) );
a_toolbar.AddButton( new ToolBarButton('next', '<inp2:m_phrase label="la_ToolTip_Next" escape="1"/>', function() {
go_to_id('cf', '<inp2:cf_NextId/>');
}
) );
a_toolbar.Render();
<inp2:m_if check="cf_IsSingle" >
a_toolbar.HideButton('prev');
a_toolbar.HideButton('next');
a_toolbar.HideButton('sep1');
<inp2:m_else/>
<inp2:m_if check="cf_IsLast" >
a_toolbar.DisableButton('next');
</inp2:m_if>
<inp2:m_if check="cf_IsFirst" >
a_toolbar.DisableButton('prev');
</inp2:m_if>
</inp2:m_if>
</script>
</td>
</tr>
</tbody>
</table>
<inp2:m_RenderElement name="inp_edit_hidden" prefix="cf" field="Type" db="db"/>
<table width="100%" border="0" cellspacing="0" cellpadding="4" class="bordered">
<inp2:m_RenderElement name="subsection" title="!la_section_General!"/>
<inp2:m_RenderElement name="inp_id_label" prefix="cf" field="CustomFieldId" title="!la_prompt_FieldId!"/>
<inp2:m_RenderElement name="inp_edit_box" prefix="cf" field="FieldName" title="!la_prompt_FieldName!" size="40"/>
<inp2:m_RenderElement name="inp_edit_box" prefix="cf" field="FieldLabel" title="!la_prompt_FieldLabel!" size="40"/>
<inp2:m_RenderElement name="inp_edit_checkbox" prefix="cf" field="MultiLingual" title="!la_fld_MultiLingual!"/>
<inp2:m_RenderElement name="subsection" title="!la_tab_AdminUI!"/>
<inp2:m_RenderElement name="inp_edit_checkbox" prefix="cf" field="OnGeneralTab" title="!la_prompt_showgeneraltab!"/>
<inp2:m_RenderElement name="inp_edit_box" prefix="cf" field="Heading" title="!la_prompt_heading!" size="40"/>
<inp2:m_RenderElement name="inp_edit_box" prefix="cf" field="Prompt" title="!la_prompt_FieldPrompt!" size="40"/>
<inp2:m_RenderElement name="inp_edit_options" prefix="cf" field="ElementType" title="!la_prompt_InputType!" size="20" onchange="update_layout();"/>
<inp2:m_if check="cf_Field" name="ElementType" equals_to="select|multiselect|radio" db="db" inverse="inverse">
<inp2:m_RenderElement name="inp_edit_box" prefix="cf" field="ValueList" title="!la_prompt_valuelist!" size="40"/>
</inp2:m_if>
<inp2:m_RenderElement name="inp_edit_box" prefix="cf" field="DefaultValue" title="la_prompt_Default"/>
<inp2:m_RenderElement name="inp_edit_box" prefix="cf" field="DisplayOrder" title="!la_field_displayorder!" size="10"/>
<inp2:m_if check="m_IsDebugMode">
<inp2:m_RenderElement name="inp_edit_checkbox" prefix="cf" field="IsSystem" title="!la_fld_IsSystem!"/>
</inp2:m_if>
<inp2:m_if check="cf_Field" name="ElementType" equals_to="select|multiselect|radio" db="db">
<inp2:m_RenderElement name="subsection" title="la_section_Values"/>
<inp2:m_RenderElement name="inp_edit_checkbox" prefix="cf" field="SortValues" title="la_fld_SortValues"/>
<inp2:m_RenderElement name="inp_edit_hidden" prefix="cf" field="OptionKey"/>
<inp2:m_RenderElement name="inp_edit_box" prefix="cf" field="OptionTitle" title="la_fld_OptionTitle" size="60"/>
<inp2:m_RenderElement name="inp_edit_minput" prefix="cf" field="Options" title="la_fld_Options" format="#OptionTitle# (#OptionKey#)" style="width: 600px; height: 500px;"/>
</inp2:m_if>
</table>
<inp2:m_if check="cf_Field" name="ElementType" equals_to="select|multiselect|radio" db="db">
<script type="text/javascript">
Options.registerControl('OptionKey', 'text', false);
Options.registerControl('OptionTitle', 'text', true);
Options.LoadValues();
Options.getControlValue = function ($field) {
var $value = this.getControl($field).value;
if ($field == 'OptionKey' && !$value) {
$options = this.getControl(this.FieldName, 'minput').options;
if ($options.length) {
var $i = 0;
var $max_option_key = 0;
while ($i < $options.length) {
if (parseInt(this.Records[ $options[$i].value ]['OptionKey']) > $max_option_key) {
$max_option_key = parseInt(this.Records[ $options[$i].value ]['OptionKey']);
}
$i++;
}
return $max_option_key + 1;
}
// when no this will be 1st record in list use 1
return 1;
}
return $value;
}
Options.compareRecords = function($record_a, $record_b) {
// compare by option title only, it's id doesn't matter
return $record_a['OptionTitle'].toLowerCase() == $record_b['OptionTitle'].toLowerCase();
}
</script>
</inp2:m_if>
<script type="text/javascript">
function update_layout() {
var $last_element_type = '<inp2:cf_Field name="ElementType" db="db" js_escape="1"/>';
var $element_type = document.getElementById('<inp2:cf_InputName name="ElementType" js_escape="1"/>').value;
// value is changed from ml supported to normal or otherwise
if (canHaveMultipleValues($last_element_type) != canHaveMultipleValues($element_type)) {
submit_event('cf', 'OnPreSave');
}
}
function canHaveMultipleValues($element_type) {
var $element_types = ['select', 'multiselect', 'radio'];
return $element_types.indexOf($element_type) != -1;
}
</script>
<inp2:m_include t="incs/footer"/>
Property changes on: branches/RC/core/admin_templates/custom_fields/custom_fields_edit.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.5.2.3
\ No newline at end of property
+1.5.2.4
\ No newline at end of property

Event Timeline