PluginProbe
WebTotem Security / 2.4.2
WebTotem Security v2.4.2
3.0.2 3.0.1 3.0.0 trunk 1.0 1.1 1.2 1.3 1.3.1 1.3.2 1.3.3 2.0 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.1 2.2.2 2.2.3 All 110 releases
← All changes | lib/Option.php +124 -463 trunk2.4.2 View file →
@@ -11,8 +11,39 @@
11 11 * WebTotem Option class.
12 12 */
13 13 class WebTotemOption {
14 14
15 + /**
16 + * Get all config options name.
17 + *
18 + * @param string $option
19 + * Option name.
20 + *
21 + * @return mixed
22 + * Returns saved data by option name.
23 + */
24 + public static function getAllOptions() {
25 + return [
26 + 'api_key',
27 + 'activated',
28 + 'auth_token_expired',
29 + 'auth_token',
30 + 'am_file',
31 + 'waf_file',
32 + 'av_file',
33 + 'am_installed',
34 + 'av_installed',
35 + 'waf_installed',
36 + 'time_zone_check',
37 + 'time_zone_offset',
38 + 'all_hosts',
39 + 'plugin_version',
40 +
41 + 'host_id',
42 + 'host_name',
43 + ];
44 + }
45 +
15 46 /**
16 47 * Get config option.
17 48 *
18 49 * @param string $option
@@ -21,10 +52,10 @@
21 52 * @return mixed
22 53 * Returns saved data by option name.
23 54 */
24 55 public static function getOption($option) {
25 - $data = WebTotemDB::getData([ 'name' => $option ],'settings');
26 - return (array_key_exists('value', $data)) ? $data['value'] : '';
56 + // Control is passed to get_option() when the MultiSite mode is not used.
57 + return get_site_option('wtotem_' . $option);
27 58 }
28 59
29 60 /**
30 61 * Save multiple configuration options.
@@ -37,10 +68,11 @@
37 68 */
38 69 public static function setOptions(array $options) {
39 70
40 71 foreach ($options as $option => $value) {
41 - $value = is_array($value) ? json_encode($value) : $value;
42 - WebTotemDB::setData(['name' => $option, 'value' => $value,], 'settings', ['name' => $option]);
72 + //If the function is not used in a MultiSite assembly, then control is passed to
73 + // the update_option() function with the parameter $autoload = 'no'
74 + update_site_option('wtotem_' . $option, $value);
43 75 }
44 76
45 77 return TRUE;
46 78 }
@@ -56,9 +88,10 @@
56 88 */
57 89 public static function clearOptions(array $options) {
58 90
59 91 foreach ($options as $option) {
60 - WebTotemDB::deleteData([ 'name' => $option ], 'settings');
92 + delete_option('wtotem_' . $option);
93 + delete_site_option('wtotem_' . $option);
61 94 }
62 95
63 96 return TRUE;
64 97 }
@@ -73,17 +106,11 @@
73 106 * Returns TRUE after setting the session options.
74 107 */
75 108 public static function setSessionOptions(array $options) {
76 109
77 - $sessions = json_decode(self::getOption('sessions'), true) ?: [];
78 - $user_id = get_current_user_id();
79 -
80 - foreach ($options as $option => $value){
81 - $sessions[$user_id][$option] = $value;
82 - }
83 -
84 - self::setOptions(['sessions' => $sessions]);
85 -
110 + foreach ($options as $option => $value) {
111 + $_SESSION['wtotem.' . $option] = $value;
112 + }
86 113 return TRUE;
87 114 }
88 115
89 116 /**
@@ -95,79 +122,20 @@
95 122 * @return mixed
96 123 * Returns saved data by option name.
97 124 */
98 125 public static function getSessionOption($option) {
99 -
100 - $sessions = json_decode(self::getOption('sessions'), true) ?: [];
101 - $user_id = get_current_user_id();
102 -
103 - if(array_key_exists($user_id, $sessions) and array_key_exists($option, $sessions[$user_id])){
104 - return $sessions[$user_id][$option];
105 - } else {
106 - return [];
107 - }
108 -
126 + if(!isset($_SESSION)) {
127 + return [];
128 + }
129 + if(isset($_SESSION['wtotem.' . $option])){
130 + return $_SESSION['wtotem.' . $option];
131 + }
132 + else {
133 + return FALSE;
134 + }
109 135 }
110 136
111 - /**
112 - * Save multiple some plugin settings.
113 - *
114 - * @param array $options
115 - * Array of data, key is name of option.
116 - *
117 - * @return bool
118 - * Returns TRUE after save settings.
119 - */
120 - public static function setPluginSettings(array $options) {
121 -
122 - $settings = json_decode(self::getOption('settings'), true) ?: [];
123 -
124 - foreach ($options as $option => $value){
125 - $settings[$option] = $value;
126 - }
127 -
128 - self::setOptions(['settings' => $settings]);
129 -
130 - return TRUE;
131 - }
132 -
133 - /**
134 - * Get plugin settings.
135 - *
136 - * @param string $option
137 - * Option name.
138 - *
139 - * @return mixed
140 - * Returns saved data by option name.
141 - */
142 - public static function getPluginSettings($option = null) {
143 -
144 - $settings = json_decode(self::getOption('settings'), true) ?: [];
145 -
146 - if($option){
147 - if(array_key_exists($option, $settings)){
148 - return $settings[$option];
149 - } else {
150 - return [];
151 - }
152 - } else{
153 - return $settings;
154 - }
155 - }
156 -
157 -
158 - /**
159 - * Check has reCaptcha enabled.
160 - *
161 - * @return bool
162 - * Returns TRUE if reCaptcha enabled.
163 - */
164 - public static function reCaptchaEnabled() {
165 - return self::getPluginSettings('recaptcha') ?: false;
166 - }
167 -
168 -
169 - /**
137 + /**
170 138 * Save authentication token and token expiration dates in settings.
171 139 *
172 140 * @param array $params
173 141 * Parameters for authorization.
@@ -175,46 +143,21 @@
175 143 * @return string
176 144 * Returns TRUE after setting the options.
177 145 */
178 146 public static function login(array $params) {
179 - $parts = explode('.', $params['token']);
180 - $token_data = json_decode(WebTotem::base64UrlDecode($parts[1]), true);
181 - $token_expired = $token_data['exp'] - 60;
147 + $token_expired = time() + $params['token']['expiresIn'] - 60;
182 148
183 149 self::setOptions([
184 150 'activated' => TRUE,
185 151 'auth_token_expired' => $token_expired,
186 - 'auth_token' => $params['token'],
152 + 'auth_token' => $params['token']['value'],
187 153 'api_key' => $params['api_key'],
188 - 'multisite_options' => WebTotem::isMultiSite()
189 154 ]);
190 155
191 156 return TRUE;
192 157 }
193 158
194 - /**
195 - * Save authentication token and token expiration dates in settings.
196 - *
197 - * @param string $token
198 - * Parameters for authorization.
199 - *
200 - * @return bool
201 - * Returns TRUE after setting the options.
202 - */
203 - public static function refreshToken(string $token) {
204 - $parts = explode('.', $token);
205 - $token_data = json_decode(WebTotem::base64UrlDecode($parts[1]), true);
206 - $token_expired = $token_data['exp'] - 60;
207 -
208 - self::setOptions([
209 - 'auth_token_expired' => $token_expired,
210 - 'auth_token' => $token,
211 - ]);
212 -
213 - return TRUE;
214 - }
215 -
216 - /**
159 + /**
217 160 * Checks whether the user has activated the plugin using the API key.
218 161 *
219 162 * @return bool
220 163 * Returns the module activation status.
@@ -235,40 +178,14 @@
235 178 'activated',
236 179 'auth_token_expired',
237 180 'auth_token',
238 181 'api_key',
239 - 'api_url',
240 - 'host_id',
241 - 'host_name',
182 + 'host_id',
183 + 'host_name',
242 184 ]);
243 185 return TRUE;
244 186 }
245 187
246 - /**
247 - * Return the current API access token, authorizing only when necessary.
248 - *
249 - * The token is reused until it actually expires; a new sign-in happens only
250 - * when there is no token or the stored one is past its expiry.
251 - *
252 - * @return string
253 - * Access token, or an empty string when authorization failed.
254 - */
255 - public static function getAuthToken() {
256 - $token = self::getOption('auth_token');
257 - $expired_at = (int) self::getOption('auth_token_expired');
258 -
259 - if ($token && $expired_at > time()) {
260 - return $token;
261 - }
262 -
263 - $api_key = self::getOption('api_key');
264 - if ($api_key && WebTotemAPI::auth($api_key) === 'success') {
265 - return self::getOption('auth_token');
266 - }
267 -
268 - return $token ?: '';
269 - }
270 -
271 188 /**
272 189 * Set notification.
273 190 *
274 191 * @param string $type
@@ -331,22 +248,18 @@
331 248 add_blog_option($blog_id, 'wtotem_host_id', $host_id);
332 249 add_blog_option($blog_id, 'wtotem_host_name', $host_name);
333 250
334 251 if(!is_main_site($blog_id)){
335 - $all_hosts = json_decode(self::getOption('all_hosts'), true) ?: [];
252 + $all_hosts = self::getOption('all_hosts') ?: [];
336 253 $all_hosts[$host_name] = $host_id;
337 254
338 255 self::setOptions([
339 256 'all_hosts' => $all_hosts,
340 257 ]);
341 - } else {
342 - self::setOptions([
343 - 'host_id' => $host_id,
344 - 'host_name' => $host_name,
345 - ]);
346 258 }
347 259
348 - } else {
260 + }
261 + else {
349 262 self::setOptions([
350 263 'host_id' => $host_id,
351 264 'host_name' => $host_name,
352 265 ]);
@@ -362,20 +275,21 @@
362 275 * @return array
363 276 * Host data.
364 277 */
365 278 public static function getHost($hid = false) {
366 -
367 - if ( $hid ) {
279 + if($hid){
368 280 $all_hosts = self::getAllHosts() ?: [];
369 - if ( $all_hosts and in_array( $hid, $all_hosts ) ) {
281 + if($all_hosts and in_array($hid, $all_hosts)){
370 282 return [
371 - 'id' => $hid,
372 - 'name' => array_search( $hid, $all_hosts ),
283 + 'id' => $hid,
284 + 'name' => array_search($hid, $all_hosts),
373 285 ];
374 286 }
375 287 }
376 -
377 - return self::getMainHost();
288 + return [
289 + 'id' => get_option('wtotem_host_id'),
290 + 'name' => get_option('wtotem_host_name'),
291 + ];
378 292 }
379 293
380 294 /**
381 295 * Get host data.
@@ -383,9 +297,9 @@
383 297 * @return array
384 298 * Host data.
385 299 */
386 300 public static function getAllHosts() {
387 - $all_hosts = json_decode(self::getOption('all_hosts'), true) ?: [];
301 + $all_hosts = self::getOption('all_hosts') ?: [];
388 302
389 303 $main_host = self::getMainHost();
390 304 $all_hosts = ($main_host['id']) ? [$main_host['name'] => $main_host['id']] + $all_hosts : $all_hosts;
391 305
@@ -399,13 +313,12 @@
399 313 * Main host data.
400 314 */
401 315 public static function getMainHost() {
402 316
403 - return [
404 - 'id' => self::getOption('host_id'),
405 - 'name' => self::getOption('host_name'),
406 - ];
317 + $host['id'] = get_blog_option(0, 'wtotem_host_id');
318 + $host['name'] = get_blog_option(0, 'wtotem_host_name');
407 319
320 + return $host;
408 321 }
409 322
410 323 /**
411 324 * Delete host data from DB.
@@ -413,14 +326,12 @@
413 326 * @return void
414 327 */
415 328 public static function clearAllHosts() {
416 329
417 - $hosts = WebTotemAPI::getSites(1, 1000000);
418 - foreach ($hosts as $site) {
419 - if (empty($site['name'])) {
420 - continue;
421 - }
422 - $blog_id = self::getBlogId($site['name']);
330 + $data = WebTotemAPI::getSites();
331 + foreach ($data['edges'] as $site) {
332 + $site = $site['node'];
333 + $blog_id = self::getBlogId($site['hostname']);
423 334 delete_blog_option($blog_id, 'wtotem_host_id');
424 335 delete_blog_option($blog_id, 'wtotem_host_name');
425 336 }
426 337
@@ -454,48 +365,14 @@
454 365 *
455 366 * @return integer
456 367 * Blog id.
457 368 */
458 - public static function getBlogId($host_name){
459 - $local_sites = get_sites();
369 + public static function getBlogId($host_name){
370 + $current_network = get_network();
371 + $patterns = [ '/' . $current_network->domain . '/', '/\./', '/\//', ];
460 372
461 - foreach ($local_sites as $site){
462 - $domain = untrailingslashit($site->domain . $site->path);
463 - if($host_name == $domain){
464 - return $site->blog_id;
465 - }
466 - }
467 - return 0;
468 - }
469 -
470 - /**
471 - * Get all config options name.
472 - *
473 - * @return array
474 - * Returns saved data by option name.
475 - */
476 - public static function getAllOptions() {
477 - return [
478 - 'api_key',
479 - 'activated',
480 - 'auth_token_expired',
481 - 'auth_token',
482 - 'am_file',
483 - 'waf_file',
484 - 'av_file',
485 - 'am_installed',
486 - 'av_installed',
487 - 'waf_installed',
488 - 'time_zone_check',
489 - 'time_zone_offset',
490 - 'all_hosts',
491 - 'plugin_version',
492 - 'sessions',
493 - 'multisite_options',
494 -
495 - 'host_id',
496 - 'host_name',
497 - ];
373 + $slug = preg_replace( $patterns, '', $host_name );
374 + return ($slug) ? get_id_from_blogname($slug) : 0;
498 375 }
499 376
500 377 /**
501 378 * Checking the old version of options.
@@ -504,276 +381,60 @@
504 381 * If there are old options, it will return true.
505 382 */
506 383 public static function checkOldOptions() {
507 384
508 - // Creating a database with plugin settings.
509 - if(WebTotemDB::install()){
385 + $api_key = get_option('wtsec_api_key');
386 + $am_file = get_option('wtsec_am_installed_file');
387 + $waf_file = get_option('wtsec_waf_installed_file');
510 388
511 - $api_key = get_option('wtsec_api_key');
512 - $am_file = get_option('wtsec_am_installed_file');
513 - $waf_file = get_option('wtsec_waf_installed_file');
389 + if($api_key && $am_file && $waf_file){
514 390
515 - if($api_key){
516 - self::setOptions([
517 - 'api_key' => $api_key,
518 - 'am_file' => $am_file,
519 - 'waf_file' => $waf_file,
520 - 'activated' => true,
521 - 'am_installed' => true,
522 - 'av_installed' => true,
523 - 'waf_installed' => true,
524 - ]);
391 + self::setOptions([
392 + 'api_key' => $api_key,
393 + 'am_file' => $am_file,
394 + 'waf_file' => $waf_file,
395 + 'activated' => true,
396 + 'am_installed' => true,
397 + 'av_installed' => true,
398 + 'waf_installed' => true,
399 + ]);
525 400
526 - $old_options = [
527 - 'api_key',
528 - 'api_key_safe',
529 - 'api_key_activated',
530 - 'authorized',
531 - 'authToken',
532 - 'waf_installed_file',
533 - 'av_installed_file',
534 - 'am_installed_file',
535 - 'am_installed',
536 - 'logout',
537 - 'av_installed',
538 - 'waf_installed',
539 - 'agents_installed',
540 - 'api_url',
541 - 'color_scheme' ,
542 - 'time_zone',
543 - 'token_expired',
544 - 'deactivated',
545 - 'antivirus_event',
546 - 'antivirus_permissions_changed',
547 - 'antivirus_endCursor',
548 - 'antivirus_hasNextPage',
549 - 'firewall_endCursor',
550 - 'firewall_hasNextPage',
551 - 'reports_endCursor',
552 - 'reports_hasNextPage'
553 - ];
401 + $old_options = [
402 + 'api_key',
403 + 'api_key_safe',
404 + 'api_key_activated',
405 + 'authorized',
406 + 'authToken',
407 + 'waf_installed_file',
408 + 'am_installed_file',
409 + 'am_installed',
410 + 'logout',
411 + 'av_installed',
412 + 'waf_installed',
413 + 'agents_installed',
414 + 'api_url',
415 + 'color_scheme' ,
416 + 'time_zone',
417 + 'token_expired',
418 + 'deactivated',
419 + 'antivirus_event',
420 + 'antivirus_permissions_changed',
421 + 'antivirus_endCursor',
422 + 'antivirus_hasNextPage',
423 + 'firewall_endCursor',
424 + 'firewall_hasNextPage',
425 + 'reports_endCursor',
426 + 'reports_hasNextPage'
427 + ];
554 428
555 - foreach ($old_options as $option) {
556 - delete_option('wtsec_' . $option);
557 - delete_site_option('wtsec_' .$option);
558 - }
559 -
429 + foreach ($old_options as $option) {
430 + delete_option('wtsec_' . $option);
431 + delete_site_option('wtsec_' .$option);
560 432 }
561 433
562 - $api_key = get_site_option('wtotem_api_key');
563 - $am_file = get_site_option('wtotem_am_installed_file');
564 - $waf_file = get_site_option('wtotem_waf_installed_file');
565 -
566 - if($api_key){
567 - self::setOptions([
568 - 'api_key' => $api_key,
569 - 'am_file' => $am_file,
570 - 'waf_file' => $waf_file,
571 - 'activated' => true,
572 - 'am_installed' => true,
573 - 'av_installed' => true,
574 - 'waf_installed' => true,
575 - ]);
576 -
577 - foreach (self::getAllOptions() as $option) {
578 - delete_option('wtotem_' . $option);
579 - delete_site_option('wtotem_' .$option);
580 - }
581 - }
434 + return true;
582 435 }
583 436
584 - return true;
585 - }
586 -
587 - /**
588 - * Check multisite.
589 - */
590 - public static function multisiteCheck() {
591 - // Check the transition to/from the multisite.
592 - if ( ( WebTotem::isMultiSite() && ! WebTotemOption::getOption( 'multisite_options' ) ) or
593 - ( ! WebTotem::isMultiSite() && WebTotemOption::getOption( 'multisite_options' ) ) ) {
594 -
595 - self::setOptions([ 'multisite_options' => WebTotem::isMultiSite() ]);
596 -
597 - if(WebTotem::isMultiSite()){
598 - WebTotemOption::clearAllHosts();
599 - WebTotemOption::clearOptions([ 'host_id', 'host_name' ]);
600 - } else {
601 - WebTotemOption::clearOptions([ 'host_id', 'host_name' ]);
602 - }
603 -
604 - WebTotemAgentManager::removeAgents();
605 - }
606 - }
607 -
608 - /**
609 - * Hide readme file
610 - * @param string $readmeFile
611 - * @return bool
612 - */
613 - public static function hideReadme($readmeFile = null) {
614 - if ($readmeFile === null) {
615 - $readmeFile = ABSPATH . 'readme.html';
616 - }
617 -
618 - if (file_exists($readmeFile)) {
619 - $readmePathInfo = pathinfo($readmeFile);
620 - require_once(ABSPATH . WPINC . '/pluggable.php');
621 - $hiddenReadmeFile = $readmePathInfo['filename'] . '.' . wp_hash('readme') . '.' . $readmePathInfo['extension'];
622 - return @rename($readmeFile, $readmePathInfo['dirname'] . '/' . $hiddenReadmeFile);
623 - }
624 -
625 437 return false;
626 438 }
627 -
628 - /**
629 - * Restore readme file
630 - * @param string $readmeFile
631 - * @return bool
632 - */
633 - public static function restoreReadme($readmeFile = null) {
634 - if ($readmeFile === null) {
635 - $readmeFile = ABSPATH . 'readme.html';
636 - }
637 - $readmePathInfo = pathinfo($readmeFile);
638 - require_once(ABSPATH . WPINC . '/pluggable.php');
639 - $hiddenReadmeFile = $readmePathInfo['dirname'] . '/' . $readmePathInfo['filename'] . '.' . wp_hash('readme') . '.' . $readmePathInfo['extension'];
640 - if (file_exists($hiddenReadmeFile)) {
641 - return @rename($hiddenReadmeFile, $readmeFile);
642 - }
643 -
644 - return false;
645 - }
646 - /**
647 - * Hide WP version
648 - * @return void
649 - */
650 - public static function hideWPVersion() {
651 - global $wp_version;
652 - global $wp_styles;
653 -
654 - if (!($wp_styles instanceof WP_Styles)) {
655 - $wp_styles = new WP_Styles();
656 - }
657 - if ($wp_styles->default_version === $wp_version) {
658 - $wp_styles->default_version = wp_hash($wp_styles->default_version);
659 - }
660 -
661 - foreach ($wp_styles->registered as $key => $val) {
662 - if ($wp_styles->registered[$key]->ver === $wp_version) {
663 - $wp_styles->registered[$key]->ver = wp_hash($wp_styles->registered[$key]->ver);
664 - }
665 - }
666 -
667 - global $wp_scripts;
668 - if (!($wp_scripts instanceof WP_Scripts)) {
669 - $wp_scripts = new WP_Scripts();
670 - }
671 - if ($wp_scripts->default_version === $wp_version) {
672 - $wp_scripts->default_version = wp_hash($wp_scripts->default_version);
673 - }
674 -
675 - foreach ($wp_scripts->registered as $key => $val) {
676 - if ($wp_scripts->registered[$key]->ver === $wp_version) {
677 - $wp_scripts->registered[$key]->ver = wp_hash($wp_scripts->registered[$key]->ver);
678 - }
679 - }
680 - }
681 -
682 - public static function replaceVersion($url) {
683 - return preg_replace_callback("/([&;\?]ver)=(.+?)(&|$)/", "WebTotemOption::replaceVersionCallback", $url);
684 - }
685 -
686 - public static function replaceVersionCallback($matches) {
687 - global $wp_version;
688 - return $matches[1] . '=' . ($wp_version === $matches[2] ? wp_hash($matches[2]) : $matches[2]) . $matches[3];
689 - }
690 -
691 - /**
692 - * Check the nonce comming from any of the settings pages.
693 - *
694 - * @return bool True if the nonce is valid, false otherwise.
695 - */
696 - public static function checkOptionsNonce() {
697 - // Create the option_page value if permalink submission.
698 - if (!isset($_POST['option_page']) && isset($_POST['permalink_structure'])) {
699 - $_POST['option_page'] = 'permalink';
700 - }
701 -
702 - /* check if the option_page has an allowed value */
703 - $option_page = WebTotemRequest::post('option_page');
704 -
705 - if (!$option_page) {
706 - return false;
707 - }
708 -
709 - $action = '';
710 - $nonce = '_wpnonce';
711 -
712 - switch ($option_page) {
713 - case 'general':
714 - case 'writing':
715 - case 'reading':
716 - case 'discussion':
717 - case 'media':
718 - case 'options':
719 - $action = $option_page . '-options';
720 - break;
721 - case 'permalink':
722 - $action = 'update-permalink';
723 - break;
724 - }
725 -
726 - /* check the nonce validity */
727 - return (bool) (
728 - !empty($action)
729 - && isset($_REQUEST[$nonce])
730 - && wp_verify_nonce($_REQUEST[$nonce], $action)
731 - );
732 - }
733 -
734 - /**
735 - * Retrieve all the options stored by Wordpress in the database.
736 - *
737 - * @return array All the options stored by Wordpress in the database.
738 - */
739 - private static function getSiteOptions() {
740 - $settings = array();
741 -
742 - if (array_key_exists('wpdb', $GLOBALS)) {
743 - $results = $GLOBALS['wpdb']->get_results(
744 - 'SELECT * FROM ' . $GLOBALS['wpdb']->options . ' WHERE option_name NOT LIKE "%_transient_%" ORDER BY option_id ASC'
745 - );
746 -
747 - foreach ($results as $row) {
748 - $settings[$row->option_name] = $row->option_value;
749 - }
750 - }
751 -
752 - return $settings;
753 - }
754 -
755 - /**
756 - * Check what Wordpress options were changed comparing the values in the database
757 - * with the values sent through a simple request using a GET or POST method.
758 - *
759 - * @param array $request The content of the global variable GET or POST considering SERVER[REQUEST_METHOD].
760 - * @return array A list of all the options that were changes through this request.
761 - */
762 - public static function whatOptionsWereChanged($request = array())
763 - {
764 - $options_changed = [ 'original' => [], 'changed' => [] ];
765 -
766 - $site_options = self::getSiteOptions();
767 -
768 - foreach ($request as $req_name => $req_value) {
769 - if (array_key_exists($req_name, $site_options) && $site_options[ $req_name ] != $req_value ) {
770 - $options_changed['original'][ $req_name ] = $site_options[ $req_name ];
771 - $options_changed['changed'][ $req_name ] = $req_value;
772 - }
773 - }
774 -
775 - return $options_changed;
776 - }
777 -
778 439
779 440 }