Tidy up a gedcom record on export, for compatibility/portability.

@param string $rec

@return string
495686
public static function reformatRecord($rec): string
    {
        $newrec = '';
        foreach (preg_split('/[\r\n]+/', $rec, -1, PREG_SPLIT_NO_EMPTY) as $line) {
            // Split long lines
            // The total length of a GEDCOM line, including level number, cross-reference number,
            // tag, value, delimiters, and terminator, must not exceed 255 (wide) characters.
            if (mb_strlen($line) > Gedcom::LINE_LENGTH) {
                [$level, $tag] = explode(' ', $line, 3);
                if ($tag !== 'CONT' && $tag !== 'CONC') {
                    $level++;
                }
                do {
                    // Split after $pos chars
                    $pos = Gedcom::LINE_LENGTH;
                    // Split on a non-space (standard gedcom behaviour)
                    while (mb_substr($line, $pos - 1, 1) === ' ') {
                        --$pos;
                    }
                    if ($pos === strpos($line, ' ', 3)) {
                        // No non-spaces in the data! Can’t split it :-(
                        break;
                    }
                    $newrec .= mb_substr($line, 0, $pos) . Gedcom::EOL;
                    $line   = $level . ' CONC ' . mb_substr($line, $pos);
                } while (mb_strlen($line) > Gedcom::LINE_LENGTH);
            }
            $newrec .= $line . Gedcom::EOL;
        }

        return $newrec;
    }
268745
public function exportGedcom($stream): void
    {
        $buffer = FunctionsExport::reformatRecord(FunctionsExport::gedcomHeader($this, 'UTF-8'));

        $union_families = DB::table('families')
            ->where('f_file', '=', $this->id)
            ->select(['f_gedcom AS gedcom', 'f_id AS xref', DB::raw('LENGTH(f_id) AS len'), DB::raw('2 AS n')]);

        $union_sources = DB::table('sources')
            ->where('s_file', '=', $this->id)
            ->select(['s_gedcom AS gedcom', 's_id AS xref', DB::raw('LENGTH(s_id) AS len'), DB::raw('3 AS n')]);

        $union_other = DB::table('other')
            ->where('o_file', '=', $this->id)
            ->whereNotIn('o_type', ['HEAD', 'TRLR'])
            ->select(['o_gedcom AS gedcom', 'o_id AS xref', DB::raw('LENGTH(o_id) AS len'), DB::raw('4 AS n')]);

        $union_media = DB::table('media')
            ->where('m_file', '=', $this->id)
            ->select(['m_gedcom AS gedcom', 'm_id AS xref', DB::raw('LENGTH(m_id) AS len'), DB::raw('5 AS n')]);

        DB::table('individuals')
            ->where('i_file', '=', $this->id)
            ->select(['i_gedcom AS gedcom', 'i_id AS xref', DB::raw('LENGTH(i_id) AS len'), DB::raw('1 AS n')])
            ->union($union_families)
            ->union($union_sources)
            ->union($union_other)
            ->union($union_media)
            ->orderBy('n')
            ->orderBy('len')
            ->orderBy('xref')
            ->chunk(100, static function (Collection $rows) use ($stream, &$buffer): void {
                foreach ($rows as $row) {
                    $buffer .= FunctionsExport::reformatRecord($row->gedcom);
                    if (strlen($buffer) > 65535) {
                        fwrite($stream, $buffer);
                        $buffer = '';
                    }
                }
            });

        fwrite($stream, $buffer . '0 TRLR' . Gedcom::EOL);
    }
416077
protected function fieldsRemain()
    {
        $bufferlen = strlen($this->buffer);
        $minlen = strlen($this->lastBoundary);

        # if the buffer is too short to contain the last boundary
        # read enough bytes into the buffer to allow for a strpos test
        if ($bufferlen < $minlen) {
            if (feof($this->fp)) {
                fclose($this->fp);
                throw new \sndsgd\http\data\DecodeException(
                    "Invalid multipart data encountered; ".
                    "end of content was reached before expected"
                );
            }

            $bytes = fread($this->fp, $this->bytesPerRead);
            if ($bytes === false) {
                fclose($this->fp);
                throw new \RuntimeException(
                    "failed to read $minlen bytes from input stream"
                );
            }

            $this->buffer .= $bytes;
        }

        # if the buffer starts with the last boundary, there are no more fields
        return (strpos($this->buffer, $this->lastBoundary) !== 0);
    }
223434
private function cleanUpFileName($fileName, $locale, $extension)
    {
        $pathInfo = pathinfo($fileName);
        $cleanedFileName = $this->get('sulu.content.path_cleaner')->cleanup($pathInfo['filename'], $locale);
        if ($extension) {
            $cleanedFileName .= '.' . $extension;
        }

        return $cleanedFileName;
    }
1161710
public static function clean($data) {
		// String?
		if (!is_array($data)) return $data;
		// Needs a good scrubbing...
		$out = [];
		$whitelist = ['.priority'];
		// Recursive iterator to sanitize all keys (and flatten object values)
		foreach ($data as $key => $value) {
			$key = (in_array($key, $whitelist) !== false) ? $key : preg_replace('/[\.\#\$\/\[\]]/i', '', $key);
			if (is_object($value)) $value = $value->__toString();
			if (is_array($value) || is_object($value)) {
				$out[$key] = self::clean($value);
			} else {
				$out[$key] = $value;
			}
		}
		return $out;
	}
452635
public function cleanupOutputDirectory()
    {
        $directoryIterator = new \RecursiveDirectoryIterator($this->outputDirectory, \RecursiveDirectoryIterator::SKIP_DOTS);

        /**
         * Items, which must not be deleted have to be skipped during the directory iteration
         *
         * @param \SplFileInfo $current
         * @return bool
         */
        $filterCallback = function (\SplFileInfo $current) {
            $skipItem = false === strpos($current->getFilename(), '.gitkeep') ? true : false;
            return $skipItem;
        };

        $filteredDirectoryIterator = new \RecursiveCallbackFilterIterator($directoryIterator, $filterCallback);
        $items = new \RecursiveIteratorIterator(
            $filteredDirectoryIterator,
            \RecursiveIteratorIterator::CHILD_FIRST
        );

        $this->fileSystem->remove($items);
    }
1023606
protected function cleanData($data)
    {
        $replacementChars = array(
            "\xe2\x80\x98" => "'",   // ‘
            "\xe2\x80\x99" => "'",   // ’
            "\xe2\x80\x9a" => "'",   // ‚
            "\xe2\x80\x9b" => "'",   // ‛
            "\xe2\x80\x9c" => '"',   // “
            "\xe2\x80\x9d" => '"',   // ”
            "\xe2\x80\x9e" => '"',   // „
            "\xe2\x80\x9f" => '"',   // ‟
            "\xe2\x80\x93" => '-',   // –
            "\xe2\x80\x94" => '--',  // —
            "\xe2\x80\xa6" => '...', // …
            "\xc2\xa0"     => ' ',
        );
        // Replace UTF-8 characters
        $cleanedData = strtr($data, $replacementChars);

        // Replace Windows-1252 equivalents
        $charsToReplace = array_map(function ($code) {
            return $this->mb_chr($code);
        }, array(133, 145, 146, 147, 148, 150, 151, 194));
        $cleanedData = $this->mb_str_replace($charsToReplace, $replacementChars, $cleanedData);

        return $cleanedData;
    }
983694
public void clean()
	{

		ChronoFullRevision cfr = firstCFR;
		totalSize = size;
		while (cfr != null) {
			totalSize += cfr.size();
			cfr = cfr.getNext();
		}

		if (totalSize < MAX_STORAGE_SIZE) {
			return;
		}

		cfr = firstCFR;
		while (cfr != null) {
			totalSize += cfr.clean(revisionIndex, 0);
			cfr = cfr.getNext();
		}

		ChronoStorageBlock block;
		while (last != null && totalSize >= MAX_STORAGE_SIZE) {

			// System.out.println("CLEAN " + last.getRevisionIndex());

			// Retrieve previous block
			block = last.getIndexPrev();

			// Subtract size
			if (storage.remove(last.getRevisionIndex()) == null) {
				throw new RuntimeException("VALUE WAS NOT REMOVED FROM STORAGE");
			}
			totalSize -= last.length();
			size += last.length();

			// Delete references
			if (block != null) {
				block.setIndexNext(null);
			}
			last.setIndexPrev(null);

			cfr = last.getChronoFullRevision();
			totalSize += cfr.size()
					- cfr.clean(revisionIndex, last.getRevisionIndex());

			if (last == first) {
				first = null;
			}

			// Set the new last
			last = block;
		}

		
	}
625068
private function getRecomUser($each_recom)
    {
        $user = $each_recom->find('.users', 0)->plaintext;
        $user = str_replace(['Users', 'User'], '', $user);

        return trim($user);
    }
50328
public static function clean($path, $dirSep = DIRECTORY_SEPARATOR): string
    {
        if (!is_string($path) || empty($path)) {
            return '';
        }

        $path = trim((string)$path);

        if (empty($path)) {
            $path = Vars::get($_SERVER['DOCUMENT_ROOT'], '');
        } elseif (($dirSep === '\\') && ($path[0] === '\\') && ($path[1] === '\\')) {
            $path = "\\" . preg_replace('#[/\\\\]+#', $dirSep, $path);
        } else {
            $path = preg_replace('#[/\\\\]+#', $dirSep, $path);
        }

        return $path;
    }
1110258
public function getLastPublishedString($format = \DateTime::ISO8601)
    {
        $date = $this->getLastPublished();

        if (empty($date)) {
            return null;
        }

        return $date->format($format);
    }
956257
public function doArchive($data, $form)
    {
        /** @var Versioned|DataObject $record */
        $record = $this->getRecord();
        if (!$record->canArchive()) {
            return $this->httpError(403);
        }

        // Record name before it's deleted
        $title = $record->Title;
        $record->doArchive();

        $message = _t(
            __CLASS__ . '.Archived',
            'Archived {name} {title}',
            [
                'name' => $record->i18n_singular_name(),
                'title' => Convert::raw2xml($title)
            ]
        );
        $this->setFormMessage($form, $message);

        //when an item is deleted, redirect to the parent controller
        $controller = $this->getToplevelController();
        $controller->getRequest()->addHeader('X-Pjax', 'Content'); // Force a content refresh

        return $controller->redirect($this->getBackLink(), 302); //redirect back to admin section
    }
826310
public function doesRecordNeedUpdate(GedcomRecord $record): bool
    {
        $gedcom = $record->gedcom();

        return !$this->error && preg_match('/(?:' . $this->regex . ')/mu' . $this->case, $gedcom);
    }
344399
public function chgrp( $filename, $group, $recursive = false )
    {
        return $this->SFTPObject->chgrp($filename, $group, $recursive);
	}
574540
public function getAndRemove(string $key, $default = null)
	{
		$storedValue = $this->get($key, $default);

		$this->remove($key);

		return $storedValue;
	}
919506
public static function lastChangeComparator(int $direction = 1): Closure
    {
        return static function (GedcomRecord $x, GedcomRecord $y) use ($direction): int {
            return $direction * ($x->lastChangeTimestamp() <=> $y->lastChangeTimestamp());
        };
    }
645212
public function summary(): string
    {
        $attributes = [];
        $target     = $this->target();
        if ($target instanceof GedcomRecord) {
            $attributes[] = $target->fullName();
        } else {
            // Fact value
            $value = $this->value();
            if ($value !== '' && $value !== 'Y') {
                $attributes[] = '<span dir="auto">' . e($value) . '</span>';
            }
            // Fact date
            $date = $this->date();
            if ($date->isOK()) {
                if ($this->record() instanceof Individual && in_array($this->getTag(), Gedcom::BIRTH_EVENTS, true) && $this->record()->tree()->getPreference('SHOW_PARENTS_AGE')) {
                    $attributes[] = $date->display() . FunctionsPrint::formatParentsAges($this->record(), $date);
                } else {
                    $attributes[] = $date->display();
                }
            }
            // Fact place
            if ($this->place()->gedcomName() !== '') {
                $attributes[] = $this->place()->shortName();
            }
        }

        $class = 'fact_' . $this->getTag();
        if ($this->isPendingAddition()) {
            $class .= ' new';
        } elseif ($this->isPendingDeletion()) {
            $class .= ' old';
        }

        return
            '<div class="' . $class . '">' .
            /* I18N: a label/value pair, such as “Occupation: Farmer”. Some languages may need to change the punctuation. */
            I18N::translate('<span class="label">%1$s:</span> <span class="field" dir="auto">%2$s</span>', $this->label(), implode(' — ', $attributes)) .
            '</div>';
    }