Completed
Push — master ( b0ff97...7f4bca )
by Jonathan
06:58
created

Functions::promptAlert()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 5
rs 9.4285
cc 1
eloc 4
nc 1
nop 1
1
<?php
2
/**
3
 * webtrees-lib: MyArtJaub library for webtrees
4
 *
5
 * @package MyArtJaub\Webtrees
6
 * @subpackage Functions
7
 * @author Jonathan Jaubart <[email protected]>
8
 * @copyright Copyright (c) 2009-2016, Jonathan Jaubart
9
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3
10
 */
11
namespace MyArtJaub\Webtrees\Functions; 
12
13
use \Fisharebest\Webtrees as fw;
14
use Fisharebest\Webtrees\Filter;
15
16
/**
17
 * General functions.
18
 */
19
class Functions {
20
	
21
	/**
22
	 * This array contains the cached short month names, based on the cal_info functions.
23
	 * Retrieves the abbrevmonths values of months: Jan, Feb, Mar...
24
	 * 
25
	 * @uses cal_info
26
	 * @var array $calendarShortMonths Cached array of abbreviated short month names
27
	 */
28
	private static $calendarShortMonths = array();
29
	
30
	/**
31
	 * Debug tool: prompt a Javascript pop-up with a text
32
	 *
33
	 * @param string $text Text to display
34
	 */
35
	static public function promptAlert($text){
36
		echo '<script>';
37
		echo 'alert("',fw\Filter::escapeHtml($text),'")';
38
		echo '</script>';
39
	}
40
	
41
	/**
42
	 * Return the result of a division, and a default value if denomintaor is 0
43
	 * 
44
	 * @param integer $num Numerator
45
	 * @param integer $denom Denominator
46
	 * @param float $default Default value if denominator null or 0
47
	 * @return float Result of the safe division
48
	 */
49
	public static function safeDivision($num, $denom, $default = 0) {
50
		if($denom && $denom!=0){
51
			return $num / $denom;
52
		}
53
		return $default;
54
	}
55
	
56
	/**
57
	 * Returns the percentage of two numbers
58
	 *
59
	 * @param int $num Numerator
60
	 * @param int $denom Denominator
61
	 * @param float $default Default value if denominator null or 0
62
	 * @return float Percentage
63
	 */
64
	public static function getPercentage($num, $denom, $default = 0){
65
		return 100 * self::safeDivision($num, $denom, $default);
66
	}
67
	
68
	/**
69
	 * Get width and heigth of an image resized in order fit a target size.
70
	 *
71
	 * @param string $file The image to resize
72
	 * @param int $target	The final max width/height
73
	 * @return array array of ($width, $height). One of them must be $target
74
	 */
75
	static public function getResizedImageSize($file, $target=25){
76
		list($width, $height, , ) = getimagesize($file);
77
		$max = max($width, $height);
78
		$rapp = $target / $max;
79
		$width = intval($rapp * $width);
80
		$height = intval($rapp * $height);
81
		return array($width, $height);
82
	}
83
84
	
85
	/**
86
	 * Checks if a table exist in the DB schema
87
	 *
88
	 * @param string $table Name of the table to look for
89
	 * @return boolean Does the table exist
90
	 */
91
	public static function doesTableExist($table) {
92
		try {
93
			fw\Database::prepare("SELECT 1 FROM {$table}")->fetchOne();
94
			return true;
95
		} catch (\PDOException $ex) {
96
			return false;
97
		}
98
	}
99
	
100
	/**
101
	 * Returns a randomy generated token of a given size
102
	 *
103
	 * @param int $length Length of the token, default to 32
104
	 * @return string Random token
105
	 */
106
	public static function generateRandomToken($length=32) {
107
		$chars = str_split('abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
108
		$len_chars = count($chars);
109
		$token = '';
110
		
111
		for ($i = 0; $i < $length; $i++)
112
			$token .= $chars[ mt_rand(0, $len_chars - 1) ];
113
		
114
		# Number of 32 char chunks
115
		$chunks = ceil( strlen($token) / 32 );
116
		$md5token = '';
117
		
118
		# Run each chunk through md5
119
		for ( $i=1; $i<=$chunks; $i++ )
120
			$md5token .= md5( substr($token, $i * 32 - 32, 32) );
121
		
122
			# Trim the token
123
		return substr($md5token, 0, $length);		
124
	}
125
	
126
	/**
127
	 * Generate the key used by the encryption to safe base64 functions.
128
	 * 
129
	 * @return string Encryption key
130
	 */
131
	protected static function getBase64EncryptionKey() {	    
132
	    $key = 'STANDARDKEYIFNOSERVER';
133
	    if(!empty(Filter::server('SERVER_NAME')) && !empty(Filter::server('SERVER_SOFTWARE')))
134
	        $key = md5(Filter::server('SERVER_NAME').Filter::server('SERVER_SOFTWARE'));
135
	    
136
	    return $key;
137
	}
138
	
139
	/**	  
140
	 * Encrypt a text, and encode it to base64 compatible with URL use
141
	 * 	(no +, no /, no =)
142
	 *
143
	 * @param string $data Text to encrypt
144
	 * @return string Encrypted and encoded text
145
	 */
146
	public static function encryptToSafeBase64($data){		
147
		$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);	
148
		$id = sodium_crypto_secretbox($data, $nonce, self::getBase64EncryptionKey());
149
		$encrypted = base64_encode($nonce.$id);
150
		
151
		//sodium_memzero($data);   // Requires PHP 7.2
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
152
		
153
		// +, / and = are not URL-compatible
154
		$encrypted = str_replace('+', '-', $encrypted);
155
		$encrypted = str_replace('/', '_', $encrypted);
156
		$encrypted = str_replace('=', '*', $encrypted);
157
		return $encrypted;
158
	}
159
	
160
	/**
161
	 * Decode and encrypt a text from base64 compatible with URL use
162
	 *
163
	 * @param string $encrypted Text to decrypt
164
	 * @return string Decrypted text
165
	 */
166
	public static function decryptFromSafeBase64($encrypted){
167
		$encrypted = str_replace('-', '+', $encrypted);
168
		$encrypted = str_replace('_', '/', $encrypted);
169
		$encrypted = str_replace('*', '=', $encrypted);
170
		$encrypted = base64_decode($encrypted);
171
		if($encrypted === false)
172
			throw new \InvalidArgumentException('The encrypted value is not in correct base64 format.');
173
		
174
		if (mb_strlen($encrypted, '8bit') < (SODIUM_CRYPTO_SECRETBOX_NONCEBYTES + SODIUM_CRYPTO_SECRETBOX_MACBYTES))
175
		    throw new \InvalidArgumentException('The encrypted value does not contain enough characters for the key.');
176
177
	    $nonce = mb_substr($encrypted, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
178
	    $ciphertext = mb_substr($encrypted, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
179
        
180
        $decrypted = sodium_crypto_secretbox_open($ciphertext, $nonce, self::getBase64EncryptionKey());
181
		
182
        if($decrypted === false) {
183
            throw new \InvalidArgumentException('The message has been tampered with in transit.');
184
        }
185
        
186
        //sodium_memzero($encrypted);   // Requires PHP 7.2
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
187
        
188
        return $decrypted;
189
	}
190
	
191
	/**
192
	 * Encode a string from the file system encoding to UTF-8 (if necessary)
193
	 *
194
	 * @param string $string Filesystem encoded string to encode
195
	 * @return string UTF-8 encoded string
196
	 */
197
	public static function encodeFileSystemToUtf8($string){
198
		if (strtoupper(substr(php_uname('s'), 0, 7)) === 'WINDOWS') {
199
		    return iconv('cp1252', 'utf-8//IGNORE',$string);
200
		}
201
		return $string;
202
	}
203
	
204
	/**
205
	 * Encode a string from UTF-8 to the file system encoding (if necessary)
206
	 *
207
	 * @param string $string UTF-8 encoded string to encode
208
	 * @return string Filesystem encoded string
209
	 */
210
	public static function encodeUtf8ToFileSystem($string){
211
		if (preg_match('//u', $string) && strtoupper(substr(php_uname('s'), 0, 7)) === 'WINDOWS') {
212
			return iconv('utf-8', 'cp1252//IGNORE' ,  $string);
213
		}
214
		return $string;
215
	}
216
	
217
	/**
218
	 * Check whether a path is under a valid form.
219
	 * 
220
	 * @param string $filename Filename path to check
221
	 * @param boolean $acceptfolder Should folders be accepted?
222
	 * @return boolean True if path valid
223
	 */
224
	public static function isValidPath($filename, $acceptfolder = FALSE) {		
225
		if(strpbrk($filename, $acceptfolder ? '?%*:|"<>' : '\\/?%*:|"<>') === FALSE) return true;
226
		return false;
227
	}
228
	
229
	/**
230
	 * Return short names for the months of the specific calendar.
231
	 * 
232
	 * @see \cal_info()
233
	 * @param integer $calendarId Calendar ID (according to PHP cal_info)
234
	 * @return array Array of month short names
235
	 */
236
	public static function getCalendarShortMonths($calendarId = 0) {
237
		if(!isset(self::$calendarShortMonths[$calendarId])) {
238
			$calendar_info = cal_info($calendarId);
239
			self::$calendarShortMonths[$calendarId] = $calendar_info['abbrevmonths'];
240
		}		
241
		return self::$calendarShortMonths[$calendarId];
242
	}
243
	
244
	/**
245
	 * Returns the generation associated with a Sosa number
246
	 *
247
	 * @param int $sosa Sosa number
248
	 * @return number
249
	 */
250
	public static function getGeneration($sosa){
251
		return(int)log($sosa, 2)+1;
252
	}
253
	
254
	
255
256
257
	/**
258
	 * Returns whether the image type is supported by the system, and if so, return the standardised type
259
	 *
260
	 * @param string $reqtype Extension to test
261
	 * @return boolean|string Is supported?
262
	 */
263
	public static function isImageTypeSupported($reqtype) {
264
	    $supportByGD = array('jpg'=>'jpeg', 'jpeg'=>'jpeg', 'gif'=>'gif', 'png'=>'png');
265
	    $reqtype = strtolower($reqtype);
266
	
267
	    if (empty($supportByGD[$reqtype])) {
268
	        return false;
269
	    }
270
	
271
	    $type = $supportByGD[$reqtype];
272
	
273
	    if (function_exists('imagecreatefrom'.$type) && function_exists('image'.$type)) {
274
	        return $type;
275
	    }
276
	
277
	    return false;
278
	}
279
		
280
}
281