Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F1069654
in-portal
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Jul 20, 5:36 AM
Size
19 KB
Mime Type
text/x-diff
Expires
Tue, Jul 22, 5:36 AM (9 h, 25 m)
Engine
blob
Format
Raw Data
Handle
692551
Attached To
rINP In-Portal
in-portal
View Options
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
Log In to Comment