1
|
|
|
<?php |
|
|
|
|
2
|
|
|
|
3
|
|
|
namespace demo\browser; |
4
|
|
|
|
5
|
|
|
//import composer autoload file |
6
|
|
|
require_once dirname(__DIR__) . implode(DIRECTORY_SEPARATOR, ['.', '..', 'vendor', 'autoload.php']); |
7
|
|
|
|
8
|
|
|
use PassGenerator\Generator; |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* @author Lachezar Mihaylov <[email protected]> |
12
|
|
|
* @license https://github.com/lmihaylov2512/pass-generator/blob/master/LICENSE.md MIT License |
13
|
|
|
*/ |
14
|
|
|
class App |
15
|
|
|
{ |
16
|
|
|
/** |
17
|
|
|
* @var integer whether the app is in debug mode |
18
|
|
|
*/ |
19
|
|
|
const DEBUG_MODE = 0; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* @var array options with title and description |
23
|
|
|
*/ |
24
|
|
|
protected static $options = [ |
25
|
|
|
'upperCase' => [ |
26
|
|
|
'title' => 'upper case', |
27
|
|
|
'desc' => 'use alphabet upper letters [A-Z]', |
28
|
|
|
], |
29
|
|
|
'lowerCase' => [ |
30
|
|
|
'title' => 'lower case', |
31
|
|
|
'desc' => 'use alphabet lower letters [a-z]', |
32
|
|
|
], |
33
|
|
|
'digits' => [ |
34
|
|
|
'title' => 'digits', |
35
|
|
|
'desc' => 'all numbers [0-9]', |
36
|
|
|
], |
37
|
|
|
'special' => [ |
38
|
|
|
'title' => 'special', |
39
|
|
|
'desc' => 'special symbols ~, !, @, #, ...' |
40
|
|
|
], |
41
|
|
|
'brackets' => [ |
42
|
|
|
'title' => 'brackets', |
43
|
|
|
'desc' => 'all kind of brackets (, ), {, }, [, ]', |
44
|
|
|
], |
45
|
|
|
'minus' => [ |
46
|
|
|
'title' => 'minus', |
47
|
|
|
'desc' => 'minus sign -', |
48
|
|
|
], |
49
|
|
|
'underline' => [ |
50
|
|
|
'title' => 'underline', |
51
|
|
|
'desc' => 'underline sign _', |
52
|
|
|
], |
53
|
|
|
'space' => [ |
54
|
|
|
'title' => 'space', |
55
|
|
|
'desc' => 'space character \' \'', |
56
|
|
|
], |
57
|
|
|
]; |
58
|
|
|
/** |
59
|
|
|
* @var Generator password generator instance |
60
|
|
|
*/ |
61
|
|
|
protected static $generator; |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* Check whether the current request is ajax. |
65
|
|
|
* |
66
|
|
|
* @return boolean the result from checking |
67
|
|
|
*/ |
68
|
|
|
public static function isAjaxRequest() |
|
|
|
|
69
|
|
|
{ |
70
|
|
|
return !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'; |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* Return post variable, if exists, or specific default value. |
75
|
|
|
* |
76
|
|
|
* @param mixed $default default value, if post doesn't exist |
77
|
|
|
* @return mixed |
78
|
|
|
*/ |
79
|
|
|
public static function getPost($default = null) |
|
|
|
|
80
|
|
|
{ |
81
|
|
|
return isset($_POST) ? $_POST : $default; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* Get all options array. |
86
|
|
|
* |
87
|
|
|
* @return array options array |
88
|
|
|
*/ |
89
|
|
|
public static function getOptions() |
90
|
|
|
{ |
91
|
|
|
return static::$options; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Create password generator, if necessary and return it. |
96
|
|
|
* |
97
|
|
|
* @return Generator password generator instance |
98
|
|
|
*/ |
99
|
|
|
public static function getGenerator() |
100
|
|
|
{ |
101
|
|
|
if (static::$generator === null) { |
102
|
|
|
static::$generator = new Generator(); |
103
|
|
|
} |
104
|
|
|
return static::$generator; |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* If is ajax request and post exists, generate password and cancel script execution. |
109
|
|
|
* |
110
|
|
|
* @return string|null if is ajax request, returns the generated password |
111
|
|
|
*/ |
112
|
|
|
public static function run() |
113
|
|
|
{ |
114
|
|
|
if (static::isAjaxRequest() && ($data = static::getPost()) !== null) { |
115
|
|
|
foreach ($data as $option => $value) { |
116
|
|
|
static::getGenerator()->$option = $value; |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
return static::getGenerator()->generate(); |
120
|
|
|
} |
121
|
|
|
} |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
//run the app |
125
|
|
|
if (($password = App::run()) !== null) { |
126
|
|
|
die($password); |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
?> |
130
|
|
|
<!DOCTYPE html> |
131
|
|
|
<html> |
132
|
|
|
<head> |
133
|
|
|
<meta charset="utf-8" /> |
134
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" /> |
135
|
|
|
<title>Demo password generator</title> |
136
|
|
|
<link href="./assets/bootstrap/css/<?= App::DEBUG_MODE ? 'bootstrap.css' : 'bootstrap.min.css' ?>" rel="stylesheet" /> |
137
|
|
|
<style>.margin-top-20{margin-top:20px}.loader{border:4px solid #eee;border-top:4px solid #337ab7;border-radius:50%;width:32px;height:32px;animation:spin 2s linear infinite;display:inline-block;vertical-align:middle}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}</style> |
138
|
|
|
</head> |
139
|
|
|
<body> |
140
|
|
|
<nav class="navbar navbar-default"> |
141
|
|
|
<div class="container-fluid"> |
142
|
|
|
<div class="navbar-header"> |
143
|
|
|
<a href="https://packagist.org/packages/lmihaylov/pass-generator" class="navbar-brand" target="_blank">Pass-Generator</a> |
144
|
|
|
</div> |
145
|
|
|
</div> |
146
|
|
|
</nav> |
147
|
|
|
<div class="container"> |
148
|
|
|
<div class="row"> |
149
|
|
|
<div class="col-lg-8 col-lg-offset-2"> |
150
|
|
|
<div class="panel panel-default"> |
151
|
|
|
<div class="panel-body"> |
152
|
|
|
<div class="row"> |
153
|
|
|
<div class="col-lg-12"> |
154
|
|
|
<div class="input-group"> |
155
|
|
|
<span class="input-group-addon">Password length</span> |
156
|
|
|
<input type="text" class="form-control" placeholder="Password length" value="<?= App::getGenerator()->length ?>" id="input-length"> |
157
|
|
|
<span class="input-group-btn"> |
158
|
|
|
<button class="btn btn-primary" type="button" id="btn-generate">Generate</button> |
159
|
|
|
</span> |
160
|
|
|
</div> |
161
|
|
|
<div id="password-output" class="well lead hide margin-top-20"></div> |
162
|
|
|
<div class="list-group margin-top-20"> |
163
|
|
|
<?php foreach (App::getOptions() as $group => $option): ?> |
164
|
|
|
<a href="#" class="list-group-item<?= App::getGenerator()->$group ? ' active' : '' ?>" data-option="<?= $group ?>"> |
165
|
|
|
<h4 class="list-group-item-heading"><span class="glyphicon glyphicon-<?= App::getGenerator()->$group ? 'ok' : 'remove' ?>" aria-hidden="true"></span> <?= $option['title'] ?></h4> |
166
|
|
|
<p class="list-group-item-text"><?= $option['desc'] ?></p> |
167
|
|
|
</a> |
168
|
|
|
<?php endforeach; ?> |
169
|
|
|
</div> |
170
|
|
|
</div> |
171
|
|
|
</div> |
172
|
|
|
</div> |
173
|
|
|
</div> |
174
|
|
|
</div> |
175
|
|
|
</div> |
176
|
|
|
</div> |
177
|
|
|
<script src="./assets/jquery/<?= App::DEBUG_MODE ? 'jquery.js' : 'jquery.min.js' ?>"></script> |
178
|
|
|
<script> |
179
|
|
|
(function (w, d, $) { |
180
|
|
|
//attach click event handler on list elements |
181
|
|
|
$('.list-group > a').on('click', function (e) { |
182
|
|
|
e.preventDefault(); |
183
|
|
|
var isActive = $(this).hasClass('active'); |
184
|
|
|
|
185
|
|
|
if (isActive) { |
186
|
|
|
$(this).toggleClass('active').find('span.glyphicon').removeClass('glyphicon-ok').addClass('glyphicon-remove'); |
187
|
|
|
} else { |
188
|
|
|
$(this).toggleClass('active').find('span.glyphicon').removeClass('glyphicon-remove').addClass('glyphicon-ok'); |
189
|
|
|
} |
190
|
|
|
}); |
191
|
|
|
|
192
|
|
|
//attach event handler on generate button for generating a new password string |
193
|
|
|
$('#btn-generate').on('click', function (e) { |
194
|
|
|
var data = { length: $('#input-length').val() }; |
195
|
|
|
|
196
|
|
|
//prepare request data |
197
|
|
|
$('#password-output').html('<span class="loader"></span> Generating...').removeClass('hide'); |
198
|
|
|
$('.list-group-item').each(function () { |
199
|
|
|
data[$(this).data('option')] = $(this).hasClass('active') ? '1' : ''; |
200
|
|
|
}); |
201
|
|
|
|
202
|
|
|
$.ajax({ |
203
|
|
|
type: 'POST', |
204
|
|
|
data: data, |
205
|
|
|
success: function (res) { |
206
|
|
|
$('#password-output').html(res === '' ? 'Please choose the at least one or more symbols types' : res); |
207
|
|
|
} |
208
|
|
|
}); |
209
|
|
|
}); |
210
|
|
|
})(window, document, jQuery); |
211
|
|
|
</script> |
212
|
|
|
</body> |
213
|
|
|
</html> |
214
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.