<commit_before><?php

namespace duncan3dc\Helpers;

class Helper {


    /**
     * Simulated named arguments using associative arrays
     * Basically just merge the two arrays, giving user specified options the preference
     * Also ensures that each paramater in the user array is valid
     */
    public static function getOptions($userSpecified,$defaults) {

        $options = static::getAnyOptions($userSpecified,$defaults);

        foreach($options as $key => $null) {
            if(array_key_exists($key,$defaults)) {
                continue;
            }
            throw new \Exception("Unknown parameter (" . $key . ")");
        }

        return $options;

    }


    /**
     * This is a safe version of the getOptions() method
     * It allows any custom option key in the userSpecified array
     */
    public static function getAnyOptions($userSpecified,$defaults) {

        $options = $defaults;
        $userSpecified = static::toArray($userSpecified);

        foreach($userSpecified as $key => $val) {
            $options[$key] = $val;
        }

        return $options;

    }


    /**
     * Ensure that the passed parameter is a string, or an array of strings
     */
    public static function toString($data) {

        if(is_array($data)) {
            $newData = [];
            foreach($data as $key => $val) {
                $key = (string)$key;
                $newData[$key] = static::toString($val);
            }

        } else {
            $newData = (string)$data;

        }

        return $newData;

    }


    /**
     * Ensure that the passed parameter is an array
     */
    public static function toArray($value=false) {

        # If it's already an array then just pass it back
        if(is_array($value)) {
            return $value;
        }

        # If it's not an array then create a new array to be returned
        $array = [];

        # If a value was passed as a string/int then include it in the new array
        if($value) {
            $array[] = $value;
        }

        return $array;

    }


    public static function cleanupArray($array) {

        $newArray = [];

        $array = static::toArray($array);

        foreach($array as $key => $val) {

            if(is_array($val)) {
                $val = static::cleanupArray($val);

            } else {
                $val = trim($val);
                if(!$val) {
                    continue;
                }
            }

            $newArray[$key] = $val;

        }

        return $newArray;

    }


    public static function date($format,$date,$time=false) {

        if(!$date = trim($date)) {
            return 0;
        }

        if(preg_match("/[a-z]/i",$date)) {
            return 0;
        }

        # Define some time handling code to be used in several places below
        $timeFunc = function($time=false) {

            $return = [12,0,0];

            if(!$time) {
                return $return;
            }

            if(preg_match("/[a-z]/i",$date)) {
                return $return;
            }

            # Human readable format (h:i:s)
            if(strpos($time,":")) {
                return explode(":",$time);
            }

            # Sortable format (His)
            return [
                floor($time / 10000),
                floor(($time / 100) % 100),
                $time % 100,
            ];

        };

        # Sql date format (yyyy-mm-dd hh:ii:ss) (with optional milliseconds)
        if(preg_match("/^([0-9]{4})-([0-9]{2})-([0-9]{2})[\s-]([0-9]{2})[:\.]([0-9]{2})[:\.]([0-9]{2})(\.[0-9]{6})?$/",$date,$matches)) {
            list($null,$y,$m,$d,$h,$i,$s) = $matches;
            $date = mktime($h,$i,$s,$m,$d,$y);

            list($null,$y,$m,$d,$h,$i,$s) = $matches;
            $date = mktime($h,$i,$s,$m,$d,$y);

        # Human readable format (d/m/y or d-m-y)
        } elseif(strpos($date,"/") || strpos($date,"-")) {
            $char = (strpos($date,"/")) ? "/" : "-";
            if(!$time && strpos($date," ")) {
                list($date,$time) = explode(" ",$date);
            }
            list($d,$m,$y) = explode($char,$date);
            list($h,$i,$s) = $timeFunc($time);
            $date = mktime($h,$i,$s,$m,$d,$y);

        # Sortable format (YmdHi/YmdHis)
        } elseif($date > 200000000000) {
            $y = substr($date,0,4);
            $m = substr($date,4,2);
            $d = substr($date,6,2);
            $h = substr($date,8,2);
            $i = substr($date,10,2);
            $s = substr($date,12,2);<commit_msg>Added the universal human readable date format<commit_after><?php

namespace duncan3dc\Helpers;

class Helper {


    /**
     * Simulated named arguments using associative arrays
     * Basically just merge the two arrays, giving user specified options the preference
     * Also ensures that each paramater in the user array is valid
     */
    public static function getOptions($userSpecified,$defaults) {

        $options = static::getAnyOptions($userSpecified,$defaults);

        foreach($options as $key => $null) {
            if(array_key_exists($key,$defaults)) {
                continue;
            }
            throw new \Exception("Unknown parameter (" . $key . ")");
        }

        return $options;

    }


    /**
     * This is a safe version of the getOptions() method
     * It allows any custom option key in the userSpecified array
     */
    public static function getAnyOptions($userSpecified,$defaults) {

        $options = $defaults;
        $userSpecified = static::toArray($userSpecified);

        foreach($userSpecified as $key => $val) {
            $options[$key] = $val;
        }

        return $options;

    }


    /**
     * Ensure that the passed parameter is a string, or an array of strings
     */
    public static function toString($data) {

        if(is_array($data)) {
            $newData = [];
            foreach($data as $key => $val) {
                $key = (string)$key;
                $newData[$key] = static::toString($val);
            }

        } else {
            $newData = (string)$data;

        }

        return $newData;

    }


    /**
     * Ensure that the passed parameter is an array
     */
    public static function toArray($value=false) {

        # If it's already an array then just pass it back
        if(is_array($value)) {
            return $value;
        }

        # If it's not an array then create a new array to be returned
        $array = [];

        # If a value was passed as a string/int then include it in the new array
        if($value) {
            $array[] = $value;
        }

        return $array;

    }


    public static function cleanupArray($array) {

        $newArray = [];

        $array = static::toArray($array);

        foreach($array as $key => $val) {

            if(is_array($val)) {
                $val = static::cleanupArray($val);

            } else {
                $val = trim($val);
                if(!$val) {
                    continue;
                }
            }

            $newArray[$key] = $val;

        }

        return $newArray;

    }


    public static function date($format,$date,$time=false) {

        if(!$date = trim($date)) {
            return 0;
        }

        if(preg_match("/[a-z]/i",$date)) {
            return 0;
        }

        # Define some time handling code to be used in several places below
        $timeFunc = function($time=false) {

            $return = [12,0,0];

            if(!$time) {
                return $return;
            }

            if(preg_match("/[a-z]/i",$date)) {
                return $return;
            }

            # Human readable format (h:i:s)
            if(strpos($time,":")) {
                return explode(":",$time);
            }

            # Sortable format (His)
            return [
                floor($time / 10000),
                floor(($time / 100) % 100),
                $time % 100,
            ];

        };

        # Sql date format (yyyy-mm-dd hh:ii:ss) (with optional milliseconds)
        if(preg_match("/^([0-9]{4})-([0-9]{2})-([0-9]{2})[\s-]([0-9]{2})[:\.]([0-9]{2})[:\.]([0-9]{2})(\.[0-9]{6})?$/",$date,$matches)) {
            list($null,$y,$m,$d,$h,$i,$s) = $matches;
            $date = mktime($h,$i,$s,$m,$d,$y);

            list($null,$y,$m,$d,$h,$i,$s) = $matches;
            $date = mktime($h,$i,$s,$m,$d,$y);

        # Human readable universal format (yyyy-mm-dd)
        } elseif(preg_match("/^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})$/",$date,$matches)) {
            $date = mktime(12,0,0,$matches[2],$matches[3],$matches[1]);

        # Human readable format (d/m/y or d-m-y)
        } elseif(strpos($date,"/") || strpos($date,"-")) {
            $char = (strpos($date,"/")) ? "/" : "-";
            if(!$time && strpos($date," ")) {
                list($date,$time) = explode(" ",$date);
            }
            list($d,$m,$y) = explode($char,$date);
            list($h,$i,$s) = $timeFunc($time);
            $date = mktime($h,$i,$s,$m,$d,$y);

        # Sortable format (YmdHi/YmdHis)
        } elseif($date > 200000000000) {
            $y = substr($date,0,4);
            $m = substr($date,4,2);
            $d = substr($date,6,2);
            $h = substr($date,8,2);
            $i = substr($date,10,2);
            $s = substr($date,12,2);
{'fraction_non_alphanumeric': 0.1654063265523485, 'fraction_numerical': 0.016402172755352006, 'mean_word_length': 1.6473075838736961, 'pattern_counts': {'":': 4, '<': 5, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1403294', 'n_tokens_mistral': 2978, 'n_tokens_neox': 2775, 'n_words': 629}