<?php

namespace Comitium5\DesignerBundle\Helper;

use Cocur\Slugify\Slugify;
use Comitium5\ApiClientBundle\ApiClient\ResourcesTypes;
use Comitium5\DesignerBundle\Helper\SlugStopWordsHelper;
use Comitium5\DesignerBundle\Provider\SlugRulesProvider;
use ErrorException;


/**
 * Class CSUtils
 *
 * All the utilities for development
 *
 * @author Fernando Pradas <fernando@bab-soft.com>
 * @author Sergio de Candelario <sergio@bab-soft.com>
 * @package Comitium5\DesignerBundle\Helper
 */
final class Utils
{
    /**
     * Return date in specific format from calendar format
     * @access public
     * @static
     * @param string $date
     * @param string $format (optional)
     * @return string
     */
    public static function getDateFromCalendar(string $date, $format = 'Y-m-d H:i:s')
    {
        $result = false;
        $date = trim($date);
        $expRegDate = "/^\d{2}-\d{2}-\d{4}$/";
        $expRegDatetime = "/^(\d{2})-(\d{2})-(\d{4}) (\d{2}:\d{2}:\d{2})(\.\d+)?$/";
        $expRegDatetime2 = "/^(\d{2})-(\d{2})-(\d{4}) (\d{2}:\d{2})$/";

        $date = preg_replace('/[\/\.\-]/', '-', $date);
        if (preg_match($expRegDate, $date)) {
            $date .= " 00:00:00";
        } elseif (preg_match($expRegDatetime2, $date)) {
            $date .= ":00";
        }

        $data = array();
        if (preg_match($expRegDatetime, $date, $data)) {
            if (count($data) > 4) {
                $result = self::getDate($data[3]."-".$data[2]."-".$data[1]." ".$data[4], $format);
            }
        }

        return $result;
    }

    /**
     * Return date in specific format
     * @access public
     * @static
     * @param string $date
     * @param string $format (optional)
     * @return string
     */
    public static function getDate(string $date, $format = 'd/m/Y H:i')
    {
        $result = false;

        if ($date && $date != '0000-00-00 00:00:00' && $date != '0000-00-00') {
            $date = self::getDateTime($date);
            if ($date != null) {
                $result = $date->format($format);
            }
        }

        return $result;
    }

    /**
     * Return current time or time from date
     * @access public
     * @static
     * @param  string $date    (optional)
     * @param  bool   $current (optional)
     * @return int
     */
    public static function getTime($date = false, $current = true)
    {
        $result = false;
        $expRegDate = "/^\d{4}-\d{2}-\d{2}$/";
        $expRegDatetime = "/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}(:\d{2}(\.\d+)?)?$/";

        if ($date) {
            if (is_numeric($date) && $date > 0) {
                $result = $date;
            } else {
                if (is_array($date) && isset($date['date'])) {
                    $date = $date['date'];
                }
                $date = trim($date);
                if (!preg_match($expRegDate, $date) && !preg_match($expRegDatetime, $date)) {
                    $date = self::getDateFromCalendar($date);
                }
                if (is_string($date) && $date != '0000-00-00 00:00:00' && $date != '0000-00-00') {
                    if (preg_match($expRegDate, $date)) {
                        $date = $date." 00:00:00";
                    }
                    if (preg_match($expRegDatetime, $date)) {
                        $result = strtotime($date);
                    }
                }
            }
        }
        if ($result === false && $current) {
            $result = time();
        }

        return $result;
    }

    /**
     * Return DateTime from string date
     * @access public
     * @static
     * @param  mixed     $date
     * @return \DateTime
     */
    public static function getDateTime($date)
    {
        $result = null;

        if ($date instanceof \DateTime) {
            $result = $date;
        } else {
            $info = self::getTime($date, false);
            if ($info !== false) {
                $result = new \DateTime();
                $result->setTimestamp($info);
            }
        }

        return $result;
    }

    /**
     * Convert all applicable characters to HTML entities
     *
     * @access public
     * @static
     *
     * @param $string
     * @param $flags
     * @param string $encoding      (optional)
     * @param bool   $double_encode (optional)
     *
     * @return string
     */
    public static function htmlentities($string, $flags = ENT_COMPAT, $encoding = "UTF-8", $double_encode = true)
    {
        return htmlentities($string, $flags, $encoding, $double_encode);
    }

    /**
     * @param $errno
     * @param $errstr
     * @param $errfile
     * @param $errline
     *
     * @throws ErrorException
     */
    public static function specificErrorHandler($errno, $errstr, $errfile, $errline)
    {
        if ($errno != E_STRICT && $errno != E_DEPRECATED && $errno != E_NOTICE && $errno != E_WARNING) {
            throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
        }
    }

    /**
     * @param $errno
     * @param $errstr
     * @param $errfile
     * @param $errline
     *
     * @return bool
     */
    public static function errorHandler($errno, $errstr, $errfile, $errline)
    {
        return false;
    }

    /**
     * If you want to clone any realted object or set any default value use the __clone() magic function in the object
     *
     * @access public
     * @static
     *
     * @param  mixed $object
     * @return mixed
     */
    public static function cloneObject($object)
    {
        if (function_exists('clone')) {
            $result = clone($object);
        } else {
            $result = unserialize(serialize($object));
        }

        return $result;
    }

    /**
     * Make a curl petition
     *
     * @access public
     * @static
     *
     * @param $url
     *
     * @return mixed
     */
    public static function curl($url)
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        $data = curl_exec($ch);
        curl_close($ch);

        return $data;
    }

    /**
     * Turn on output buffering
     *
     * @access public
     * @static
     *
     * @param callable|null $output_callback
     * @param int $chunk_size
     * @param int $flags
     */
    public static function bufferStart(
        callable $output_callback = null,
        $chunk_size = 0,
        $flags = PHP_OUTPUT_HANDLER_STDFLAGS
    ) {
        ob_start($output_callback, $chunk_size, $flags);
    }

    /**
     * Clean (erase) the output buffer
     *
     * @access public
     * @static
     *
     * @return void
     */
    public static function bufferClean()
    {
        ob_clean();
    }

    /**
     * Return the contents of the output buffer
     *
     * @access public
     * @static
     *
     * @return string
     */
    public static function bufferContents()
    {
        return ob_get_contents();
    }

    /**
     * Flush (send) the output buffer
     *
     * @access public
     * @static
     *
     * @return void
     */
    public static function bufferFlush()
    {
        ob_flush();
    }

    /**
     * Cut part of a text
     *
     * @access public
     * @static
     *
     * @param string $text
     * @param int $maxChars
     * @param string $charsAddEnd
     *
     * @return string
     */
    public static function cutText(string $text, int $maxChars, $charsAddEnd = '...')
    {
        $excludedChars = array(',', '.', '(', '{', '¿', '¡', '[');
        $textAux = self::cleanText($text);

        if(strlen($textAux) > $maxChars){
            $text = substr($textAux, 0, $maxChars);
            $position = strrpos($text, ' ');

            if ($position !== false) {
                if(in_array($text{$position-1}, $excludedChars))
                    $position--;
                $text = substr($text, 0, $position).$charsAddEnd;
            } else
                $text .= $charsAddEnd;
        }

        return $text;
    }

    /**
     * Encode in json
     *
     * @access public
     * @static
     *
     * @param $value
     * @param  string $toCharset   (optional)
     * @param  string $fromCharset (optional)
     * @return string
     */
    public static function encode($value, $toCharset = 'UTF-8', $fromCharset = 'ASCII,ISO-8859-1,UTF-8')
    {
        mb_convert_variables($toCharset, $fromCharset, $value);

        return $value;
    }

    /**
     * Decode entities as &#39
     *
     * @param $input
     *
     * @param string $to
     * @param string $from
     *
     * @return mixed
     */
    public static function decodeSpecialEntities($input, $to = 'UTF-8', $from = 'HTML-ENTITIES')
    {
        $input = str_replace(['&nbsp;'], '', $input);

        return preg_replace_callback("/(&#[0-9]+;)/", function ($m) use ($to, $from) {
            return mb_convert_encoding($m[1], $to, $from);
        }, $input);
    }

    /**
     * Return the class of the passed object
     *
     * @access public
     * @static
     *
     * @param mixed $object
     *
     * @return string
     */
    public static function getClassName($object)
    {
        $path = explode('\\', self::getClass($object));

        return array_pop($path);
    }

    /**
     * Return the FQDN of class the passed object
     *
     * @access public
     * @static
     *
     * @param mixed $object
     *
     * @return string
     */
    public static function getClass($object)
    {
        return str_replace("Proxies\\__CG__\\", "", get_class($object));
    }

    /**
     * Serialize an object
     *
     * @access public
     * @static
     *
     * @param $object
     *
     * @return string
     */
    public static function serialize($object)
    {
        return serialize($object);
    }

    /**
     * Unserialize an object
     *
     * @param $object
     *
     * @access public
     * @static
     *
     * @return mixed
     */
    public static function unserialize($object)
    {
        return unserialize($object);
    }

    /**
     * Encode to JSON
     * @access public
     * @static
     * @param  mixed  $data
     * @return string
     */
    public static function toJson($data, $options = 0)
    {
        return json_encode($data, $options);
    }

    /**
     * @param $data
     * @param bool $assoc
     *
     * @return mixed
     */
    public static function fromJson($data, $assoc = true)
    {
        return json_decode($data, $assoc);
    }

    /**
     * Check if a string match the regular expresions
     *
     * @param $pattern
     * @param $subject
     * @param $matches
     * @param bool $all    (optional)
     * @param int  $flags  (optional)
     * @param int  $offset (optional)
     *
     * @return int
     */
    public static function match($pattern, $subject, &$matches, $all = true, $flags = PREG_PATTERN_ORDER, $offset = 0)
    {
        if ($all) {
            $result = preg_match_all($pattern, $subject, $matches, $flags, $offset);
        } else {
            $result = preg_match($pattern, $subject, $matches, $flags, $offset);
        }

        return $result;
    }

    /**
     * @param $string
     * @param string $separator
     *
     * @return string
     */
    public static function makeSlug($string, $separator = "-")
    {
        if ($string === "/") {
            return $string;
        }

        $slugify = new Slugify();

        return $slugify->slugify($string, $separator);
    }

    /**
     * @param $string
     * @param string $separator
     * @param array $extraStopWords
     *
     * @return string
     */
    public static function makeSlugWithStopWords($string, $separator = "-",array $extraStopWords = [])
    {
        if ($string === "/") {
            return $string;
        }

        $string = SlugStopWordsHelper::removeStopWords($string, $extraStopWords);

        $slugify = new Slugify(
            [
                'rulesets' => ['default']
            ],
            new SlugRulesProvider()
        );

        return $slugify->slugify($string, $separator);
    }

    /**
     * @access public
     * @static
     * @param string $email
     * @return bool
     */
    public static function isEmail(string $email)
    {
        //return preg_match('/^[a-z0-9_\.\-]+\@[a-z0-9_\.\-]+\.[a-z]{2,4}$/i', $email);
        return (filter_var($email, FILTER_VALIDATE_EMAIL) !== false);
    }

    /**
     * @param $class
     * @param $method
     *
     * @return bool
     */
    public static function methodExists($class, $method)
    {
        return method_exists($class, $method);
    }

    /**
     * @param $content
     *
     * @return string
     */
    public static function checksum($content)
    {
        return Utils::md5($content);
    }

    /**
     * @param $content
     *
     * @return string
     */
    public static function md5($content)
    {
        return hash('md5', $content);
    }

    /**
     * @param $className
     *
     * @return string
     */
    public static function getEntityName($className)
    {
        return strtolower(preg_replace("/(?:\\w*\\\\)+(\\w*)/", "$1", $className));
    }

    /**
     * @static
     * @param string $text
     * @return string
     */
    public static function cleanText(string $text)
    {
        $text = self::replaceSpecialChars($text);

        return preg_replace('/[\n\r\t\s]+/', ' ', strip_tags(
            html_entity_decode(trim($text))
        ));
    }

    /**
     * @param $input
     *
     * @return mixed
     */
    public static function replaceSpecialChars($input)
    {
        $htmlSpecialEntities = ['&nbsp;','&ldquo;','&rdquo;','&lsquo;','&rsquo;','&#63;','&#664;','&#8200;','“','”','‘','’','&#8217;','&#8220;','&#8221;','&#149;','&#183;','&#191;','&#8216;','&#8208;','&#147;','&#148;','&#145;','&#146;','&#39;'];
        $replaceHtmlSpecialEntities = [' ','"','"','\'','\'','?','·',' ','"','"','\'','\'','\'','"','"','·','·','¿','\'','-','"','"','\'','\'','\''];

        return str_replace($htmlSpecialEntities, $replaceHtmlSpecialEntities, $input);
    }

    /**
     * @static
     * @param string $text
     * @return string
     */
    public static function cleanTextWithoutStripTags(string $text)
    {
        return preg_replace('/[\n\r\t\s]+/', ' ',
            html_entity_decode(trim($text)
            ));
    }

    /**
     * @param $inputText
     *
     * @return int
     */
    public static function isUrl($inputText)
    {
        return \filter_var($inputText, FILTER_VALIDATE_URL);
    }

    /**
     * @param $inputText
     *
     * @return bool|int
     */
    public static function isIframe($inputText)
    {
        return strpos($inputText, 'iframe');
    }

    /**
     * Transforms an under_scored_string to a camelCasedOne
     * @param $scored
     * @param string $separator
     * @return string
     */
    public static function camelize($scored, string $separator = '_')
    {
        return lcfirst(self::upperCamelize($scored, $separator));
    }

    /**
     * @param $scored
     * @param string $separator
     *
     * @return string
     */
    public static function upperCamelize($scored, $separator = '_')
    {
        return implode(
            '',
            array_map(
                'ucfirst',
                array_map(
                    'strtolower',
                    explode(
                        $separator, $scored))));
    }

    /**
     * Transforms a camelCasedString to an under_scored_one
     * @param $cameled
     * @return string
     */
    public static function underscore($cameled)
    {
        return implode(
            '_',
            array_map(
                'strtolower',
                preg_split('/([A-Z]{1}[^A-Z]*)/', $cameled, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY)));
    }

    /**
     * Get entity name type
     * used in services naming
     *
     * @param $entity
     *
     * @return string|false
     */
    public static function getEntityNameType($entity)
    {
        try {
            $reflection = new \ReflectionClass($entity);

            return self::underscore($reflection->getShortName());
        } catch (\Exception $e) {
            return false;
        }
    }

    /**
     * @return string
     */
    public static function uuidV4()
    {
        // fix for compatibility with 32bit architecture; seed range restricted to 62bit
        $seed = mt_rand(0, 2147483647) . '#' . mt_rand(0, 2147483647);

        // Hash the seed and convert to a byte array
        $val  = md5($seed, true);
        $byte = array_values(unpack('C16', $val));

        // extract fields from byte array
        $tLo  = ($byte[0] << 24) | ($byte[1] << 16) | ($byte[2] << 8) | $byte[3];
        $tMi  = ($byte[4] << 8) | $byte[5];
        $tHi  = ($byte[6] << 8) | $byte[7];
        $csLo = $byte[9];
        $csHi = $byte[8] & 0x3f | (1 << 7);

        // correct byte order for big edian architecture
        if (pack('L', 0x6162797A) == pack('N', 0x6162797A)) {
            $tLo = (($tLo & 0x000000ff) << 24) | (($tLo & 0x0000ff00) << 8)
                | (($tLo & 0x00ff0000) >> 8) | (($tLo & 0xff000000) >> 24);
            $tMi = (($tMi & 0x00ff) << 8) | (($tMi & 0xff00) >> 8);
            $tHi = (($tHi & 0x00ff) << 8) | (($tHi & 0xff00) >> 8);
        }

        // apply version number
        $tHi &= 0x0fff;
        $tHi |= (3 << 12);

        // cast to string
        return sprintf(
            '%08x-%04x-%04x-%02x%02x-%s%02x',
            $tLo,
            $tMi,
            $tHi,
            $csHi,
            $csLo,
            time(),
            $byte[15]
        );
    }

    /**
     * Get char list.
     *
     * @return string
     */
    public static function getCharList()
    {
        return "ÀàÁáÈèÉéÍíÒòÓóÚúÄãËëÏïÖöÜüÇç'’-ñ";
    }

    /**
     * @param $input
     *
     * @return mixed
     */
    public static function removeWitheSpaces($input)
    {
        return preg_replace('/(\s\s+|\t|\n|\.|\,|\;)/', ' ', $input);
    }

    /**
     * @param $badStr
     *
     * @return mixed
     */
    public static function html2text($badStr)
    {
        //remove PHP if it exists
        while (substr_count($badStr, '<'.'?') && substr_count($badStr, '?'.'>') && strpos($badStr, '?'.'>', strpos($badStr, '<'.'?')) > strpos($badStr, '<'.'?')) {
            $badStr = substr($badStr, 0, strpos($badStr, '<'.'?')).substr($badStr, strpos($badStr, '?'.'>', strpos($badStr, '<'.'?')) + 2);
        }
        //remove comments
        while (substr_count($badStr, '<!--') && substr_count($badStr, '-->') && strpos($badStr, '-->', strpos($badStr, '<!--')) > strpos($badStr, '<!--')) {
            $badStr = substr($badStr, 0, strpos($badStr, '<!--')).substr($badStr, strpos($badStr, '-->', strpos($badStr, '<!--')) + 3);
        }
        //now make sure all HTML tags are correctly written (> not in between quotes)
        for ($x = 0, $goodStr = '', $is_open_tb = false, $is_open_sq = false, $is_open_dq = false; $x < strlen($badStr); $x++) {
            //take each letter in turn and check if that character is permitted there
            $chr = $badStr{$x};
            switch ($chr) {
                case '<':
                    if (!$is_open_tb && strtolower(substr($badStr, $x + 1, 5)) == 'style') {
                        $badStr = substr($badStr, 0, $x).substr($badStr, strpos(strtolower($badStr), '</style>', $x) + 7);
                        $chr = '';
                    } elseif (!$is_open_tb && strtolower(substr($badStr, $x + 1, 6)) == 'script') {
                        $badStr = substr($badStr, 0, $x).substr($badStr, strpos(strtolower($badStr), '</script>', $x) + 8);
                        $chr = '';
                    } elseif (!$is_open_tb) {
                        $is_open_tb = true;
                    } else {
                        $chr = '&lt;';
                    }
                    break;
                case '>':
                    if (!$is_open_tb || $is_open_dq || $is_open_sq) {
                        $chr = '&gt;';
                    } else {
                        $is_open_tb = false;
                    }
                    break;
                case '"':
                    if ($is_open_tb && !$is_open_dq && !$is_open_sq) {
                        $is_open_dq = true;
                    } elseif ($is_open_tb && $is_open_dq && !$is_open_sq) {
                        $is_open_dq = false;
                    } else {
                        $chr = '&quot;';
                    }
                    break;
                case "'":
                    if ($is_open_tb && !$is_open_dq && !$is_open_sq) {
                        $is_open_sq = true;
                    } elseif ($is_open_tb && !$is_open_dq && $is_open_sq) {
                        $is_open_sq = false;
                    }
            }
            $goodStr .= $chr;
        }
        //now that the page is valid (I hope) for strip_tags, strip all unwanted tags
        $goodStr = strip_tags($goodStr, '<title><hr><h1><h2><h3><h4><h5><h6><div><p><pre><sup><ul><ol><br><dl><dt><table><caption><tr><li><dd><th><td><a><area><img><form><input><textarea><button><select><option>');
        //strip extra whitespace except between <pre> and <textarea> tags
        $badStr = preg_split("/<\/?pre[^>]*>/i", $goodStr);
        for ($x = 0; $x < count($badStr); $x++) {
            if ($x % 2) {
                $badStr[$x] = '<pre>'.$badStr[$x].'</pre>';
            } else {
                $goodStr = preg_split("/<\/?textarea[^>]*>/i", $badStr[$x]);
                for ($z = 0; $z < count($goodStr); $z++) {
                    if ($z % 2) {
                        $goodStr[$z] = '<textarea>'.$goodStr[$z].'</textarea>';
                    } else {
                        $goodStr[$z] = preg_replace("/\s+/", ' ', $goodStr[$z]);
                    }
                }
                $badStr[$x] = implode('', $goodStr);
            }
        }
        $goodStr = implode('', $badStr);
        //remove all options from select inputs
        $goodStr = preg_replace("/<option[^>]*>[^<]*/i", '', $goodStr);
        //replace all tags with their text equivalents
        $goodStr = preg_replace("/<(\/title|hr)[^>]*>/i", "\n          --------------------\n", $goodStr);
        $goodStr = preg_replace("/<(h|div|p)[^>]*>/i", "\n\n", $goodStr);
        $goodStr = preg_replace("/<sup[^>]*>/i", '^', $goodStr);
        $goodStr = preg_replace("/<(ul|ol|br|dl|dt|table|caption|\/textarea|tr[^>]*>\s*<(td|th))[^>]*>/i", "\n", $goodStr);
        $goodStr = preg_replace("/<li[^>]*>/i", "\n", $goodStr);
        $goodStr = preg_replace("/<dd[^>]*>/i", "\n\t", $goodStr);
        $goodStr = preg_replace("/<(th|td)[^>]*>/i", "\t", $goodStr);
        //$goodStr = preg_replace( "/<a[^>]* href=(\"((?!\"|#|javascript:)[^\"#]*)(\"|#)|'((?!'|#|javascript:)[^'#]*)('|#)|((?!'|\"|>|#|javascript:)[^#\"'> ]*))[^>]*>/i", "[LINK: $2$4$6] ", $goodStr );
        $goodStr = preg_replace("/<a[^>]* href=(\"((?!\"|#|javascript:)[^\"#]*)(\"|#)|'((?!'|#|javascript:)[^'#]*)('|#)|((?!'|\"|>|#|javascript:)[^#\"'> ]*))[^>]*>/i", "", $goodStr);
        $goodStr = preg_replace("/<img[^>]* alt=(\"([^\"]+)\"|'([^']+)'|([^\"'> ]+))[^>]*>/i", "[IMAGE: $2$3$4] ", $goodStr);
        $goodStr = preg_replace("/<form[^>]* action=(\"([^\"]+)\"|'([^']+)'|([^\"'> ]+))[^>]*>/i", "\n[FORM: $2$3$4] ", $goodStr);
        $goodStr = preg_replace("/<(input|textarea|button|select)[^>]*>/i", "[INPUT] ", $goodStr);
        //strip all remaining tags (mostly closing tags)
        $goodStr = strip_tags($goodStr);
        //convert HTML entities
        $goodStr = strtr($goodStr, array_flip(get_html_translation_table(HTML_ENTITIES)));
        preg_replace("/&#(\d+);/me", "chr('$1')", $goodStr);
        //wordwrap
        $goodStr = wordwrap($goodStr);
        //make sure there are no more than 3 linebreaks in a row and trim whitespace
        return preg_replace("/^\n*|\n*$/", '', preg_replace("/[ \t]+(\n|$)/", "$1", preg_replace("/\n(\s*\n){2}/", "\n\n\n", preg_replace("/\r\n?|\f/", "\n", str_replace(chr(160), ' ', $goodStr)))));
    }

    /**
     * Get either a Gravatar URL or complete image tag for a specified email address.
     *
     * @param string $email The email address
     * @param int $s Size in pixels, defaults to 80px [ 1 - 2048 ]
     * @param string $d Default imageset to use [ 404 | mm | identicon | monsterid | wavatar ]
     * @param string $r Maximum rating (inclusive) [ g | pg | r | x ]
     * @param bool $img True to return a complete IMG tag False for just the URL
     * @param array $attributes Optional, additional key/value attributes to include in the IMG tag
     * @return String containing either just a URL or a complete image tag
     * @source http://gravatar.com/site/implement/images/php/
     */
    public static function getGravatar(string $email, $s = 80, $d = 'mm', $r = 'g', $img = false, array $attributes = [])
    {
        $url = 'https://www.gravatar.com/avatar/';
        $url .= md5(strtolower(trim($email)));
        $url .= "?s=$s&d=$d&r=$r";

        if ($img !== false) {
            $url = '<img src="'.$url.'"';
            foreach ($attributes as $key => $val) {
                $url .= ' '.$key.'="'.$val.'"';
            }
            $url .= ' />';
        }

        return $url;
    }

    /**
     * @param $string
     * @return string
     */
    public static function strToLower($string)
    {
        return mb_strtolower($string);
    }

    /**
     * @return string
     */
    public static function patternUrl()
    {
        return "/(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?/";
    }

    /**
     * @param $extension
     * @return bool
     */
    public static function isJpeg($extension)
    {
        return preg_match("/(jpg)|(jpeg)/", $extension) === 1;
    }

    /**
     * @param $extension
     * @return bool
     */
    public static function isPng($extension)
    {
        return preg_match("/png/", $extension) === 1;
    }

    /**
     * @param $extension
     * @return bool
     */
    public static function isGif($extension)
    {
        return preg_match("/gif/", $extension) === 1;
    }

    /**
     * @param $entityClass
     * @return mixed
     */
    public static function resolveEntityType($entityClass)
    {
        $constant = strtoupper(self::getEntityNameType($entityClass));
        $reflection = new \ReflectionClass(ResourcesTypes::class);

        return $reflection->getConstant($constant);
    }

    /**
     * @param $entityClass
     * @return mixed
     */
    public static function resolveEntityTypeCode($entityClass)
    {
        $constant = strtoupper(self::getEntityNameType($entityClass));
        $reflection = new \ReflectionClass(ResourcesTypes::class);

        return $reflection->getConstant($constant. "_CODE");
    }

    /**
     * @param $url
     * @param null $key
     * @return mixed|null
     */
    public static function parseUrl($url, $key = null)
    {
        $parse = parse_url($url);

        if ($key === null) {
            return $parse;
        }

        return isset($parse[$key]) ? $parse[$key] : null;
    }

    /**
     * @param $url
     * @return string
     */
    public static function getTwitterUsername($url)
    {
        preg_match('/(https\:\/\/|http\:\/\/)?(?:www\.)?twitter\.com\/(#!\/)?([A-z0-9-]+)/', $url, $matches);

        return isset($matches[3]) ? $matches[3] : '';
    }

    /**
     * @param $url
     * @return string
     */
    public static function getFacebookUsername($url)
    {
        preg_match('/(https\:\/\/|http\:\/\/)?(?:www\.)?facebook\.com\/(#!\/)?([A-z0-9-]+)/', $url, $matches);

        return isset($matches[3]) ? $matches[3] : '';
    }

    /**
     * @param $url
     * @return string
     */
    public static function getLinkedinUsername($url)
    {
        preg_match('/(https\:\/\/|http\:\/\/)?(?:www\.)?linkedin\.com\/(in\/)?([A-z0-9-]+)/', $url, $matches);

        return isset($matches[3]) ? $matches[3] : '';
    }

    /**
     * @param $url
     * @return string
     */
    public static function getGooglePlusUsername($url)
    {
        preg_match('/(https\:\/\/|http\:\/\/)?plus.google\.com\/([A-z0-9-+]+)/', $url, $matches);

        return isset($matches[3]) ? $matches[3] : '';
    }

    /**
     * @param $input
     *
     * @return false|string
     */
    public static function iconvFromUtf8($input)
    {
        return iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE',$input);
    }
}
