70 $this->_config = $config ?: [];
76 $this->
configure($this->_config = array_merge(
77 $this->_controller->config([
'widget',lcfirst(\
Rsi\File::basename(get_called_class()))],[]),
80 $this->
publish([
'controller',
'securityChecksIgnore']);
81 $this->
publish(
'parent',self::READWRITE);
89 $this->_config = array_merge($this->_config,$config);
98 protected function config($key,$default =
null){
99 return \Rsi\Record::get($this->_config,$key,$default);
106 $config = array_merge(
107 [self::CLASS_NAME => get_called_class()],
108 $this->
get([self::DEFAULT_VALUE,self::DISPLAY,self::MIN,self::MAX,self::REQUIRED])
110 if($meta = $this->
meta){
111 foreach($meta as $key => $value) $meta[$key] = $this->
meta($key);
114 if($params = $this->
config(self::PARAMS)){
116 foreach($params as $key => $value)
if(substr($key,0,1) ==
'@') $ids[] = $value;
120 ? (is_object($this->validFunc[0]) ? get_class($this->validFunc[0]) : $this->validFunc[0]) .
'::' . $this->validFunc[1]
122 if($this->trailer) $config[
self::TRAILER] = $this->trans->str($this->trailer,$this->tags);
127 foreach($this->widgets as $id => $widget) $widgets[$id] = array_filter($widget->clientConfig());
134 $caption = $this->
config(self::CAPTION);
135 return $this->trans->str($caption ===
null ? $this->_controller->caption($id ?: $this->id) : $caption);
138 public function hint($id =
null){
139 $hint = $this->
config(self::HINT);
140 return $hint ===
null
142 $this->trans->str($this->_controller->hint($id ?: $this->id),$this->tags) ?:
143 $this->trans->str($this->_controller->hint(\
Rsi\File::basename(get_called_class())),$this->tags)
145 : $this->trans->str($hint,$this->tags);
153 public function meta($key,$default =
null){
154 return is_callable($meta = $this->
config(array_merge([self::META],(array)$key),$default)) ? call_user_func($meta,$this->
id) : $meta;
202 return $this->
format($value);
219 foreach(get_class_methods($this) as $method)
220 if((strlen($method) > 5) && (substr($method,0,5) ==
'purge') && ($method !=
'purgeBase')) $value = call_user_func([$this,$method],$value);
228 $this->_controller->expect($this->
id,$action);
235 $this->fred->externalError(
'Unknown child widget',[
'class' => get_called_class(),
'id' => $id]);
245 $this->_executing =
true;
246 if(!$this->security->check($this->securityChecksIgnore,$this->_controller->expected($this->id,$action = $this->_controller->action)))
247 $this->fred->externalError(
'Suspicious widget action call',[
'class' => get_called_class()]);
249 elseif(!method_exists($this,$method =
'action' . ucfirst($action)))
250 $this->fred->externalError(
'Unknown widget action',[
'class' => get_called_class(),
'action' => $action]);
252 $this->indexes = $this->request->record(
'indexes');
253 call_user_func([$this,$method]);
254 $this->
event->trigger(self::EVENT_ACTION_PREFIX . lcfirst(\
Rsi\File::basename(get_called_class())) .
':' . $action,$this);
263 protected function indexId($id,$join =
false){
264 $id = explode(self::CHILD_ID_SEPARATOR,$id);
266 foreach($id as $i => $sub)
if(is_numeric($sub ==
'*' ? ($id[$i] = $this->indexes[$index] ??
null) : $sub)) $index++;
267 return $join ? implode(self::CHILD_ID_SEPARATOR,$id) : $id;
275 return \Rsi::nothing($value);
295 if($this->required === self::VALID_FUNC)
return $this->
checkValidFunc($value,$index);
296 if(is_array(
$required = $this->required)){
298 $widget = $this->_controller->widgets[$widget_id = array_shift($id)];
299 $ref = $widget->purge($this->request->complex([
'widget',$widget_id]));
300 $ref = $this->_controller->view->convert ? $widget->convert($ref) : $widget->clientConvert($ref);
307 return $this->validFunc ? call_user_func($this->validFunc,$value) :
true;
316 foreach(get_class_methods($this) as $method)
317 if(($method !=
'checkRequired') && (strlen($method) > 5) && (substr($method,0,5) ==
'check') && !call_user_func([$this,$method],$value))
318 return lcfirst(substr($method,5));
324 switch($this->request->type){
327 $this->request->result = [
328 'caption' => $this->trans->str($this->_controller->helpCaption,$this->tags),
329 'help' => $this->trans->str(($this->widgets[$this->request->id] ?? $this)->$type,$this->tags)
334 $this->_controller = $value;
339 if($this->_display ===
null){
342 $this->_display = $this->
config(self::DISPLAY,$this->_controller->display);
343 if(($this->_display > self::DISPLAY_READABLE) && !$this->user->authorized($this->right,
User::RIGHT_LEVEL_WRITE))
345 if($this->parent) $this->_display = min($this->_display,$this->parent->display);
352 return $this->_controller->fred;
356 if($this->_id ===
null){
359 foreach($this->parent->widgets as $id => $widget)
if($this === $widget){
360 $this->_id = $this->parent->id . self::CHILD_ID_SEPARATOR . $id;
364 elseif($this->_controller)
foreach($this->_controller->widgets as $id => $widget)
if($this === $widget){
373 $params = $refs = [];
374 foreach($this->
config(self::PARAMS,[]) as $key => $value){
375 if(substr($key,0,1) ==
'@'){
376 $id = explode(self::CHILD_ID_SEPARATOR,$value);
378 foreach($id as $i => $sub)
if(is_numeric($sub ==
'*' ? ($id[$i] = $this->indexes[$index] ??
null) : $sub)) $index++;
381 else $params[$key] = $value;
383 if(!array_key_exists($params_key = serialize($refs + $params),$this->_params)){
384 foreach($refs as $key => $id){
386 if(array_key_exists($widget_id = array_shift($id),$this->request->data)) $value = $this->request->data[$widget_id];
388 $widget = $this->_controller->widgets[$widget_id];
389 $value = $widget->purge($this->request->complex([
'widget',$widget_id]));
393 $value = $value[$sub = array_shift($id)] ??
null;
394 if($widget && !is_numeric($sub)) $widget = $widget->widgets[$sub] ??
null;
397 $value = $this->_controller->view->convert ? $widget->convert($value) : $widget->clientConvert($value);
398 if($widget->check($value)) $value =
false;
400 $params[substr($key,1)] = $value;
402 $this->_params[$params_key] = $params;
404 return $this->_params[$params_key];
412 if($right = $this->
config(self::RIGHT))
return $right;
413 if($right !==
false)
return $this->_controller->right;
418 if($this->_tags ===
null){
419 $this->_tags = $this->
config(self::TAGS,[]);
420 if($this->_config)
foreach($this->_config as $key => $value)
421 $this->_tags[$key] = is_array($value) || is_object($value) ? (bool)$value : $value;
422 if(!$this->
nothing($this->min)) $this->_tags[self::MIN] = $this->
formatTag($this->min);
423 if(!$this->
nothing($this->max)) $this->_tags[self::MAX] = $this->
formatTag($this->max);
429 if($this->_widgets ===
null){
430 $this->_widgets = $this->
config(self::WIDGETS,[]);
431 foreach($this->_widgets as $widget){
432 $widget->parent = $this;
444 return array_key_exists($key,$this->_config) ? $this->_config[$key] : $this->_controller->component($key);