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