]> git.mxchange.org Git - friendica.git/blobdiff - src/Util/Strings.php
Add new contact/{id}/contacts[/{type}] route and module
[friendica.git] / src / Util / Strings.php
index f91a78d66c802dc3ef0fcb9dad5a92f53382bb44..1d440c19b7eede0aef7e7cd9b8ec13aea6df6c3c 100644 (file)
@@ -1,7 +1,22 @@
 <?php
-
 /**
- * @file src/Util/Strings.php
+ * @copyright Copyright (C) 2020, Friendica
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
  */
 
 namespace Friendica\Util;
@@ -10,12 +25,12 @@ use Friendica\Content\ContactSelector;
 use Friendica\Core\Logger;
 
 /**
- * @brief This class handles string functions
+ * This class handles string functions
  */
 class Strings
 {
        /**
-        * @brief Generates a pseudo-random string of hexadecimal characters
+        * Generates a pseudo-random string of hexadecimal characters
         *
         * @param int $size
         * @return string
@@ -45,7 +60,7 @@ class Strings
        }
 
        /**
-        * @brief This is our primary input filter.
+        * This is our primary input filter.
         *
         * Use this on any text input where angle chars are not valid or permitted
         * They will be replaced with safer brackets. This may be filtered further
@@ -60,7 +75,7 @@ class Strings
        }
 
        /**
-        * @brief Use this on "body" or "content" input where angle chars shouldn't be removed,
+        * Use this on "body" or "content" input where angle chars shouldn't be removed,
         * and allow them to be safely displayed.
         * @param string $string
         *
@@ -72,7 +87,7 @@ class Strings
        }
 
        /**
-        * @brief Generate a string that's random, but usually pronounceable. Used to generate initial passwords
+        * Generate a string that's random, but usually pronounceable. Used to generate initial passwords
         *
         * @param int $len      length
         *
@@ -179,7 +194,7 @@ class Strings
        }
 
        /**
-        * @brief Remove indentation from a text
+        * Remove indentation from a text
         *
         * @param string $text  String to be transformed.
         * @param string $chr   Optional. Indentation tag. Default tab (\t).
@@ -209,7 +224,7 @@ class Strings
        }
 
        /**
-        * @brief Get byte size returned in a Data Measurement (KB, MB, GB)
+        * Get byte size returned in a Data Measurement (KB, MB, GB)
         *
         * @param int $bytes    The number of bytes to be measured
         * @param int $precision        Optional. Default 2.
@@ -228,7 +243,7 @@ class Strings
        }
 
        /**
-        * @brief Protect percent characters in sprintf calls
+        * Protect percent characters in sprintf calls
         *
         * @param string $s String to transform.
         *
@@ -240,7 +255,7 @@ class Strings
        }
 
        /**
-        * @brief Base64 Encode URL and translate +/ to -_ Optionally strip padding.
+        * Base64 Encode URL and translate +/ to -_ Optionally strip padding.
         *
         * @param string $s                                     URL to encode
         * @param boolean $strip_padding        Optional. Default false
@@ -259,7 +274,7 @@ class Strings
        }
 
        /**
-        * @brief Decode Base64 Encoded URL and translate -_ to +/
+        * Decode Base64 Encoded URL and translate -_ to +/
         * @param string $s URL to decode
         *
         * @return string       Decoded URL
@@ -292,7 +307,7 @@ class Strings
        }
 
        /**
-        * @brief Normalize url
+        * Normalize url
         *
         * @param string $url   URL to be normalized.
         *
@@ -305,7 +320,7 @@ class Strings
        }
 
        /**
-        * @brief Normalize OpenID identity
+        * Normalize OpenID identity
         *
         * @param string $s OpenID Identity
         *
@@ -317,7 +332,7 @@ class Strings
        }
 
        /**
-        * @brief Compare two URLs to see if they are the same, but ignore
+        * Compare two URLs to see if they are the same, but ignore
         * slight but hopefully insignificant differences such as if one
         * is https and the other isn't, or if one is www.something and
         * the other isn't - and also ignore case differences.
@@ -354,13 +369,43 @@ class Strings
         * @param array  $chars
         * @return bool
         */
-       public static function startsWith($string, array $chars)
+       public static function startsWithChars($string, array $chars)
        {
                $return = in_array(substr(trim($string), 0, 1), $chars);
 
                return $return;
        }
 
+       /**
+        * Check if the first string starts with the second
+        *
+        * @see http://maettig.com/code/php/php-performance-benchmarks.php#startswith
+        * @param string $string
+        * @param string $start
+        * @return bool
+        */
+       public static function startsWith(string $string, string $start)
+       {
+               $return = substr_compare($string, $start, 0, strlen($start)) === 0;
+
+               return $return;
+       }
+
+       /**
+        * Checks if the first string ends with the second
+        *
+        * @see http://maettig.com/code/php/php-performance-benchmarks.php#endswith
+        * @param string $string
+        * @param string $end
+        * @return bool
+        */
+       public static function endsWith(string $string, string $end)
+       {
+               $return = substr_compare($string, $end, -strlen($end)) === 0;
+
+               return $return;
+       }
+
        /**
         * Returns the regular expression string to match URLs in a given text
         *
@@ -405,4 +450,90 @@ class Strings
 
                return $pathItem;
        }
+
+       /**
+        * Multi-byte safe implementation of substr_replace where $start and $length are character offset and count rather
+        * than byte offset and counts.
+        *
+        * Depends on mbstring, use default encoding.
+        *
+        * @param string   $string
+        * @param string   $replacement
+        * @param int      $start
+        * @param int|null $length
+        * @return string
+        * @see substr_replace()
+        */
+       public static function substringReplace(string $string, string $replacement, int $start, int $length = null)
+       {
+               $string_length = mb_strlen($string);
+
+               $length = $length ?? $string_length;
+
+               if ($start < 0) {
+                       $start = max(0, $string_length + $start);
+               } else if ($start > $string_length) {
+                       $start = $string_length;
+               }
+
+               if ($length < 0) {
+                       $length = max(0, $string_length - $start + $length);
+               } else if ($length > $string_length) {
+                       $length = $string_length;
+               }
+
+               if (($start + $length) > $string_length) {
+                       $length = $string_length - $start;
+               }
+
+               return mb_substr($string, 0, $start) . $replacement . mb_substr($string, $start + $length, $string_length - $start - $length);
+       }
+
+       /**
+        * Perform a custom function on a text after having escaped blocks matched by the provided regular expressions.
+        * Only full matches are used, capturing group are ignored.
+        *
+        * To change the provided text, the callback function needs to return it and this function will return the modified
+        * version as well after having restored the escaped blocks.
+        *
+        * @param string   $text
+        * @param string   $regex
+        * @param callable $callback
+        * @return string
+        * @throws \Exception
+        */
+       public static function performWithEscapedBlocks(string $text, string $regex, callable $callback)
+       {
+               // Enables nested use
+               $executionId = random_int(PHP_INT_MAX / 10, PHP_INT_MAX);
+
+               $blocks = [];
+
+               $text = preg_replace_callback($regex,
+                       function ($matches) use ($executionId, &$blocks) {
+                               $return = '«block-' . $executionId . '-' . count($blocks) . '»';
+
+                               $blocks[] = $matches[0];
+
+                               return $return;
+                       },
+                       $text
+               );
+
+               $text = $callback($text) ?? '';
+
+               // Restore code blocks
+               $text = preg_replace_callback('/«block-' . $executionId . '-([0-9]+)»/iU',
+                       function ($matches) use ($blocks) {
+                               $return = $matches[0];
+                               if (isset($blocks[intval($matches[1])])) {
+                                       $return = $blocks[$matches[1]];
+                               }
+                               return $return;
+                       },
+                       $text
+               );
+
+               return $text;
+       }
 }