Files
2026-05-13 09:43:32 -04:00

1156 lines
28 KiB
PHP

<?php
include_once dirname(__FILE__) . '/' . '../component.php';
include_once dirname(__FILE__) . '/' . '../utils/file_utils.php';
include_once dirname(__FILE__) . '/' . '../utils/string_utils.php';
include_once dirname(__FILE__) . '/' . '../utils/html_utils.php';
include_once dirname(__FILE__) . '/' . 'validators.php';
// require_once 'components/component.php';
// require_once 'components/utils/file_utils.php';
// require_once 'components/utils/string_utils.php';
// require_once 'components/utils/html_utils.php';
// require_once 'components/editors/validators.php';
/**
* @property mixed GetViewData
*/
abstract class CustomEditor extends Component {
/** @var null|string */
private $customAttributes;
/** @var boolean */
private $readOnly;
/** @var \SuperGlobals */
private $superGlobals;
/** @var string */
private $fieldName;
/** @var \ValidatorCollection */
private $validators;
/**
* @param string $name
* @param string $customAttributes
*/
public function __construct($name, $customAttributes = null) {
parent::__construct($name);
$this->customAttributes = $customAttributes;
$this->readOnly = false;
$this->superGlobals = GetApplication()->GetSuperGlobals();
$this->validators = new ValidatorCollection();
$this->fieldName = null;
}
/**
* @return bool
*/
protected function SuppressRequiredValidation() {
return false;
}
/**
* @return string
*/
public final function GetValidationAttributes() {
return $this->GetValidatorCollection()->GetInputAttributes($this->SuppressRequiredValidation());
}
/**
* @return ValidatorCollection
*/
public final function GetValidatorCollection() {
return $this->validators;
}
protected final function GetSuperGlobals() {
return $this->superGlobals;
}
/**
* @param Renderer $renderer
* @return void
*/
public function Accept(Renderer $renderer) {
assert(false);
}
/**
* @param boolean $valueChanged
* @return string
*/
public function ExtractsValueFromPost(&$valueChanged) {
$valueChanged = false;
return '';
}
/**
* @abstract
* @return mixed
*/
public abstract function GetValue();
/**
* @abstract
* @param mixed $value
* @return void
*/
public abstract function SetValue($value);
/**
* @return string
*/
public function GetFieldName() {
return $this->fieldName;
}
/**
* @param string $value
* @return void
*/
public function SetFieldName($value) {
$this->fieldName = $value;
}
/**
* @return boolean
*/
public function GetReadOnly() {
return $this->readOnly;
}
/**
* @param boolean $value
* @return void
*/
public function SetReadOnly($value) {
$this->readOnly = $value;
}
/**
* @param string $value
* @return void
*/
public function SetCustomAttributes($value) {
$this->customAttributes = $value;
}
/**
* @return null|string
*/
public function GetCustomAttributes() {
return $this->customAttributes;
}
/**
* @return array
*/
public final function GetViewData() {
return ArrayUtils::Merge(
array(
'ReadOnly' => $this->GetReadOnly()
),
$this->DoGetViewData()
);
}
protected function DoGetViewData() {
return array();
}
}
class TextAreaEdit extends CustomEditor {
private $value;
private $columnCount;
private $rowCount;
private $allowHtmlCharacters = true;
public function __construct($name, $columnCount = null, $rowCount = null, $customAttributes = null) {
parent::__construct($name, $customAttributes);
$this->columnCount = $columnCount;
$this->rowCount = $rowCount;
}
public function GetValue() {
return $this->value;
}
public function SetValue($value) {
$this->value = $value;
}
#region Editor options
public function SetColumnCount($value) {
$this->columnCount = $value;
}
public function GetColumnCount() {
return $this->columnCount;
}
public function SetRowCount($value) {
$this->rowCount = $value;
}
public function GetRowCount() {
return $this->rowCount;
}
public function GetAllowHtmlCharacters() {
return $this->allowHtmlCharacters;
}
public function SetAllowHtmlCharacters($value) {
$this->allowHtmlCharacters = $value;
}
#endregion
public function ExtractsValueFromPost(&$valueChanged) {
if (GetApplication()->IsPOSTValueSet($this->GetName())) {
$valueChanged = true;
$value = GetApplication()->GetPOSTValue($this->GetName());
if (isset($value) && !$this->allowHtmlCharacters)
$value = htmlspecialchars($value, ENT_QUOTES);
return $value;
} else {
$valueChanged = false;
return null;
}
}
public function Accept(Renderer $renderer) {
$renderer->RenderTextAreaEdit($this);
}
}
class TextEdit extends CustomEditor {
private $value;
private $size = null;
private $maxLength = null;
private $allowHtmlCharacters = true;
private $passwordMode;
public function __construct($name, $size = null, $maxLength = null, $customAttributes = null) {
parent::__construct($name, $customAttributes);
$this->size = $size;
$this->maxLength = $maxLength;
$this->passwordMode = false;
}
public function SetSize($value) {
$this->size = $value;
}
public function GetSize() {
return $this->size;
}
public function SetMaxLength($value) {
$this->maxLength = $value;
}
public function GetMaxLength() {
return $this->maxLength;
}
public function GetValue() {
return $this->value;
}
public function SetValue($value) {
$this->value = $value;
}
public function GetPasswordMode() {
return $this->passwordMode;
}
public function SetPasswordMode($value) {
$this->passwordMode = $value;
}
public function GetHTMLValue() {
return str_replace('"', '&quot;', $this->value);
}
public function GetAllowHtmlCharacters() {
return $this->allowHtmlCharacters;
}
public function SetAllowHtmlCharacters($value) {
$this->allowHtmlCharacters = $value;
}
public function ExtractsValueFromPost(&$valueChanged) {
if (GetApplication()->IsPOSTValueSet($this->GetName())) {
$valueChanged = true;
$value = GetApplication()->GetPOSTValue($this->GetName());
if (isset($value) && !$this->allowHtmlCharacters)
$value = htmlspecialchars($value, ENT_QUOTES);
return $value;
} else {
$valueChanged = false;
return null;
}
}
public function Accept(Renderer $Renderer) {
$Renderer->RenderTextEdit($this);
}
private function GetControllerAttributes() {
$result = new AttributesBuilder();
$result->AddAttrValue('data-editor', 'true');
$result->AddAttrValue('data-editor-class', 'TextEdit');
$result->AddAttrValue('data-field-name', $this->GetFieldName());
$result->AddAttrValue('data-editable', 'true');
return $result->GetAsString();
}
private function GetAdditionalAttributes() {
$result = new AttributesBuilder();
$result->AddAttrValue('type', $this->GetPasswordMode() ? 'password' : 'text');
if ($this->GetMaxLength() != null)
$result->AddAttrValue('maxlength', $this->GetMaxLength());
if ($this->GetSize() != null)
$result->AddAttrValue('size', $this->GetSize());
return $result->GetAsString();
}
public function DoGetViewData() {
return array(
'ControllerAttributes' => $this->GetControllerAttributes(),
'AdditionalAttributes' => $this->GetAdditionalAttributes(),
'Name' => $this->GetName(),
'DisplayValue' => $this->GetHTMLValue(),
'Value' => $this->GetValue(),
'CustomStyle' => $this->GetCustomAttributes(),
'PasswordMode' => $this->GetPasswordMode()
);
}
}
class TimeEdit extends CustomEditor {
private $value;
public function __construct($name) {
parent::__construct($name);
}
public function GetValue() {
return $this->value;
}
public function SetValue($value) {
$this->value = $value;
}
public function Accept(Renderer $Renderer) {
$Renderer->RenderTimeEdit($this);
}
public function ExtractsValueFromPost(&$valueChanged) {
if (GetApplication()->IsPOSTValueSet($this->GetName())) {
$valueChanged = true;
$value = GetApplication()->GetPOSTValue($this->GetName());
if (StringUtils::IsNullOrEmpty($value))
return null;
else
return GetApplication()->GetPOSTValue($this->GetName());
} else {
$valueChanged = false;
return null;
}
}
}
class MaskedEdit extends CustomEditor {
private $value;
private $mask;
private $hint;
/**
* @param string $name
* @param string $mask see http://digitalbush.com/projects/masked-input-plugin/ for details
* @param string $hint
*/
public function __construct($name, $mask, $hint = '') {
parent::__construct($name, null);
$this->mask = $mask;
$this->hint = $hint;
}
public function GetValue() {
return $this->value;
}
public function SetValue($value) {
$this->value = $value;
}
public function Accept(Renderer $Renderer) {
$Renderer->RenderMaskedEdit($this);
}
public function ExtractsValueFromPost(&$valueChanged) {
if (GetApplication()->IsPOSTValueSet($this->GetName())) {
$valueChanged = true;
return GetApplication()->GetPOSTValue($this->GetName());
} else {
$valueChanged = false;
return null;
}
}
public function GetMask() {
return $this->mask;
}
public function GetHint() {
return $this->hint;
}
}
class SpinEdit extends CustomEditor {
private $value;
private $useConstraints = false;
private $minValue;
private $maxValue;
public function GetMaxValue() {
return $this->maxValue;
}
public function SetMaxValue($value) {
$this->maxValue = $value;
}
public function GetMinValue() {
return $this->minValue;
}
public function SetMinValue($value) {
$this->minValue = $value;
}
public function GetValue() {
return $this->value;
}
public function SetValue($value) {
$this->value = $value;
}
public function SetUseConstraints($value) {
$this->useConstraints = $value;
}
public function GetUseConstraints() {
return $this->useConstraints;
}
public function ExtractsValueFromPost(&$valueChanged) {
if (GetApplication()->IsPOSTValueSet($this->GetName())) {
$valueChanged = true;
return GetApplication()->GetPOSTValue($this->GetName());
} else {
$valueChanged = false;
return null;
}
}
public function Accept(Renderer $Renderer) {
$Renderer->RenderSpinEdit($this);
}
}
class CheckBox extends CustomEditor {
private $value;
public function GetValue() {
return $this->value;
}
public function SetValue($value) {
$this->value = $value;
}
protected function SuppressRequiredValidation() {
return true;
}
public function ExtractsValueFromPost(&$valueChanged) {
if ($this->GetReadOnly()) {
$valueChanged = false;
return null;
} else {
$valueChanged = true;
return GetApplication()->IsPOSTValueSet($this->GetName()) ? '1' : '0';
}
}
public function Accept(Renderer $renderer) {
$renderer->RenderCheckBox($this);
}
public function Checked() {
return (isset($this->value) && !empty($this->value));
}
}
class DateTimeEdit extends CustomEditor {
/** @var SMDateTime */
private $value;
private $showsTime;
private $format;
private $firstDayOfWeek;
public function __construct($name, $showsTime = false, $format = null, $firstDayOfWeek = 0) {
parent::__construct($name);
$this->showsTime = $showsTime;
if (!isset($format))
$this->format = $this->showsTime ? 'Y-m-d H:i:s' : 'Y-m-d';
else
$this->format = $format;
$this->firstDayOfWeek = $firstDayOfWeek;
}
public function GetFirstDayOfWeek() {
return $this->firstDayOfWeek;
}
public function GetValue() {
if (isset($this->value))
return $this->value->ToString($this->format);
else
return '';
}
public function SetValue($value) {
if (!StringUtils::IsNullOrEmpty($value))
$this->value = SMDateTime::Parse($value, $this->showsTime ? 'Y-m-d H:i:s' : 'Y-m-d');
else
$this->value = null;
}
public function GetFormat() {
return DateFormatToOSFormat($this->format);
}
public function SetFormat($value) {
$this->format = $value;
}
public function GetShowsTime() {
return $this->showsTime;
}
public function SetShowsTime($value) {
$this->showsTime = $value;
}
public function Accept(Renderer $renderer) {
$renderer->RenderDateTimeEdit($this);
}
public function ExtractsValueFromPost(&$valueChanged) {
if (GetApplication()->IsPOSTValueSet($this->GetName())) {
$valueChanged = true;
$value = GetApplication()->GetPOSTValue($this->GetName());
if ($value == '')
return null;
else
return $value;
} else {
$valueChanged = false;
return null;
}
}
}
class ComboBox extends CustomEditor {
private $values;
private $selectedValue;
private $emptyValue;
//
private $mfuValues;
private $preparedMfuValues;
private $displayValues;
public function __construct($name, $emptyValue = '') {
parent::__construct($name);
$this->values = array();
$this->selectedValue = null;
$this->emptyValue = $emptyValue;
$this->values[''] = $emptyValue;
$this->displayValues = array();
$this->mfuValues = array();
$this->preparedMfuValues = null;
}
public function GetSelectedValue() {
return $this->selectedValue;
}
public function SetSelectedValue($selectedValue) {
$this->selectedValue = $selectedValue;
}
public function AddValue($value, $name) {
$this->values[$value] = $name;
$this->displayValues[$value] = $name;
}
public function GetValues() {
return $this->values;
}
public function GetDisplayValues() {
return $this->displayValues;
}
public function ShowEmptyValue() {
return true;
}
public function GetEmptyValue() {
return $this->emptyValue;
}
public function AddMFUValue($value) {
$this->mfuValues[] = $value;
}
private function PrepareMFUValues() {
$this->preparedMfuValues = array();
foreach ($this->mfuValues as $mfuValue) {
if (array_key_exists($mfuValue, $this->values))
$this->preparedMfuValues[$mfuValue] = $this->values[$mfuValue];
elseif (in_array($mfuValue, $this->values)) {
$key = array_search($mfuValue, $this->values);
$this->preparedMfuValues[$key] = $mfuValue;
}
}
}
public function HasMFUValues() {
return count($this->mfuValues) > 0;
}
public function GetMFUValues() {
if ($this->HasMFUValues()) {
if (!isset($this->preparedMfuValues))
$this->PrepareMFUValues();
return $this->preparedMfuValues;
} else
return array();
}
public function GetValue() {
return $this->selectedValue;
}
public function SetValue($value) {
$this->selectedValue = $value;
}
protected function DoSetAllowNullValue($value) {
if ($value) {
$this->values[''] = $this->emptyValue;
} else {
if (isset($this->values['']))
unset($this->values['']);
}
}
public function ExtractsValueFromPost(&$valueChanged) {
if (GetApplication()->IsPOSTValueSet($this->GetName())) {
$valueChanged = true;
$value = GetApplication()->GetPOSTValue($this->GetName());
if ($value == '')
return null;
else
return $value;
} else {
$valueChanged = false;
return null;
}
}
public function CanSetupNullValues() {
return false;
}
public function Accept(Renderer $Renderer) {
$Renderer->RenderComboBox($this);
}
}
class AutocomleteComboBox extends CustomEditor {
/** @var string */
private $value;
/** @var string */
private $displayValue;
/** @var string */
private $handlerName;
/** @var string */
private $size;
/** @var \LinkBuilder */
private $linkBuilder;
/**
* @param string $name
* @param LinkBuilder $linkBuilder
*/
public function __construct($name, LinkBuilder $linkBuilder) {
parent::__construct($name);
$this->size = '260px';
$this->linkBuilder = $linkBuilder;
}
/**
* @return string
*/
public function GetDisplayValue() {
return $this->displayValue;
}
/**
* @param string $value
* @return void
*/
public function SetDisplayValue($value) {
$this->displayValue = $value;
}
/**
* @return string
*/
public function GetValue() {
return $this->value;
}
/**
* @param string $value
* @return void
*/
public function SetValue($value) {
$this->value = $value;
}
#region Options
/**
* @return string
*/
public function GetSize() {
return $this->size;
}
/**
* @param string $value
* @return void
*/
public function SetSize($value) {
$this->size = $value;
}
#endregion
public function ExtractsValueFromPost(&$valueChanged) {
if ($this->GetSuperGlobals()->IsPostValueSet($this->GetName())) {
$valueChanged = true;
return $this->GetSuperGlobals()->GetPostValue($this->GetName());
} else {
$valueChanged = false;
return null;
}
}
/**
* @param string $value
* @return void
*/
public function SetHandlerName($value) {
$this->handlerName = $value;
}
/**
* @return string
*/
public function GetHandlerName() {
return $this->handlerName;
}
/**
* @return string
*/
public function GetDataUrl() {
$linkBuilder = $this->linkBuilder->CloneLinkBuilder();
$linkBuilder->AddParameter(OPERATION_HTTPHANDLER_NAME_PARAMNAME, $this->GetHandlerName());
return $linkBuilder->GetLink();
}
/**
* @param Renderer $Renderer
* @return void
*/
public function Accept(Renderer $Renderer) {
$Renderer->RenderAutocompleteComboBox($this);
}
/**
* @return bool
*/
public function CanSetupNullValues() {
return true;
}
/**
* @return bool
*/
public function GetSetToNullFromPost() {
if (GetApplication()->IsPOSTValueSet($this->GetName()))
return GetApplication()->GetPOSTValue($this->GetName()) == '';
return true;
}
}
class RadioEdit extends CustomEditor {
/** @var array */
private $values;
/** @var null|string */
private $selectedValue;
/** @var int */
private $displayMode;
const StackedMode = 0;
const InlineMode = 1;
public function __construct($name) {
parent::__construct($name);
$this->values = array();
$this->selectedValue = null;
$this->displayMode = self::StackedMode;
}
public function GetSelectedValue() {
return $this->selectedValue;
}
public function SetSelectedValue($selectedValue) {
$this->selectedValue = $selectedValue;
}
public function AddValue($value, $name) {
$this->values[$value] = $name;
}
public function GetValues() {
return $this->values;
}
public function GetValue() {
return $this->selectedValue;
}
public function SetValue($value) {
$this->selectedValue = $value;
}
public function GetDisplayMode() {
return $this->displayMode;
}
public function SetDisplayMode($value) {
$this->displayMode = $value;
}
/** @return bool */
public function IsInlineMode() {
return $this->displayMode == self::InlineMode;
}
public function ExtractsValueFromPost(&$valueChanged) {
if (GetApplication()->IsPOSTValueSet($this->GetName())) {
$valueChanged = true;
return GetApplication()->GetPOSTValue($this->GetName());
} else {
$valueChanged = false;
return null;
}
}
public function Accept(Renderer $Renderer) {
$Renderer->RenderRadioEdit($this);
}
}
class CheckBoxGroup extends CustomEditor {
/** @var array */
private $values;
/** @var array */
private $selectedValues;
/** @var int */
private $displayMode;
const StackedMode = 0;
const InlineMode = 1;
/** @param string $name */
public function __construct($name) {
parent::__construct($name);
$this->values = array();
$this->selectedValues = array();
$this->displayMode = self::StackedMode;
}
/**
* @param string $value
* @return bool
*/
public function IsValueSelected($value) {
return in_array($value, $this->selectedValues);
}
/**
* @param string $value
* @param string $name
*/
public function AddValue($value, $name) {
$this->values[$value] = $name;
}
/**
* @return array
*/
public function GetValues() {
return $this->values;
}
/**
* @return mixed|string
*/
public function GetValue() {
$result = '';
foreach ($this->selectedValues as $selectedValue)
AddStr($result, $selectedValue, ',');
return $result;
}
/**
* @param mixed $value
*/
public function SetValue($value) {
$this->selectedValues = explode(',', $value);
}
public function GetDisplayMode() {
return $this->displayMode;
}
public function SetDisplayMode($value) {
$this->displayMode = $value;
}
/** @return bool */
public function IsInlineMode() {
return $this->displayMode == self::InlineMode;
}
/**
* @param bool $valueChanged
* @return string
*/
public function ExtractsValueFromPost(&$valueChanged) {
if (GetApplication()->IsPOSTValueSet($this->GetName())) {
$valueChanged = true;
$valuesArray = GetApplication()->GetPOSTValue($this->GetName());
$result = '';
foreach ($valuesArray as $value)
AddStr($result, $value, ',');
return $result;
} else {
$valueChanged = true;
return '';
}
}
public function Accept(Renderer $Renderer) {
$Renderer->RenderCheckBoxGroup($this);
}
}
class ImageUploader extends CustomEditor {
private $showImage;
private $imageLink;
public function __construct($name) {
parent::__construct($name);
$this->showImage = false;
}
public function GetShowImage() {
return $this->showImage;
}
public function SetShowImage($value) {
$this->showImage = $value;
}
public function GetLink() {
return $this->imageLink;
}
public function SetLink($value) {
$this->imageLink = $value;
}
public function ExtractImageActionFromPost() {
if (GetApplication()->IsPOSTValueSet($this->GetName() . "_action"))
return GetApplication()->GetPOSTValue($this->GetName() . "_action");
else
return KEEP_IMAGE_ACTION;
}
public function GetValue() {
return null;
}
public function SetValue($value) {
;
}
public function ExtractsValueFromPost(&$valueChanged) {
$action = $this->ExtractImageActionFromPost();
if ($action == REMOVE_IMAGE_ACTION) {
$valueChanged = true;
return null;
} elseif ($action == REPLACE_IMAGE_ACTION) {
$filename = $_FILES[$this->GetName() . "_filename"]["tmp_name"];
$valueChanged = true;
return $filename;
} else {
$valueChanged = false;
return null;
}
}
public function ExtractFileTypeFromPost() {
$action = $this->ExtractImageActionFromPost();
if ($action == REMOVE_IMAGE_ACTION)
return null;
elseif ($action == REPLACE_IMAGE_ACTION) {
$clientFileName = $_FILES[$this->GetName() . "_filename"]["name"];
return Path::GetFileExtension($clientFileName);
} else
return null;
}
public function ExtractFileNameFromPost() {
$action = $this->ExtractImageActionFromPost();
if ($action == REMOVE_IMAGE_ACTION)
return null;
elseif ($action == REPLACE_IMAGE_ACTION) {
$clientFileName = $_FILES[$this->GetName() . "_filename"]["name"];
return Path::GetFileTitle($clientFileName);
} else
return null;
}
public function ExtractFileSizeFromPost() {
$action = GetApplication()->GetPOSTValue($this->GetName() . "_action");
$fileSize = $_FILES[$this->GetName() . "_filename"]["size"];
if ($action == REMOVE_IMAGE_ACTION)
return null;
elseif ($action == REPLACE_IMAGE_ACTION)
return $fileSize; else
return null;
}
public function Accept(Renderer $renderer) {
$renderer->RenderImageUploader($this);
}
}
class HtmlWysiwygEditor extends CustomEditor {
private $value;
private $allowColorControls;
private $columnCount;
private $rowCount;
public function __construct($name, $customAttributes = null) {
parent::__construct($name, $customAttributes);
$this->allowColorControls = false;
}
public function GetValue() {
return $this->value;
}
public function SetValue($value) {
$this->value = $value;
}
public function SetColumnCount($value) {
$this->columnCount = $value;
}
public function GetColumnCount() {
return $this->columnCount;
}
public function SetRowCount($value) {
$this->rowCount = $value;
}
public function GetRowCount() {
return $this->rowCount;
}
#region WYSIWYG Editor Options
public function GetAllowColorControls() {
return $this->allowColorControls;
}
public function SetAllowColorControls($value) {
$this->allowColorControls = $value;
}
#endregion
public function ExtractsValueFromPost(&$valueChanged) {
if (GetApplication()->IsPOSTValueSet($this->GetName())) {
$valueChanged = true;
return GetApplication()->GetPOSTValue($this->GetName());
} else {
$valueChanged = false;
return null;
}
}
public function Accept(Renderer $renderer) {
$renderer->RenderHtmlWysiwygEditor($this);
}
}