@param array $replacements
@param array $input

@return array
6639
private static function replaceKeys(array &$replacements, array $input)
    {
        $return = [];
        foreach ($input as $key => $value) {
            $key = \str_replace(\array_keys($replacements), \array_values($replacements), $key);

            if (\is_array($value)) {
                $value = self::replaceKeys($replacements, $value);
            }

            $return[$key] = $value;
        }

        return $return;
    }
1054070
protected function expandPatterns(array $patterns, $search, array $replacements)
    {
        if ($replacements === []) {
            return $patterns;
        }
        $patternsWithReplacements = [];
        foreach ($patterns as $pattern) {
            foreach ($replacements as $replacement) {
                $patternsWithReplacements[] = Files::getUnixStylePath(str_replace($search, $replacement, $pattern));
            }
        }

        return $patternsWithReplacements;
    }
1364954
public static function replaceInFile($filename, $replacements){
		$content = \file_get_contents($filename);
		foreach ($replacements as $find => $replace) {
			$content = \str_replace($find, $replace, $content);
		}
		\file_put_contents($filename, $content);
	}
1096960
public function removeEmptyInput($input)
    {
        $filterableInput = [];

        foreach ($input as $key => $val) {
            if ($val !== '' && $val !== null) {
                $filterableInput[$key] = $val;
            }
        }

        return $filterableInput;
    }
174815
protected function replaceSpecialChars($input)
	{
		if(is_array($input))
		{
			$result = [];
			
			foreach($input as $k => $v)
			{
				$result[$k] = $this->replaceSpecialChars($v);
			}
			
			return $result;
		}
		
		return strtr($input, [
			'\n' => "\n",
			'\t' => "\t"
		]);
	}
1029809
public function parser($text, $replacements = []): string
	{
		global $context;

		if (empty($text) || empty($replacements) || !is_array($replacements))
			return '';

		// Split the replacements up into two arrays, for use with str_replace.
		$find = [];
		$replace = [];

		foreach ($replacements as $f => $r)
		{
			$find[] = '{' . $f . '}';
			$replace[] = $r . ((strpos($f,'href') !== false) ? (';'. $context['session_var'] .'='. $context['session_id']) : '');
		}

		// Do the variable replacements.
		return str_replace($find, $replace, $text);
	}
1002632
public function set_diacritic_custom_replacements( $custom_replacements = [] ) {
		if ( ! \is_array( $custom_replacements ) ) {
			$custom_replacements = $this->parse_diacritics_replacement_string( $custom_replacements );
		}

		$this->data['diacriticCustomReplacements'] = self::array_map_assoc(
			function( $key, $replacement ) {
				$key         = \strip_tags( \trim( $key ) );
				$replacement = \strip_tags( \trim( $replacement ) );

				if ( ! empty( $key ) && ! empty( $replacement ) ) {
					return [ $key => $replacement ];
				} else {
					return [];
				}
			},
			$custom_replacements
		);

		$this->update_diacritics_replacement_arrays();
	}
814955
public function getAllValues($input, $options = []) {
		// reset values
		$this->values = [];
		// sort fields
		$fields = $this->sortFieldsForProcessing($this->fields);
		// inject tenant #
		if (!empty($this->collection_object->primary_model->tenant)) {
			$this->values[$this->collection_object->primary_model->tenant_column] = \Tenant::id();
		}
		// if we delete we only allow pk and optimistic lock
		$allowed = [];
		if (!empty($options['validate_for_delete'])) {
			$allowed = $this->collection_object->data['pk'];
			if ($this->collection_object->primary_model->optimistic_lock) {
				$allowed[] = $this->collection_object->primary_model->optimistic_lock_column;
			}
		}
		// see if we have a change in entry fields
		$changed_field = [
			'parent' => null,
			'detail' => null,
			'subdetail' => null
		];
		if (!empty($this->misc_settings['__form_onchange_field_values_key']) && count($this->misc_settings['__form_onchange_field_values_key']) == 1) {
			if (isset($fields[$this->misc_settings['__form_onchange_field_values_key'][0]])) {
				$changed_field['parent'] = $this->misc_settings['__form_onchange_field_values_key'][0];
			}
		}
		// process json_contains
		foreach ($fields as $k => $v) {
			if (empty($v['options']['json_contains'])) continue;
			$value = array_key_get($input, $v['options']['values_key']);
			if (is_json($value)) {
				$value = json_decode($value, true);
				foreach ($v['options']['json_contains'] as $k2 => $v2) {
					array_key_set($input, $v2, $value[$k2] ?? null);
				}
			} else if (empty($value)) {
				foreach ($v['options']['json_contains'] as $k2 => $v2) {
					array_key_set($input, $v2, null);
				}
			}
		}
		// process fields
		foreach ($fields as $k => $v) {
			// skip certain values
			if (!empty($options['only_columns']) && !in_array($k, $options['only_columns'])) continue;
			if (!empty($allowed) && !in_array($k, $allowed)) continue;
			// default data type
			if (empty($v['options']['type'])) {
				$v['options']['type'] = 'varchar';
			}
			// get value
			$input = array_merge_hard($input, $this->values);
			$value = array_key_get($input, $v['options']['values_key']);
			$error_name = $v['options']['error_name'];
			// multiple column
			if (!empty($v['options']['multiple_column'])) {
				// todo - validate
				$value = $this->generateMultipleColumns($value, $error_name, array_merge($input, $this->values), null, $v);
			} else {
				$temp = $this->validateDataTypesSingleValue($k, $v, $value, $error_name);
				if (empty($temp['flag_error'])) {
					if (empty($temp[$k]) && !empty($temp[$k . '_is_serial'])) {
						// we do not create empty serial keys
						continue;
					} else {
						$value = $temp[$k];
					}
				}
			}
			// persistent
			if ($this->values_loaded && !empty($this->misc_settings['persistent']['fields'][$k])) {
				if (is_null($value)) {
					$value = $this->original_values[$k];
				} else if ($this->misc_settings['persistent']['fields'][$k] === 'if_set' && empty($this->original_values[$k])) {
					// we allow value change
				} else if ($value !== $this->original_values[$k]) {
					$this->error('danger', 'You are trying to change persistent field!', $error_name);
				}
			}
			$v['options']['error_name_no_field'] = $error_name;
			// default
			$default = null;
			if (array_key_exists('default', $v['options'])) {
				array_key_set($this->values, $v['options']['values_key'], $value);
				$default = $this->processDefaultValue($k, $v['options']['default'], null, $this->values, false, $changed_field, $v);
				if (!isset($value) && $this->canProcessDefaultValue($value, $v, $v['options']['default'])) {
					$value = $default;
				} else {
					$temp = array_key_get($this->values, $v['options']['values_key']);
					if ($temp !== $value) {
						$value = $temp;
					}
				}
			}
			// put into values
			array_key_set($this->values, $v['options']['values_key'], $value);
			// options_model validation
			if (isset($value) && !empty($v['options']['options_model']) && empty($v['options']['options_manual_validation'])) {
				$this->checkOptionsModel($v['options'], $value, $error_name, array_merge($input, $this->values));
			}
			// options validation
			if (isset($value) && !empty($v['options']['options']) && empty($v['options']['options_manual_validation'])) {
				$temp_value = is_array($value) ? $value : [$value];
				foreach ($temp_value as $k54 => $v54) {
					$key = is_scalar($v54) ? $v54 : $k54;
					if (empty($v['options']['options'][$key])) {
						$this->error('danger', \Object\Content\Messages::INVALID_VALUES, $error_name);
					}
				}
			}
		}
		// check optimistic lock
		if ($this->values_loaded && $this->collection_object->primary_model->optimistic_lock && !in_array($this->initiator_class, ['report', 'list', 'import']) && empty($this->options['skip_optimistic_lock'])) {
			if (($this->values[$this->collection_object->primary_model->optimistic_lock_column] ?? '') !== $this->original_values[$this->collection_object->primary_model->optimistic_lock_column]) {
				$this->error('danger', \Object\Content\Messages::OPTIMISTIC_LOCK);
			}
		}
		// we do not process details if only_columns is set
		if (!empty($options['only_columns'])) goto processAllValues;
		// process details & subdetails
		if (empty($options['validate_for_delete']) && !empty($this->detail_fields)) {
			foreach ($this->detail_fields as $k => $v) {
				$this->values[$k] = []; // a must
				$details = $input[$k] ?? [];
				// 1 to 1
				if (!empty($v['options']['details_11'])) {
					$details = [$details];
				}
				// sort fields
				$fields = $this->sortFieldsForProcessing($v['elements'], $v['options']);
				// if we have custom data processor
				if (!empty($v['options']['details_process_widget_data'])) {
					$widget_model = \Factory::model($k, true);
					$v['validate_required'] = $options['validate_required'] ?? false;
					$this->values[$k] = $widget_model->formProcessWidgetData($this, [$k], $details, $this->values, $fields, $v);
					continue;
				}
				// start processing of keys
				$detail_key_holder = [];
				$this->generateDetailsPrimaryKey($detail_key_holder, 'reset', $this->values, [$k], $v);
				// autoincrement
				$autoincrement_details = [];
				if (!empty($v['options']['details_autoincrement']) && empty($v['options']['details_11'])) {
					// set it to 0
					foreach ($v['options']['details_autoincrement'] as $v72) {
						$autoincrement_details[$v72] = 0;
					}
					// find maximums in original values
					if (!empty($this->original_values[$k])) {
						foreach ($this->original_values[$k] as $k71 => $v71) {
							foreach ($v['options']['details_autoincrement'] as $v72) {
								if ($v71[$v72] > $autoincrement_details[$v72]) {
									$autoincrement_details[$v72] = $v71[$v72];
								}
							}
						}
					}
					// find maximum in new values
					if (!empty($details)) {
						foreach ($details as $k71 => $v71) {
							foreach ($v['options']['details_autoincrement'] as $v72) {
								if (!empty($v71[$v72]) && intval($v71[$v72]) > $autoincrement_details[$v72]) {
									$autoincrement_details[$v72] = $v71[$v72];
								}
							}
						}
					}
				}
				// process details one by one
				foreach ($details as $k2 => $v2) {
					// see if we have a change in a detail
					$changed_field_details = $changed_field;
					if (!empty($this->misc_settings['__form_onchange_field_values_key'])) {
						$temp_count = count($this->misc_settings['__form_onchange_field_values_key']);
						if ($this->misc_settings['__form_onchange_field_values_key'][0] == $k && ($temp_count == 2 || $temp_count == 3)) {
							if (!empty($v['options']['details_11'])) {
								$changed_field_details['detail'] = $this->misc_settings['__form_onchange_field_values_key'][1];
							} else if ($this->misc_settings['__form_onchange_field_values_key'][1] . '' == $k2 . '') {
								$changed_field_details['detail'] = $this->misc_settings['__form_onchange_field_values_key'][2];
							}
						}
					}
					// change detected
					$flag_change_detected = false;
					// put pk into detail
					$detail = $detail_key_holder['parent_pks'];
					// process json_contains
					foreach ($fields as $k3 => $v3) {
						if (empty($v3['options']['json_contains'])) continue;
						// get value, grab from neighbouring values first
						$value = $v2[$k3] ?? null;
						if (is_json($value)) {
							$value = json_decode($value, true);
							foreach ($v3['options']['json_contains'] as $k31 => $v31) {
								$v2[$v31] = $value[$k31] ?? null;
							}
						} else if (empty($value)) {
							foreach ($v3['options']['json_contains'] as $k31 => $v31) {
								$detail[$v31] = $v2[$v31] = null;
							}
						}
					}
					// process pk
					$this->generateDetailsPrimaryKey($detail_key_holder, 'pk', $v2, [$k], $v);
					$error_name = $detail_key_holder['error_name'];
					$k2 = $detail_key_holder['pk'];
					// process fields
					foreach ($fields as $k3 => $v3) {
						// skip buttons and links
						if (in_array(($v3['options']['method'] ?? ''), ['button', 'button2', 'submit', 'a'])) continue;
						// default data type
						if (empty($v3['options']['type'])) {
							$v3['options']['type'] = 'varchar';
						}
						// get value, grab from neighbouring values first
						$value = $detail[$k3] ?? $v2[$k3] ?? null;
						// validate data type
						if (!empty($v3['options']['multiple_column'])) {
							if (!empty($value)) {
								$value = $this->generateMultipleColumns($value, $error_name, $detail, [$k], $v3);
							} else {
								$value = null;
							}
						} else {
							$temp = $this->validateDataTypesSingleValue($k3, $v3, $value, "{$error_name}[{$k3}]");
							if (empty($temp['flag_error'])) {
								if (empty($temp[$k3]) && !empty($temp[$k3 . '_is_serial'])) {
									// we do not create empty serial keys
									continue;
								} else {
									$value = $temp[$k3];
								}
							}
						}
						// persistent
						if (!empty($v['options']['details_11'])) {
							$detail_access_key = [$k];
						} else {
							$detail_access_key = [$k, $k2];
						}
						$original_values = array_key_get($this->original_values, array_merge($detail_access_key, [$k3]));
						if ($this->values_loaded && !empty($this->misc_settings['persistent']['details'][$k][$k3]) && isset($original_values)) {
							// todo: handle if_set
							if (is_null($value)) {
								$value = $original_values;
							} else if ($value !== $original_values) {
								$this->error('danger', 'You are trying to change persistent field!', "{$error_name}[{$k3}]");
							}
						}
						$v3['options']['error_name_no_field'] = $error_name;
						// default
						$default = null;
						if (array_key_exists('default', $v3['options'])) {
							$detail[$k3] = $value;
							$default = $this->processDefaultValue($k3, $v3['options']['default'], null, $detail, false, $changed_field_details, $v3);
							if (!isset($value) && $this->canProcessDefaultValue($value, $v3)) {
								$value = $default;
							} else if ($detail[$k3] !== $value) {
								$value = $detail[$k3];
							}
						}
						// see if we changed the value but not autoincrement
						if (isset($value) && $value !== $default && !isset($autoincrement_details[$k3])) {
							$flag_change_detected = true;
						}
						// options_model validation
						if (isset($value) && !empty($v3['options']['options_model']) && empty($v3['options']['options_manual_validation'])) {
							$this->checkOptionsModel($v3['options'], $value, "{$error_name}[{$k3}]", array_merge($v2, $detail));
						}
						// options validation
						if (isset($value) && !empty($v3['options']['options']) && empty($v3['options']['options_manual_validation'])) {
							$temp_value = is_array($value) ? $value : [$value];
							foreach ($temp_value as $v54) {
								if (empty($v3['options']['options'][$v54])) {
									$this->error('danger', \Object\Content\Messages::INVALID_VALUES, "{$error_name}[{$k3}]");
								}
							}
						}
						$detail[$k3] = $value;
					}
					// process subdetails, first to detect change
					if (!empty($v['subdetails'])) {
						foreach ($v['subdetails'] as $k0 => $v0) {
							// make empty array
							$detail[$k0] = [];
							// sort fields
							$subdetail_fields = $this->sortFieldsForProcessing($v0['elements']);
							// if we have custom data processor
							if (!empty($v0['options']['details_process_widget_data'])) {
								$widget_model = \Factory::model($k0, true);
								$v0['validate_required'] = $options['validate_required'] ?? false;
								$detail[$k0] = $widget_model->formProcessWidgetData($this, [$k, $k2, $k0], $v2[$k0] ?? [], $detail, $subdetail_fields, $v0);
								// change detected
								if (!empty($detail[$k0])) {
									$flag_change_detected = true;
								}
								continue;
							}
							// start processing of keys
							$subdetail_key_holder = [];
							$this->generateDetailsPrimaryKey($subdetail_key_holder, 'reset', $detail, [$k, $k2, $k0], $v0);
							// go through data
							if (!empty($v0['options']['details_11'])) {
								$subdetail_data = [$v2[$k0] ?? []];
							} else {
								$subdetail_data = $v2[$k0] ?? [];
							}
							// handle auto increment
							$autoincrement_subdetails = [];
							if (!empty($v0['options']['details_autoincrement']) && empty($v0['options']['details_11'])) {
								foreach ($v0['options']['details_autoincrement'] as $v72) {
									$autoincrement_subdetails[$v72] = 0;
								}
								// find maximum in new values
								if (!empty($subdetail_data)) {
									foreach ($subdetail_data as $k71 => $v71) {
										foreach ($v0['options']['details_autoincrement'] as $v72) {
											if (!empty($v71[$v72]) && intval($v71[$v72]) > $autoincrement_subdetails[$v72]) {
												$autoincrement_subdetails[$v72] = $v71[$v72];
											}
										}
									}
								}
							}
							if (!empty($subdetail_data)) {
								foreach ($subdetail_data as $k5 => $v5) {
									$flag_subdetail_change_detected = false;
									// put pk into detail
									$subdetail = $subdetail_key_holder['parent_pks'];
									// process json_contains
									foreach ($subdetail_fields as $k30 => $v30) {
										if (empty($v30['options']['json_contains'])) continue;
										// get value, grab from neighbouring values first
										$value = $v5[$k30] ?? null;
										if (is_json($value)) {
											$value = json_decode($value, true);
											foreach ($v30['options']['json_contains'] as $k31 => $v31) {
												$v5[$v31] = $value[$k31] ?? null;
											}
										} else if (empty($value)) {
											foreach ($v30['options']['json_contains'] as $k31 => $v31) {
												$subdetail[$v31] = $v5[$v31] = null;
											}
										}
									}
									// process pk
									$this->generateDetailsPrimaryKey($subdetail_key_holder, 'pk', $v5, [$k, $k2, $k0], $v0);
									$subdetail_error_name = $subdetail_key_holder['error_name'];
									$k5 = $subdetail_key_holder['pk'];
									// process fields
									foreach ($subdetail_fields as $k6 => $v6) {
										// default data type
										if (empty($v6['options']['type'])) {
											$v6['options']['type'] = 'varchar';
										}
										// get value
										$value = $v5[$k6] ?? null;
										// validate data type
										$temp = $this->validateDataTypesSingleValue($k6, $v6, $value, "{$subdetail_error_name}[{$k6}]");
										if (empty($temp['flag_error'])) {
											if (empty($temp[$k6]) && !empty($temp[$k6 . '_is_serial'])) {
												// we do not create empty serial keys
												continue;
											} else {
												$value = $temp[$k6];
											}
										}
										// persistent
										if (!empty($v0['options']['details_11'])) {
											$subdetail_access_key = array_merge($detail_access_key, [$k0]);
										} else {
											$subdetail_access_key = array_merge($detail_access_key, [$k0, $k5]);
										}
										$original_values = array_key_get($this->original_values, array_merge($subdetail_access_key, [$k6]));
										if ($this->values_loaded && !empty($this->misc_settings['persistent']['subdetails'][$k][$k0][$k6]) && isset($original_values)) {
											// todo: handle if_set
											if (is_null($value)) {
												$value = $original_values;
											} else if ($value !== $original_values) {
												$this->error('danger', 'You are trying to change persistent field!', "{$subdetail_error_name}[{$k3}]");
											}
										}
										// default
										$default = null;
										if (array_key_exists('default', $v6['options'])) {
											$default = $this->processDefaultValue($k6, $v6['options']['default'], $value, $subdetail, false);
											if (strpos($v6['options']['default'], 'static::') !== false || is_null($value)) {
												$value = $default;
											}
										}
										// see if we changed the value
										if (!is_null($value) && $value !== $default) {
											$flag_subdetail_change_detected = true;
										}
										$subdetail[$k6] = $value;
									}
									// if we have a change
									if ($flag_subdetail_change_detected) {
										$flag_change_detected = true;
										if (!empty($v0['options']['details_11'])) {
											$detail[$k0] = $subdetail;
										} else {
											// autoincrement
											if (!empty($autoincrement_subdetails)) {
												foreach ($autoincrement_subdetails as $k71 => $v71) {
													if (empty($subdetail[$k71])) {
														$subdetail[$k71] = $v71 + 1;
														$autoincrement_subdetails[$k71]++;
													}
												}
											}
											$detail[$k0][$k5] = $subdetail;
										}
									}
								}
							}
						}
					}
					// if we have changes we puth them into values
					if ($flag_change_detected) {
						// 1 to 1
						if (!empty($v['options']['details_11'])) {
							$this->values[$k] = $detail;
						} else { // 1 to M
							// autoincrement
							if (!empty($autoincrement_details)) {
								foreach ($autoincrement_details as $k71 => $v71) {
									if (empty($detail[$k71])) {
										$detail[$k71] = $v71 + 1;
										$autoincrement_details[$k71]++;
									}
								}
							}
							$this->values[$k][$k2] = $detail;
						}
					}
				}
			}
			// we need to process not set details
			foreach ($input as $k => $v) {
				if (is_string($k) && $k[0] == '\\' && !in_array($k, array_keys($this->fields)) && !in_array($k, array_keys($this->detail_fields))) {
					$this->values[$k] = $input[$k];
				}
			}
		}
processAllValues:
		$this->triggerMethod('processAllValues');
		// debug
		//print_r2($this->values);
	}
986826
public static function replace(array $words, $replacement, $text)
    {
        $replace = (mb_strlen($replacement) > 1)
            ? $replacement
            : static::transformReplacement($words, $replacement);

        return str_replace($words, $replace, $text);
    }
871733
public static function replaceStrict(array $source, array ...$replace) {

        $replacements = [];

        foreach ($replace as $items) {
            $replacements[] = array_intersect_key($items, $source);
        }

        return array_merge($source, ...$replacements);

    }
1080799
public function setPunctuationReplacements($replacements)
        {
            if(!is_array($replacements)) {
                throw new \Thin\Exception(__METHOD__ . ': method expects a keyed array as argument.', 500);
            }
            foreach($replacements as $key => $value) {
                $this->punctuation[$key] = $value;
            }
            return $this;
        }
535183
public function get(array $input) : array {
		$this->form->form_object->addInput($input);
		$this->form->form_object->process();
		return $this->form->form_object->apiResult();
	}
656829
public static function preg_replace_array($pattern, array $replacements, $subject)
    {
        return preg_replace_callback($pattern, function () use (&$replacements) {
            foreach ($replacements as $key => $value) {
                return array_shift($replacements);
            }
        }, $subject);
    }
1061009
public function insertRSS($input = [])
    {
        $stmt = $this->db->prepare("INSERT INTO  " . $this->table . " (TITLE, LINK, DESCRIPTION, CREATED) VALUES (?, ?, ?, datetime('now', 'localtime'))");
        $stmt->execute([$input['TITLE'], $input['LINK'], $input['DESCRIPTION']]);
    }
604573
public static function replace($text, array $replacements = [], $prefix = '{', $suffix = '}')
    {
        $replacements = static::prepareBinding($replacements, $prefix, $suffix);

        $filter = function ($text) use ($replacements) {
            return strtr($text, $replacements);
        };

        if (is_array($text)) {
            $text = array_map($filter, $text);
        } else {
            $text = $filter($text);
        }

        return $text;
    }
457239
public function parse($input, array $aliases = array())
    {
        if (0 !== strpos(ltrim($input), '/**')) {
            return array();
        }

        if (false == ($position = strpos($input, '@'))) {
            return array();
        }

        if (0 < $position) {
            $position -= 1;
        }

        $input = substr($input, $position);
        $input = trim($input, '*/ ');

        $this->aliases = $aliases;

        $this->lexer->setInput($input);
        $this->lexer->moveNext();

        return $this->getAnnotations();
    }
1125145
public static function parseLines($input): array
    {
        if (is_array($input)) {
            $input = implode(PHP_EOL, $input);
        }

        return Str::parseLines($input);
    }