1: <?php
2:
3: /**
4: * Jyxo PHP Library
5: *
6: * LICENSE
7: *
8: * This source file is subject to the new BSD license that is bundled
9: * with this package in the file license.txt.
10: * It is also available through the world-wide-web at this URL:
11: * https://github.com/jyxo/php/blob/master/license.txt
12: */
13:
14: namespace Jyxo;
15:
16: /**
17: * Base class for common string operations.
18: *
19: * @category Jyxo
20: * @package Jyxo\String
21: * @copyright Copyright (c) 2005-2011 Jyxo, s.r.o.
22: * @license https://github.com/jyxo/php/blob/master/license.txt
23: * @author Jan Tichý
24: * @author Jakub Tománek
25: * @author Jaroslav Hanslík
26: */
27: class String
28: {
29: /**
30: * Trims all words in a string longer than given length.
31: * String is delimited by whitespaces.
32: * If a word is trimmed, an "etc" is added at the end. Its length is also considered.
33: *
34: * @param string $string Processed string
35: * @param integer $length Maximum word length
36: * @param string $etc "etc" definition
37: * @return string
38: */
39: public static function cutWords($string, $length = 25, $etc = '...')
40: {
41: $length = (int) $length;
42:
43: return preg_replace_callback('~[^\s]{' . $length . ',}~', function($matches) use ($length, $etc) {
44: return String::cut($matches[0], $length, $etc);
45: }, $string);
46: }
47:
48: /**
49: * Trims a string to given length.
50: * Trims at word boundaries (all non-alphanumeric characters are considered delimiters).
51: * If the given string is trimmed, an "etc" is added at the end. Its length is also considered.
52: *
53: * @param string $string Trimmed string
54: * @param integer $max Maximum length
55: * @param string $etc "etc" definition
56: * @return string
57: */
58: public static function cut($string, $max = 50, $etc = '...')
59: {
60: // Trim whitespace
61: $string = trim($string);
62:
63: // No trimming is needed
64: if (mb_strlen($string, 'utf-8') <= $max) {
65: return $string;
66: }
67:
68: // Find out "etc" length
69: switch ($etc) {
70: case '…':
71: $etcLength = 1;
72: break;
73: default:
74: $etcLength = mb_strlen(html_entity_decode($etc, ENT_COMPAT, 'utf-8'), 'utf-8');
75: break;
76: }
77:
78: // Look for word boundaries
79: $search = mb_substr($string, 0, ($max - $etcLength) + 1, 'utf-8');
80: if (preg_match('~[^\w\pL\pN]~u', $search)) {
81: // Boundary found
82: $string = preg_replace('~[^\w\pL\pN]*[\w\pL\pN]*$~uU', '', $search);
83: } else {
84: // No word boundary found, will trim in the middle of a word
85: $string = mb_substr($string, 0, $max - $etcLength, 'utf-8');
86: }
87:
88: // Add "etc" at the end
89: $string .= $etc;
90:
91: return $string;
92: }
93:
94: /**
95: * Generates a crc checksum same on 32 and 64-bit platforms.
96: *
97: * @param string $string Input string
98: * @return integer
99: */
100: public static function crc($string)
101: {
102: $crc = crc32($string);
103: if ($crc & 0x80000000) {
104: $crc ^= 0xffffffff;
105: $crc++;
106: $crc = -$crc;
107: }
108: return $crc;
109: }
110:
111: /**
112: * Generates a random string of given length.
113: *
114: * @param integer $length String length
115: * @return string
116: */
117: public static function random($length)
118: {
119: static $chars = 'abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ';
120: $random = '';
121: for ($i = 1; $i <= $length; $i++) {
122: $random .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
123: }
124: return $random;
125: }
126:
127: /**
128: * Fixes and unifies line endings in a string.
129: *
130: * @param string $string String to fix
131: * @param string $lineEnd Desired line ending
132: * @return string
133: */
134: public static function fixLineEnding($string, $lineEnd = "\n")
135: {
136: $string = str_replace("\r\n", "\n", $string);
137: $string = str_replace("\r", "\n", $string);
138: $string = str_replace("\n", $lineEnd, $string);
139:
140: return $string;
141: }
142:
143: /**
144: * Obfuscates an email address.
145: *
146: * @param string $email Email address
147: * @param string $comment Put a comment into the address
148: * @return string
149: */
150: public static function obfuscateEmail($email, $comment = false)
151: {
152: if ($comment) {
153: return str_replace('@', '@<!---->', $email);
154: } else {
155: return str_replace('@', '@', $email);
156: }
157: }
158:
159: /**
160: * Converts first character of a string to lowercase.
161: * Works correctly with multibyte encodings.
162: *
163: * @param string $string Input string
164: * @return string
165: */
166: public static function lcfirst($string)
167: {
168: return mb_strtolower(mb_substr($string, 0, 1, 'utf-8')) . mb_substr($string, 1, mb_strlen($string, 'utf-8') - 1, 'utf-8');
169: }
170:
171: /**
172: * Htmlspecialchars function alias with some parameters automatically set.
173: *
174: * @param string $string Input string
175: * @param integer $quoteStyle Quote style
176: * @param boolean $doubleEncode Prevent from double encoding
177: * @return string
178: */
179: public static function escape($string, $quoteStyle = ENT_QUOTES, $doubleEncode = false)
180: {
181: return @htmlspecialchars($string, (int) $quoteStyle, 'utf-8', (bool) $doubleEncode);
182: }
183:
184: /**
185: * Converts given size in bytes to kB, MB, GB, TB or PB
186: * and appends the appropriate unit.
187: *
188: * @param float $size Input size
189: * @param string $decimalPoint Decimal point
190: * @param string $thousandsSeparator Thousands separator
191: * @return string
192: */
193: public static function formatBytes($size, $decimalPoint = ',', $thousandsSeparator = ' ')
194: {
195: static $units = array('B', 'kB', 'MB', 'GB', 'TB', 'PB');
196: foreach ($units as $unit) {
197: if ($size < 1024) {
198: break;
199: }
200: $size = $size / 1024;
201: }
202:
203: $decimals = ('B' === $unit) || ('kB' === $unit) ? 0 : 1;
204: return number_format($size, $decimals, $decimalPoint, $thousandsSeparator) . ' ' . $unit;
205: }
206: }
207: