]> git.mxchange.org Git - friendica.git/blob - mod/admin.php
rino: settings in admin, choose lowest common on notify
[friendica.git] / mod / admin.php
1 <?php
2
3  /**
4   * Friendica admin
5   */
6 require_once("include/remoteupdate.php");
7 require_once("include/enotify.php");
8 require_once("include/text.php");
9
10
11 /**
12  * @param App $a
13  */
14 function admin_post(&$a){
15
16
17         if(!is_site_admin()) {
18                 return;
19         }
20
21         // do not allow a page manager to access the admin panel at all.
22
23         if(x($_SESSION,'submanage') && intval($_SESSION['submanage']))
24                 return;
25
26
27
28         // urls
29         if ($a->argc > 1){
30                 switch ($a->argv[1]){
31                         case 'site':
32                                 admin_page_site_post($a);
33                                 break;
34                         case 'users':
35                                 admin_page_users_post($a);
36                                 break;
37                         case 'plugins':
38                                 if ($a->argc > 2 &&
39                                         is_file("addon/".$a->argv[2]."/".$a->argv[2].".php")){
40                                                 @include_once("addon/".$a->argv[2]."/".$a->argv[2].".php");
41                                                 if(function_exists($a->argv[2].'_plugin_admin_post')) {
42                                                         $func = $a->argv[2].'_plugin_admin_post';
43                                                         $func($a);
44                                                 }
45                                 }
46                                 goaway($a->get_baseurl(true) . '/admin/plugins/' . $a->argv[2] );
47                                 return; // NOTREACHED
48                                 break;
49                         case 'themes':
50                                 $theme = $a->argv[2];
51                                 if (is_file("view/theme/$theme/config.php")){
52                                         require_once("view/theme/$theme/config.php");
53                                         if (function_exists("theme_admin_post")){
54                                                 theme_admin_post($a);
55                                         }
56                                 }
57                                 info(t('Theme settings updated.'));
58                                 if(is_ajax()) return;
59
60                                 goaway($a->get_baseurl(true) . '/admin/themes/' . $theme );
61                                 return;
62                                 break;
63                         case 'logs':
64                                 admin_page_logs_post($a);
65                                 break;
66                         case 'dbsync':
67                                 admin_page_dbsync_post($a);
68                                 break;
69                         case 'update':
70                                 admin_page_remoteupdate_post($a);
71                                 break;
72                 }
73         }
74
75         goaway($a->get_baseurl(true) . '/admin' );
76         return; // NOTREACHED
77 }
78
79 /**
80  * @param App $a
81  * @return string
82  */
83 function admin_content(&$a) {
84
85         if(!is_site_admin()) {
86                 return login(false);
87         }
88
89         if(x($_SESSION,'submanage') && intval($_SESSION['submanage']))
90                 return "";
91
92         // APC deactivated, since there are problems with PHP 5.5
93         //if (function_exists("apc_delete")) {
94         //      $toDelete = new APCIterator('user', APC_ITER_VALUE);
95         //      apc_delete($toDelete);
96         //}
97
98         /**
99          * Side bar links
100          */
101
102         // array( url, name, extra css classes )
103         $aside = Array(
104                 'site'   =>     Array($a->get_baseurl(true)."/admin/site/", t("Site") , "site"),
105                 'users'  =>     Array($a->get_baseurl(true)."/admin/users/", t("Users") , "users"),
106                 'plugins'=>     Array($a->get_baseurl(true)."/admin/plugins/", t("Plugins") , "plugins"),
107                 'themes' =>     Array($a->get_baseurl(true)."/admin/themes/", t("Themes") , "themes"),
108                 'dbsync' => Array($a->get_baseurl(true)."/admin/dbsync/", t('DB updates'), "dbsync"),
109                 //'update' =>   Array($a->get_baseurl(true)."/admin/update/", t("Software Update") , "update")
110         );
111
112         /* get plugins admin page */
113
114         $r = q("SELECT name FROM `addon` WHERE `plugin_admin`=1");
115         $aside['plugins_admin']=Array();
116         foreach ($r as $h){
117                 $plugin =$h['name'];
118                 $aside['plugins_admin'][] = Array($a->get_baseurl(true)."/admin/plugins/".$plugin, $plugin, "plugin");
119                 // temp plugins with admin
120                 $a->plugins_admin[] = $plugin;
121         }
122
123         $aside['logs'] = Array($a->get_baseurl(true)."/admin/logs/", t("Logs"), "logs");
124         $aside['diagnostics_probe'] = Array($a->get_baseurl(true).'/probe/', t('probe address'), 'probe');
125         $aside['diagnostics_webfinger'] = Array($a->get_baseurl(true).'/webfinger/', t('check webfinger'), 'webfinger');
126
127         $t = get_markup_template("admin_aside.tpl");
128         $a->page['aside'] .= replace_macros( $t, array(
129                         '$admin' => $aside,
130                         '$admtxt' => t('Admin'),
131                         '$plugadmtxt' => t('Plugin Features'),
132                         '$logtxt' => t('Logs'),
133                         '$diagnosticstxt' => t('diagnostics'),
134                         '$h_pending' => t('User registrations waiting for confirmation'),
135                         '$admurl'=> $a->get_baseurl(true)."/admin/"
136         ));
137
138
139
140         /**
141          * Page content
142          */
143         $o = '';
144         // urls
145         if ($a->argc > 1){
146                 switch ($a->argv[1]){
147                         case 'site':
148                                 $o = admin_page_site($a);
149                                 break;
150                         case 'users':
151                                 $o = admin_page_users($a);
152                                 break;
153                         case 'plugins':
154                                 $o = admin_page_plugins($a);
155                                 break;
156                         case 'themes':
157                                 $o = admin_page_themes($a);
158                                 break;
159                         case 'logs':
160                                 $o = admin_page_logs($a);
161                                 break;
162                         case 'dbsync':
163                                 $o = admin_page_dbsync($a);
164                                 break;
165                         case 'update':
166                                 $o = admin_page_remoteupdate($a);
167                                 break;
168                         default:
169                                 notice( t("Item not found.") );
170                 }
171         } else {
172                 $o = admin_page_summary($a);
173         }
174
175         if(is_ajax()) {
176                 echo $o;
177                 killme();
178                 return '';
179         } else {
180                 return $o;
181         }
182 }
183
184
185 /**
186  * Admin Summary Page
187  * @param App $a
188  * @return string
189  */
190 function admin_page_summary(&$a) {
191         $r = q("SELECT `page-flags`, COUNT(uid) as `count` FROM `user` GROUP BY `page-flags`");
192         $accounts = Array(
193                 Array( t('Normal Account'), 0),
194                 Array( t('Soapbox Account'), 0),
195                 Array( t('Community/Celebrity Account'), 0),
196                 Array( t('Automatic Friend Account'), 0),
197                 Array( t('Blog Account'), 0),
198                 Array( t('Private Forum'), 0)
199         );
200
201         $users=0;
202         foreach ($r as $u){ $accounts[$u['page-flags']][1] = $u['count']; $users+= $u['count']; }
203
204         logger('accounts: ' . print_r($accounts,true),LOGGER_DATA);
205
206         $r = q("SELECT COUNT(id) as `count` FROM `register`");
207         $pending = $r[0]['count'];
208
209         $r = q("select count(*) as total from deliverq where 1");
210         $deliverq = (($r) ? $r[0]['total'] : 0);
211
212         $r = q("select count(*) as total from queue where 1");
213         $queue = (($r) ? $r[0]['total'] : 0);
214
215         // We can do better, but this is a quick queue status
216
217         $queues = array( 'label' => t('Message queues'), 'deliverq' => $deliverq, 'queue' => $queue );
218
219
220         $t = get_markup_template("admin_summary.tpl");
221         return replace_macros($t, array(
222                 '$title' => t('Administration'),
223                 '$page' => t('Summary'),
224                 '$queues' => $queues,
225                 '$users' => Array( t('Registered users'), $users),
226                 '$accounts' => $accounts,
227                 '$pending' => Array( t('Pending registrations'), $pending),
228                 '$version' => Array( t('Version'), FRIENDICA_VERSION),
229                 '$platform' => FRIENDICA_PLATFORM,
230                 '$codename' => FRIENDICA_CODENAME,
231                 '$build' =>  get_config('system','build'),
232                 '$plugins' => Array( t('Active plugins'), $a->plugins )
233         ));
234 }
235
236
237 /**
238  * Admin Site Page
239  *  @param App $a
240  */
241 function admin_page_site_post(&$a){
242         if (!x($_POST,"page_site")){
243                 return;
244         }
245
246         check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
247
248         // relocate
249         if (x($_POST,'relocate') && x($_POST,'relocate_url') && $_POST['relocate_url']!=""){
250                 $new_url = $_POST['relocate_url'];
251                 $new_url = rtrim($new_url,"/");
252
253                 $parsed = @parse_url($new_url);
254                 if (!$parsed || (!x($parsed,'host') || !x($parsed,'scheme'))) {
255                         notice(t("Can not parse base url. Must have at least <scheme>://<domain>"));
256                         goaway($a->get_baseurl(true) . '/admin/site' );
257                 }
258
259                 /* steps:
260                  * replace all "baseurl" to "new_url" in config, profile, term, items and contacts
261                  * send relocate for every local user
262                  * */
263
264                 $old_url = $a->get_baseurl(true);
265
266                 function update_table($table_name, $fields, $old_url, $new_url) {
267                         global $db, $a;
268
269                         $dbold = dbesc($old_url);
270                         $dbnew = dbesc($new_url);
271
272                         $upd = array();
273                         foreach ($fields as $f) {
274                                 $upd[] = "`$f` = REPLACE(`$f`, '$dbold', '$dbnew')";
275                         }
276
277                         $upds = implode(", ", $upd);
278
279
280
281                         $q = sprintf("UPDATE %s SET %s;", $table_name, $upds);
282                         $r = q($q);
283                         if (!$r) {
284                                 notice( "Failed updating '$table_name': " . $db->error );
285                                 goaway($a->get_baseurl(true) . '/admin/site' );
286                         }
287                 }
288
289                 // update tables
290                 update_table("profile", array('photo', 'thumb'), $old_url, $new_url);
291                 update_table("term", array('url'), $old_url, $new_url);
292                 update_table("contact", array('photo','thumb','micro','url','nurl','request','notify','poll','confirm','poco'), $old_url, $new_url);
293                 update_table("unique_contacts", array('url'), $old_url, $new_url);
294                 update_table("item", array('owner-link','owner-avatar','author-name','author-link','author-avatar','body','plink','tag'), $old_url, $new_url);
295
296                 // update config
297                 $a->set_baseurl($new_url);
298                 set_config('system','url',$new_url);
299
300                 // send relocate
301                 $users = q("SELECT uid FROM user WHERE account_removed = 0 AND account_expired = 0");
302
303                 foreach ($users as $user) {
304                         proc_run('php', 'include/notifier.php', 'relocate', $user['uid']);
305                 }
306
307                 info("Relocation started. Could take a while to complete.");
308
309                 goaway($a->get_baseurl(true) . '/admin/site' );
310         }
311         // end relocate
312
313         $sitename               =       ((x($_POST,'sitename'))                 ? notags(trim($_POST['sitename']))              : '');
314         $hostname               =       ((x($_POST,'hostname'))                 ? notags(trim($_POST['hostname']))              : '');
315         $sender_email           =       ((x($_POST,'sender_email'))             ? notags(trim($_POST['sender_email']))          : '');
316         $banner                 =       ((x($_POST,'banner'))                   ? trim($_POST['banner'])                        : false);
317         $shortcut_icon          =       ((x($_POST,'shortcut_icon'))            ? notags(trim($_POST['shortcut_icon']))         : '');
318         $touch_icon             =       ((x($_POST,'touch_icon'))               ? notags(trim($_POST['touch_icon']))            : '');
319         $info                   =       ((x($_POST,'info'))                     ? trim($_POST['info'])                  : false);
320         $language               =       ((x($_POST,'language'))                 ? notags(trim($_POST['language']))              : '');
321         $theme                  =       ((x($_POST,'theme'))                    ? notags(trim($_POST['theme']))                 : '');
322         $theme_mobile           =       ((x($_POST,'theme_mobile'))             ? notags(trim($_POST['theme_mobile']))          : '');
323         $maximagesize           =       ((x($_POST,'maximagesize'))             ? intval(trim($_POST['maximagesize']))          :  0);
324         $maximagelength         =       ((x($_POST,'maximagelength'))           ? intval(trim($_POST['maximagelength']))        :  MAX_IMAGE_LENGTH);
325         $jpegimagequality       =       ((x($_POST,'jpegimagequality'))         ? intval(trim($_POST['jpegimagequality']))      :  JPEG_QUALITY);
326
327
328         $register_policy        =       ((x($_POST,'register_policy'))          ? intval(trim($_POST['register_policy']))       :  0);
329         $daily_registrations    =       ((x($_POST,'max_daily_registrations'))  ? intval(trim($_POST['max_daily_registrations']))       :0);
330         $abandon_days           =       ((x($_POST,'abandon_days'))             ? intval(trim($_POST['abandon_days']))          :  0);
331
332         $register_text          =       ((x($_POST,'register_text'))            ? notags(trim($_POST['register_text']))         : '');
333
334         $allowed_sites          =       ((x($_POST,'allowed_sites'))            ? notags(trim($_POST['allowed_sites']))         : '');
335         $allowed_email          =       ((x($_POST,'allowed_email'))            ? notags(trim($_POST['allowed_email']))         : '');
336         $block_public           =       ((x($_POST,'block_public'))             ? True                                          : False);
337         $force_publish          =       ((x($_POST,'publish_all'))              ? True                                          : False);
338         $global_directory       =       ((x($_POST,'directory_submit_url'))     ? notags(trim($_POST['directory_submit_url']))  : '');
339         $thread_allow           =       ((x($_POST,'thread_allow'))             ? True                                          : False);
340         $newuser_private                =       ((x($_POST,'newuser_private'))          ? True                                          : False);
341         $enotify_no_content             =       ((x($_POST,'enotify_no_content'))       ? True                                          : False);
342         $private_addons                 =       ((x($_POST,'private_addons'))           ? True                                          : False);
343         $disable_embedded               =       ((x($_POST,'disable_embedded'))         ? True                                          : False);
344         $allow_users_remote_self        =       ((x($_POST,'allow_users_remote_self'))          ? True                                          : False);
345
346         $no_multi_reg           =       ((x($_POST,'no_multi_reg'))             ? True                                          : False);
347         $no_openid              =       !((x($_POST,'no_openid'))               ? True                                          : False);
348         $no_regfullname         =       !((x($_POST,'no_regfullname'))          ? True                                          : False);
349         $no_utf                 =       !((x($_POST,'no_utf'))                  ? True                                          : False);
350         $community_page_style   =       ((x($_POST,'community_page_style'))     ? intval(trim($_POST['community_page_style']))  : 0);
351         $max_author_posts_community_page        =       ((x($_POST,'max_author_posts_community_page'))  ? intval(trim($_POST['max_author_posts_community_page']))       : 0);
352
353         $verifyssl              =       ((x($_POST,'verifyssl'))                ? True                                          : False);
354         $proxyuser              =       ((x($_POST,'proxyuser'))                ? notags(trim($_POST['proxyuser']))             : '');
355         $proxy                  =       ((x($_POST,'proxy'))                    ? notags(trim($_POST['proxy']))                 : '');
356         $timeout                =       ((x($_POST,'timeout'))                  ? intval(trim($_POST['timeout']))               : 60);
357         $delivery_interval      =       ((x($_POST,'delivery_interval'))        ? intval(trim($_POST['delivery_interval']))     : 0);
358         $poll_interval          =       ((x($_POST,'poll_interval'))            ? intval(trim($_POST['poll_interval']))         : 0);
359         $maxloadavg             =       ((x($_POST,'maxloadavg'))               ? intval(trim($_POST['maxloadavg']))            : 50);
360         $maxloadavg_frontend    =       ((x($_POST,'maxloadavg_frontend'))      ? intval(trim($_POST['maxloadavg_frontend']))   : 50);
361         $dfrn_only              =       ((x($_POST,'dfrn_only'))                ? True                                          : False);
362         $ostatus_disabled       =       !((x($_POST,'ostatus_disabled'))        ? True                                          : False);
363         $ostatus_poll_interval  =       ((x($_POST,'ostatus_poll_interval'))    ? intval(trim($_POST['ostatus_poll_interval'])) :  0);
364         $diaspora_enabled       =       ((x($_POST,'diaspora_enabled'))         ? True                                          : False);
365         $ssl_policy             =       ((x($_POST,'ssl_policy'))               ? intval($_POST['ssl_policy'])                  : 0);
366         $force_ssl              =       ((x($_POST,'force_ssl'))                ? True                                          : False);
367         $old_share              =       ((x($_POST,'old_share'))                ? True                                          : False);
368         $hide_help              =       ((x($_POST,'hide_help'))                ? True                                          : False);
369         $suppress_language      =       ((x($_POST,'suppress_language'))        ? True                                          : False);
370         $suppress_tags          =       ((x($_POST,'suppress_tags'))            ? True                                          : False);
371         $use_fulltext_engine    =       ((x($_POST,'use_fulltext_engine'))      ? True                                          : False);
372         $itemcache              =       ((x($_POST,'itemcache'))                ? notags(trim($_POST['itemcache']))             : '');
373         $itemcache_duration     =       ((x($_POST,'itemcache_duration'))       ? intval($_POST['itemcache_duration'])          : 0);
374         $max_comments           =       ((x($_POST,'max_comments'))             ? intval($_POST['max_comments'])                : 0);
375         $lockpath               =       ((x($_POST,'lockpath'))                 ? notags(trim($_POST['lockpath']))              : '');
376         $temppath               =       ((x($_POST,'temppath'))                 ? notags(trim($_POST['temppath']))              : '');
377         $basepath               =       ((x($_POST,'basepath'))                 ? notags(trim($_POST['basepath']))              : '');
378         $singleuser             =       ((x($_POST,'singleuser'))               ? notags(trim($_POST['singleuser']))            : '');
379         $proxy_disabled         =       ((x($_POST,'proxy_disabled'))           ? True                                          : False);
380         $old_pager              =       ((x($_POST,'old_pager'))                ? True                                          : False);
381         $only_tag_search        =       ((x($_POST,'only_tag_search'))          ? True                                          : False);
382         $rino                   =       ((x($_POST,'rino'))                             ? intval($_POST['rino'])                                : 0);
383         
384         
385         if($ssl_policy != intval(get_config('system','ssl_policy'))) {
386                 if($ssl_policy == SSL_POLICY_FULL) {
387                         q("update `contact` set
388                                 `url`     = replace(`url`    , 'http:' , 'https:'),
389                                 `photo`   = replace(`photo`  , 'http:' , 'https:'),
390                                 `thumb`   = replace(`thumb`  , 'http:' , 'https:'),
391                                 `micro`   = replace(`micro`  , 'http:' , 'https:'),
392                                 `request` = replace(`request`, 'http:' , 'https:'),
393                                 `notify`  = replace(`notify` , 'http:' , 'https:'),
394                                 `poll`    = replace(`poll`   , 'http:' , 'https:'),
395                                 `confirm` = replace(`confirm`, 'http:' , 'https:'),
396                                 `poco`    = replace(`poco`   , 'http:' , 'https:')
397                                 where `self` = 1"
398                         );
399                         q("update `profile` set
400                                 `photo`   = replace(`photo`  , 'http:' , 'https:'),
401                                 `thumb`   = replace(`thumb`  , 'http:' , 'https:')
402                                 where 1 "
403                         );
404                 }
405                 elseif($ssl_policy == SSL_POLICY_SELFSIGN) {
406                         q("update `contact` set
407                                 `url`     = replace(`url`    , 'https:' , 'http:'),
408                                 `photo`   = replace(`photo`  , 'https:' , 'http:'),
409                                 `thumb`   = replace(`thumb`  , 'https:' , 'http:'),
410                                 `micro`   = replace(`micro`  , 'https:' , 'http:'),
411                                 `request` = replace(`request`, 'https:' , 'http:'),
412                                 `notify`  = replace(`notify` , 'https:' , 'http:'),
413                                 `poll`    = replace(`poll`   , 'https:' , 'http:'),
414                                 `confirm` = replace(`confirm`, 'https:' , 'http:'),
415                                 `poco`    = replace(`poco`   , 'https:' , 'http:')
416                                 where `self` = 1"
417                         );
418                         q("update `profile` set
419                                 `photo`   = replace(`photo`  , 'https:' , 'http:'),
420                                 `thumb`   = replace(`thumb`  , 'https:' , 'http:')
421                                 where 1 "
422                         );
423                 }
424         }
425         set_config('system','ssl_policy',$ssl_policy);
426         set_config('system','delivery_interval',$delivery_interval);
427         set_config('system','poll_interval',$poll_interval);
428         set_config('system','maxloadavg',$maxloadavg);
429         set_config('system','maxloadavg_frontend',$maxloadavg_frontend);
430         set_config('config','sitename',$sitename);
431         set_config('config','hostname',$hostname);
432         set_config('config','sender_email', $sender_email);
433         set_config('system','suppress_language',$suppress_language);
434         set_config('system','suppress_tags',$suppress_tags);
435         set_config('system','shortcut_icon',$shortcut_icon);
436         set_config('system','touch_icon',$touch_icon);
437         
438         if ($banner==""){
439                 // don't know why, but del_config doesn't work...
440                 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
441                         dbesc("system"),
442                         dbesc("banner")
443                 );
444         } else {
445                 set_config('system','banner', $banner);
446         }
447         if ($info=="") {
448                 del_config('config','info');
449         } else {
450                 set_config('config','info',$info);
451         }
452         set_config('system','language', $language);
453         set_config('system','theme', $theme);
454         if ( $theme_mobile === '---' ) {
455                 del_config('system','mobile-theme');
456         } else {
457                 set_config('system','mobile-theme', $theme_mobile);
458                 }
459                 if ( $singleuser === '---' ) {
460                         del_config('system','singleuser');
461                 } else {
462                         set_config('system','singleuser', $singleuser);
463                 }
464         set_config('system','maximagesize', $maximagesize);
465         set_config('system','max_image_length', $maximagelength);
466         set_config('system','jpeg_quality', $jpegimagequality);
467
468         set_config('config','register_policy', $register_policy);
469         set_config('system','max_daily_registrations', $daily_registrations);
470         set_config('system','account_abandon_days', $abandon_days);
471         set_config('config','register_text', $register_text);
472         set_config('system','allowed_sites', $allowed_sites);
473         set_config('system','allowed_email', $allowed_email);
474         set_config('system','block_public', $block_public);
475         set_config('system','publish_all', $force_publish);
476         if ($global_directory==""){
477                 // don't know why, but del_config doesn't work...
478                 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
479                         dbesc("system"),
480                         dbesc("directory_submit_url")
481                 );
482         } else {
483                 set_config('system','directory_submit_url', $global_directory);
484         }
485         set_config('system','thread_allow', $thread_allow);
486         set_config('system','newuser_private', $newuser_private);
487         set_config('system','enotify_no_content', $enotify_no_content);
488         set_config('system','disable_embedded', $disable_embedded);
489         set_config('system','allow_users_remote_self', $allow_users_remote_self);
490
491         set_config('system','block_extended_register', $no_multi_reg);
492         set_config('system','no_openid', $no_openid);
493         set_config('system','no_regfullname', $no_regfullname);
494         set_config('system','community_page_style', $community_page_style);
495         set_config('system','max_author_posts_community_page', $max_author_posts_community_page);
496         set_config('system','no_utf', $no_utf);
497         set_config('system','verifyssl', $verifyssl);
498         set_config('system','proxyuser', $proxyuser);
499         set_config('system','proxy', $proxy);
500         set_config('system','curl_timeout', $timeout);
501         set_config('system','dfrn_only', $dfrn_only);
502         set_config('system','ostatus_disabled', $ostatus_disabled);
503         set_config('system','ostatus_poll_interval', $ostatus_poll_interval);
504         set_config('system','diaspora_enabled', $diaspora_enabled);
505         set_config('config','private_addons', $private_addons);
506
507         set_config('system','force_ssl', $force_ssl);
508         set_config('system','old_share', $old_share);
509         set_config('system','hide_help', $hide_help);
510         set_config('system','use_fulltext_engine', $use_fulltext_engine);
511         set_config('system','itemcache', $itemcache);
512         set_config('system','itemcache_duration', $itemcache_duration);
513         set_config('system','max_comments', $max_comments);
514         set_config('system','lockpath', $lockpath);
515         set_config('system','temppath', $temppath);
516         set_config('system','basepath', $basepath);
517         set_config('system','proxy_disabled', $proxy_disabled);
518         set_config('system','old_pager', $old_pager);
519         set_config('system','only_tag_search', $only_tag_search);
520
521         set_config('system','rino_encrypt', $rino);
522         
523         
524         info( t('Site settings updated.') . EOL);
525         goaway($a->get_baseurl(true) . '/admin/site' );
526         return; // NOTREACHED
527
528 }
529
530 /**
531  * @param  App $a
532  * @return string
533  */
534 function admin_page_site(&$a) {
535
536         /* Installed langs */
537         $lang_choices = array();
538         $langs = glob('view/*/strings.php');
539
540         if(is_array($langs) && count($langs)) {
541                 if(! in_array('view/en/strings.php',$langs))
542                         $langs[] = 'view/en/';
543                 asort($langs);
544                 foreach($langs as $l) {
545                         $t = explode("/",$l);
546                         $lang_choices[$t[1]] = $t[1];
547                 }
548         }
549
550         /* Installed themes */
551         $theme_choices = array();
552         $theme_choices_mobile = array();
553         $theme_choices_mobile["---"] = t("No special theme for mobile devices");
554         $files = glob('view/theme/*');
555         if($files) {
556                 foreach($files as $file) {
557                         $f = basename($file);
558                         $theme_name = ((file_exists($file . '/experimental')) ?  sprintf("%s - \x28Experimental\x29", $f) : $f);
559                         if (file_exists($file . '/mobile')) {
560                                 $theme_choices_mobile[$f] = $theme_name;
561                         }
562                 else {
563                                 $theme_choices[$f] = $theme_name;
564                         }
565                 }
566                 }
567
568                 /* Community page style */
569                 $community_page_style_choices = array(
570                         CP_NO_COMMUNITY_PAGE => t("No community page"),
571                         CP_USERS_ON_SERVER => t("Public postings from users of this site"),
572                         CP_GLOBAL_COMMUNITY => t("Global community page")
573                         );
574
575                 /* OStatus conversation poll choices */
576                 $ostatus_poll_choices = array(
577                         "-2" => t("Never"),
578                         "-1" => t("At post arrival"),
579                         "0" => t("Frequently"),
580                         "60" => t("Hourly"),
581                         "720" => t("Twice daily"),
582                         "1440" => t("Daily")
583                         );
584
585                 /* get user names to make the install a personal install of X */
586                 $user_names = array();
587                 $user_names['---'] = t('Multi user instance');
588                 $users = q("SELECT username, nickname FROM `user`");
589                 foreach ($users as $user) {
590                         $user_names[$user['nickname']] = $user['username'];
591                 }
592
593         /* Banner */
594         $banner = get_config('system','banner');
595         if($banner == false)
596                 $banner = '<a href="http://friendica.com"><img id="logo-img" src="images/friendica-32.png" alt="logo" /></a><span id="logo-text"><a href="http://friendica.com">Friendica</a></span>';
597         $banner = htmlspecialchars($banner);
598         $info = get_config('config','info');
599         $info = htmlspecialchars($info);
600
601         // Automatically create temporary paths
602         get_temppath();
603         get_lockpath();
604         get_itemcachepath();
605
606         //echo "<pre>"; var_dump($lang_choices); die("</pre>");
607
608         /* Register policy */
609         $register_choices = Array(
610                 REGISTER_CLOSED => t("Closed"),
611                 REGISTER_APPROVE => t("Requires approval"),
612                 REGISTER_OPEN => t("Open")
613         );
614
615         $ssl_choices = array(
616                 SSL_POLICY_NONE => t("No SSL policy, links will track page SSL state"),
617                 SSL_POLICY_FULL => t("Force all links to use SSL"),
618                 SSL_POLICY_SELFSIGN => t("Self-signed certificate, use SSL for local links only (discouraged)")
619         );
620
621         if ($a->config['hostname'] == "")
622                 $a->config['hostname'] = $a->get_hostname();
623
624         $t = get_markup_template("admin_site.tpl");
625         return replace_macros($t, array(
626                 '$title' => t('Administration'),
627                 '$page' => t('Site'),
628                 '$submit' => t('Save Settings'),
629                 '$registration' => t('Registration'),
630                 '$upload' => t('File upload'),
631                 '$corporate' => t('Policies'),
632                 '$advanced' => t('Advanced'),
633                 '$performance' => t('Performance'),
634                 '$relocate'=> t('Relocate - WARNING: advanced function. Could make this server unreachable.'),
635                 '$baseurl' => $a->get_baseurl(true),
636                 // name, label, value, help string, extra data...
637                 '$sitename'             => array('sitename', t("Site name"), $a->config['sitename'],'UTF-8'),
638                 '$hostname'             => array('hostname', t("Host name"), $a->config['hostname'], ""),
639                 '$sender_email'         => array('sender_email', t("Sender Email"), $a->config['sender_email'], "The email address your server shall use to send notification emails from.", "", "", "email"),
640                 '$banner'               => array('banner', t("Banner/Logo"), $banner, ""),
641                 '$shortcut_icon'        => array('shortcut_icon', t("Shortcut icon"), get_config('system','shortcut_icon'),  "Link to an icon that will be used for browsers."),
642                 '$touch_icon'           => array('touch_icon', t("Touch icon"), get_config('system','touch_icon'),  "Link to an icon that will be used for tablets and mobiles."),
643                 '$info' => array('info',t('Additional Info'), $info, t('For public servers: you can add additional information here that will be listed at dir.friendica.com/siteinfo.')),
644                 '$language'             => array('language', t("System language"), get_config('system','language'), "", $lang_choices),
645                 '$theme'                => array('theme', t("System theme"), get_config('system','theme'), t("Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"), $theme_choices),
646                 '$theme_mobile'         => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile-theme'), t("Theme for mobile devices"), $theme_choices_mobile),
647                 '$ssl_policy'           => array('ssl_policy', t("SSL link policy"), (string) intval(get_config('system','ssl_policy')), t("Determines whether generated links should be forced to use SSL"), $ssl_choices),
648                 '$force_ssl'            => array('force_ssl', t("Force SSL"), get_config('system','force_ssl'), t("Force all Non-SSL requests to SSL - Attention: on some systems it could lead to endless loops.")),
649                 '$old_share'            => array('old_share', t("Old style 'Share'"), get_config('system','old_share'), t("Deactivates the bbcode element 'share' for repeating items.")),
650                 '$hide_help'            => array('hide_help', t("Hide help entry from navigation menu"), get_config('system','hide_help'), t("Hides the menu entry for the Help pages from the navigation menu. You can still access it calling /help directly.")),
651                 '$singleuser'           => array('singleuser', t("Single user instance"), get_config('system','singleuser'), t("Make this instance multi-user or single-user for the named user"), $user_names),
652                 '$maximagesize'         => array('maximagesize', t("Maximum image size"), get_config('system','maximagesize'), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")),
653                 '$maximagelength'               => array('maximagelength', t("Maximum image length"), get_config('system','max_image_length'), t("Maximum length in pixels of the longest side of uploaded images. Default is -1, which means no limits.")),
654                 '$jpegimagequality'             => array('jpegimagequality', t("JPEG image quality"), get_config('system','jpeg_quality'), t("Uploaded JPEGS will be saved at this quality setting [0-100]. Default is 100, which is full quality.")),
655
656                 '$register_policy'      => array('register_policy', t("Register policy"), $a->config['register_policy'], "", $register_choices),
657                 '$daily_registrations'  => array('max_daily_registrations', t("Maximum Daily Registrations"), get_config('system', 'max_daily_registrations'), t("If registration is permitted above, this sets the maximum number of new user registrations to accept per day.  If register is set to closed, this setting has no effect.")),
658                 '$register_text'        => array('register_text', t("Register text"), $a->config['register_text'], t("Will be displayed prominently on the registration page.")),
659                 '$abandon_days'         => array('abandon_days', t('Accounts abandoned after x days'), get_config('system','account_abandon_days'), t('Will not waste system resources polling external sites for abandonded accounts. Enter 0 for no time limit.')),
660                 '$allowed_sites'        => array('allowed_sites', t("Allowed friend domains"), get_config('system','allowed_sites'), t("Comma separated list of domains which are allowed to establish friendships with this site. Wildcards are accepted. Empty to allow any domains")),
661                 '$allowed_email'        => array('allowed_email', t("Allowed email domains"), get_config('system','allowed_email'), t("Comma separated list of domains which are allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains")),
662                 '$block_public'         => array('block_public', t("Block public"), get_config('system','block_public'), t("Check to block public access to all otherwise public personal pages on this site unless you are currently logged in.")),
663                 '$force_publish'        => array('publish_all', t("Force publish"), get_config('system','publish_all'), t("Check to force all profiles on this site to be listed in the site directory.")),
664                 '$global_directory'     => array('directory_submit_url', t("Global directory update URL"), get_config('system','directory_submit_url'), t("URL to update the global directory. If this is not set, the global directory is completely unavailable to the application.")),
665                 '$thread_allow'         => array('thread_allow', t("Allow threaded items"), get_config('system','thread_allow'), t("Allow infinite level threading for items on this site.")),
666                 '$newuser_private'      => array('newuser_private', t("Private posts by default for new users"), get_config('system','newuser_private'), t("Set default post permissions for all new members to the default privacy group rather than public.")),
667                 '$enotify_no_content'   => array('enotify_no_content', t("Don't include post content in email notifications"), get_config('system','enotify_no_content'), t("Don't include the content of a post/comment/private message/etc. in the email notifications that are sent out from this site, as a privacy measure.")),
668                 '$private_addons'       => array('private_addons', t("Disallow public access to addons listed in the apps menu."), get_config('config','private_addons'), t("Checking this box will restrict addons listed in the apps menu to members only.")),
669                 '$disable_embedded'     => array('disable_embedded', t("Don't embed private images in posts"), get_config('system','disable_embedded'), t("Don't replace locally-hosted private photos in posts with an embedded copy of the image. This means that contacts who receive posts containing private photos will have to authenticate and load each image, which may take a while.")),
670                 '$allow_users_remote_self'      => array('allow_users_remote_self', t('Allow Users to set remote_self'), get_config('system','allow_users_remote_self'), t('With checking this, every user is allowed to mark every contact as a remote_self in the repair contact dialog. Setting this flag on a contact causes mirroring every posting of that contact in the users stream.')),
671                 '$no_multi_reg'         => array('no_multi_reg', t("Block multiple registrations"),  get_config('system','block_extended_register'), t("Disallow users to register additional accounts for use as pages.")),
672                 '$no_openid'            => array('no_openid', t("OpenID support"), !get_config('system','no_openid'), t("OpenID support for registration and logins.")),
673                 '$no_regfullname'       => array('no_regfullname', t("Fullname check"), !get_config('system','no_regfullname'), t("Force users to register with a space between firstname and lastname in Full name, as an antispam measure")),
674                 '$no_utf'               => array('no_utf', t("UTF-8 Regular expressions"), !get_config('system','no_utf'), t("Use PHP UTF8 regular expressions")),
675                 '$community_page_style' => array('community_page_style', t("Community Page Style"), get_config('system','community_page_style'), t("Type of community page to show. 'Global community' shows every public posting from an open distributed network that arrived on this server."), $community_page_style_choices),
676                 '$max_author_posts_community_page' => array('max_author_posts_community_page', t("Posts per user on community page"), get_config('system','max_author_posts_community_page'), t("The maximum number of posts per user on the community page. (Not valid for 'Global Community')")),
677                 '$ostatus_disabled'     => array('ostatus_disabled', t("Enable OStatus support"), !get_config('system','ostatus_disabled'), t("Provide built-in OStatus \x28StatusNet, GNU Social etc.\x29 compatibility. All communications in OStatus are public, so privacy warnings will be occasionally displayed.")),
678                 '$ostatus_poll_interval'        => array('ostatus_poll_interval', t("OStatus conversation completion interval"), (string) intval(get_config('system','ostatus_poll_interval')), t("How often shall the poller check for new entries in OStatus conversations? This can be a very ressource task."), $ostatus_poll_choices),
679                 '$diaspora_enabled'     => array('diaspora_enabled', t("Enable Diaspora support"), get_config('system','diaspora_enabled'), t("Provide built-in Diaspora network compatibility.")),
680                 '$dfrn_only'            => array('dfrn_only', t('Only allow Friendica contacts'), get_config('system','dfrn_only'), t("All contacts must use Friendica protocols. All other built-in communication protocols disabled.")),
681                 '$verifyssl'            => array('verifyssl', t("Verify SSL"), get_config('system','verifyssl'), t("If you wish, you can turn on strict certificate checking. This will mean you cannot connect (at all) to self-signed SSL sites.")),
682                 '$proxyuser'            => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""),
683                 '$proxy'                => array('proxy', t("Proxy URL"), get_config('system','proxy'), ""),
684                 '$timeout'              => array('timeout', t("Network timeout"), (x(get_config('system','curl_timeout'))?get_config('system','curl_timeout'):60), t("Value is in seconds. Set to 0 for unlimited (not recommended).")),
685                 '$delivery_interval'    => array('delivery_interval', t("Delivery interval"), (x(get_config('system','delivery_interval'))?get_config('system','delivery_interval'):2), t("Delay background delivery processes by this many seconds to reduce system load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 for large dedicated servers.")),
686                 '$poll_interval'        => array('poll_interval', t("Poll interval"), (x(get_config('system','poll_interval'))?get_config('system','poll_interval'):2), t("Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval.")),
687                 '$maxloadavg'           => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")),
688                 '$maxloadavg_frontend'  => array('maxloadavg_frontend', t("Maximum Load Average (Frontend)"), ((intval(get_config('system','maxloadavg_frontend')) > 0)?get_config('system','maxloadavg_frontend'):50), t("Maximum system load before the frontend quits service - default 50.")),
689
690                 '$use_fulltext_engine'  => array('use_fulltext_engine', t("Use MySQL full text engine"), get_config('system','use_fulltext_engine'), t("Activates the full text engine. Speeds up search - but can only search for four and more characters.")),
691                 '$suppress_language'    => array('suppress_language', t("Suppress Language"), get_config('system','suppress_language'), t("Suppress language information in meta information about a posting.")),
692                 '$suppress_tags'        => array('suppress_tags', t("Suppress Tags"), get_config('system','suppress_tags'), t("Suppress showing a list of hashtags at the end of the posting.")),
693                 '$itemcache'            => array('itemcache', t("Path to item cache"), get_config('system','itemcache'), "The item caches buffers generated bbcode and external images."),
694                 '$itemcache_duration'   => array('itemcache_duration', t("Cache duration in seconds"), get_config('system','itemcache_duration'), t("How long should the cache files be hold? Default value is 86400 seconds (One day). To disable the item cache, set the value to -1.")),
695                 '$max_comments'         => array('max_comments', t("Maximum numbers of comments per post"), get_config('system','max_comments'), t("How much comments should be shown for each post? Default value is 100.")),
696                 '$lockpath'             => array('lockpath', t("Path for lock file"), get_config('system','lockpath'), "The lock file is used to avoid multiple pollers at one time. Only define a folder here."),
697                 '$temppath'             => array('temppath', t("Temp path"), get_config('system','temppath'), "If you have a restricted system where the webserver can't access the system temp path, enter another path here."),
698                 '$basepath'             => array('basepath', t("Base path to installation"), get_config('system','basepath'), "If the system cannot detect the correct path to your installation, enter the correct path here. This setting should only be set if you are using a restricted system and symbolic links to your webroot."),
699                 '$proxy_disabled'       => array('proxy_disabled', t("Disable picture proxy"), get_config('system','proxy_disabled'), t("The picture proxy increases performance and privacy. It shouldn't be used on systems with very low bandwith.")),
700                 '$old_pager'            => array('old_pager', t("Enable old style pager"), get_config('system','old_pager'), t("The old style pager has page numbers but slows down massively the page speed.")),
701                 '$only_tag_search'      => array('only_tag_search', t("Only search in tags"), get_config('system','only_tag_search'), t("On large systems the text search can slow down the system extremely.")),
702
703                 '$relocate_url'     => array('relocate_url', t("New base url"), $a->get_baseurl(), "Change base url for this server. Sends relocate message to all DFRN contacts of all users."),
704                 
705                 '$rino'                 => array('rino', t("RINO Encription"), intval(get_config('system','rino_encrypt')), t("Encription layer between nodes."), array("Disabled", "RINO1 (deprecated)", "RINO2")),
706                 
707                 '$form_security_token' => get_form_security_token("admin_site")
708
709         ));
710
711 }
712
713
714 function admin_page_dbsync(&$a) {
715
716         $o = '';
717
718         if($a->argc > 3 && intval($a->argv[3]) && $a->argv[2] === 'mark') {
719                 set_config('database', 'update_' . intval($a->argv[3]), 'success');
720                 $curr = get_config('system','build');
721                 if(intval($curr) == intval($a->argv[3]))
722                         set_config('system','build',intval($curr) + 1);
723                 info( t('Update has been marked successful') . EOL);
724                 goaway($a->get_baseurl(true) . '/admin/dbsync');
725         }
726
727         if(($a->argc > 2) AND (intval($a->argv[2]) OR ($a->argv[2] === 'check'))) {
728                 require_once("include/dbstructure.php");
729                 $retval = update_structure(false, true);
730                 if (!$retval) {
731                         $o .= sprintf(t("Database structure update %s was successfully applied."), DB_UPDATE_VERSION)."<br />";
732                         set_config('database', 'dbupdate_'.DB_UPDATE_VERSION, 'success');
733                 } else
734                         $o .= sprintf(t("Executing of database structure update %s failed with error: %s"),
735                                         DB_UPDATE_VERSION, $retval)."<br />";
736                 if ($a->argv[2] === 'check')
737                         return $o;
738         }
739
740         if ($a->argc > 2 && intval($a->argv[2])) {
741                 require_once('update.php');
742                 $func = 'update_' . intval($a->argv[2]);
743                 if(function_exists($func)) {
744                         $retval = $func();
745                         if($retval === UPDATE_FAILED) {
746                                 $o .= sprintf(t("Executing %s failed with error: %s"), $func, $retval);
747                         }
748                         elseif($retval === UPDATE_SUCCESS) {
749                                 $o .= sprintf(t('Update %s was successfully applied.', $func));
750                                 set_config('database',$func, 'success');
751                         }
752                         else
753                                 $o .= sprintf(t('Update %s did not return a status. Unknown if it succeeded.'), $func);
754                 } else {
755                         $o .= sprintf(t('There was no additional update function %s that needed to be called.'), $func)."<br />";
756                         set_config('database',$func, 'success');
757                 }
758                 return $o;
759         }
760
761         $failed = array();
762         $r = q("select k, v from config where `cat` = 'database' ");
763         if(count($r)) {
764                 foreach($r as $rr) {
765                         $upd = intval(substr($rr['k'],7));
766                         if($upd < 1139 || $rr['v'] === 'success')
767                                 continue;
768                         $failed[] = $upd;
769                 }
770         }
771         if(! count($failed)) {
772                 $o = replace_macros(get_markup_template('structure_check.tpl'),array(
773                         '$base' => $a->get_baseurl(true),
774                         '$banner' => t('No failed updates.'),
775                         '$check' => t('Check database structure'),
776                 ));
777         } else {
778                 $o = replace_macros(get_markup_template('failed_updates.tpl'),array(
779                         '$base' => $a->get_baseurl(true),
780                         '$banner' => t('Failed Updates'),
781                         '$desc' => t('This does not include updates prior to 1139, which did not return a status.'),
782                         '$mark' => t('Mark success (if update was manually applied)'),
783                         '$apply' => t('Attempt to execute this update step automatically'),
784                         '$failed' => $failed
785                 ));
786         }
787
788         return $o;
789
790 }
791
792 /**
793  * Users admin page
794  *
795  * @param App $a
796  */
797 function admin_page_users_post(&$a){
798         $pending = ( x($_POST, 'pending') ? $_POST['pending'] : Array() );
799         $users = ( x($_POST, 'user') ? $_POST['user'] : Array() );
800         $nu_name = ( x($_POST, 'new_user_name') ? $_POST['new_user_name'] : '');
801         $nu_nickname = ( x($_POST, 'new_user_nickname') ? $_POST['new_user_nickname'] : '');
802         $nu_email = ( x($_POST, 'new_user_email') ? $_POST['new_user_email'] : '');
803
804         check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
805
806         if (!($nu_name==="") && !($nu_email==="") && !($nu_nickname==="")) {
807                 require_once('include/user.php');
808
809                 $result = create_user( array('username'=>$nu_name, 'email'=>$nu_email, 'nickname'=>$nu_nickname, 'verified'=>1)  );
810                 if(! $result['success']) {
811                         notice($result['message']);
812                         return;
813                 }
814                 $nu = $result['user'];
815                 $preamble = deindent(t('
816                         Dear %1$s,
817                                 the administrator of %2$s has set up an account for you.'));
818                 $body = deindent(t('
819                         The login details are as follows:
820
821                         Site Location:  %1$s
822                         Login Name:             %2$s
823                         Password:               %3$s
824
825                         You may change your password from your account "Settings" page after logging
826                         in.
827
828                         Please take a few moments to review the other account settings on that page.
829
830                         You may also wish to add some basic information to your default profile
831                         (on the "Profiles" page) so that other people can easily find you.
832
833                         We recommend setting your full name, adding a profile photo,
834                         adding some profile "keywords" (very useful in making new friends) - and
835                         perhaps what country you live in; if you do not wish to be more specific
836                         than that.
837
838                         We fully respect your right to privacy, and none of these items are necessary.
839                         If you are new and do not know anybody here, they may help
840                         you to make some new and interesting friends.
841
842                         Thank you and welcome to %4$s.'));
843
844                 $preamble = sprintf($preamble, $nu['username'], $a->config['sitename']);
845                 $body = sprintf($body, $a->get_baseurl(), $nu['email'], $result['password'], $a->config['sitename']);
846
847                 notification(array(
848                         'type' => "SYSTEM_EMAIL",
849                         'to_email' => $nu['email'],
850                         'subject'=> sprintf( t('Registration details for %s'), $a->config['sitename']),
851                         'preamble'=> $preamble,
852                         'body' => $body));
853
854         }
855
856         if (x($_POST,'page_users_block')){
857                 foreach($users as $uid){
858                         q("UPDATE `user` SET `blocked`=1-`blocked` WHERE `uid`=%s",
859                                 intval( $uid )
860                         );
861                 }
862                 notice( sprintf( tt("%s user blocked/unblocked", "%s users blocked/unblocked", count($users)), count($users)) );
863         }
864         if (x($_POST,'page_users_delete')){
865                 require_once("include/Contact.php");
866                 foreach($users as $uid){
867                         user_remove($uid);
868                 }
869                 notice( sprintf( tt("%s user deleted", "%s users deleted", count($users)), count($users)) );
870         }
871
872         if (x($_POST,'page_users_approve')){
873                 require_once("mod/regmod.php");
874                 foreach($pending as $hash){
875                         user_allow($hash);
876                 }
877         }
878         if (x($_POST,'page_users_deny')){
879                 require_once("mod/regmod.php");
880                 foreach($pending as $hash){
881                         user_deny($hash);
882                 }
883         }
884         goaway($a->get_baseurl(true) . '/admin/users' );
885         return; // NOTREACHED
886 }
887
888 /**
889  * @param App $a
890  * @return string
891  */
892 function admin_page_users(&$a){
893         if ($a->argc>2) {
894                 $uid = $a->argv[3];
895                 $user = q("SELECT username, blocked FROM `user` WHERE `uid`=%d", intval($uid));
896                 if (count($user)==0){
897                         notice( 'User not found' . EOL);
898                         goaway($a->get_baseurl(true) . '/admin/users' );
899                         return ''; // NOTREACHED
900                 }
901                 switch($a->argv[2]){
902                         case "delete":{
903                                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
904                                 // delete user
905                                 require_once("include/Contact.php");
906                                 user_remove($uid);
907
908                                 notice( sprintf(t("User '%s' deleted"), $user[0]['username']) . EOL);
909                         }; break;
910                         case "block":{
911                                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
912                                 q("UPDATE `user` SET `blocked`=%d WHERE `uid`=%s",
913                                         intval( 1-$user[0]['blocked'] ),
914                                         intval( $uid )
915                                 );
916                                 notice( sprintf( ($user[0]['blocked']?t("User '%s' unblocked"):t("User '%s' blocked")) , $user[0]['username']) . EOL);
917                         }; break;
918                 }
919                 goaway($a->get_baseurl(true) . '/admin/users' );
920                 return ''; // NOTREACHED
921
922         }
923
924         /* get pending */
925         $pending = q("SELECT `register`.*, `contact`.`name`, `user`.`email`
926                                  FROM `register`
927                                  LEFT JOIN `contact` ON `register`.`uid` = `contact`.`uid`
928                                  LEFT JOIN `user` ON `register`.`uid` = `user`.`uid`;");
929
930
931         /* get users */
932
933         $total = q("SELECT count(*) as total FROM `user` where 1");
934         if(count($total)) {
935                 $a->set_pager_total($total[0]['total']);
936                 $a->set_pager_itemspage(100);
937         }
938
939
940         $users = q("SELECT `user` . * , `contact`.`name` , `contact`.`url` , `contact`.`micro`, `lastitem`.`lastitem_date`, `user`.`account_expired`
941                                 FROM
942                                         (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid`
943                                         FROM `item`
944                                         WHERE `item`.`type` = 'wall'
945                                         GROUP BY `item`.`uid`) AS `lastitem`
946                                                  RIGHT OUTER JOIN `user` ON `user`.`uid` = `lastitem`.`uid`,
947                                            `contact`
948                                 WHERE
949                                            `user`.`uid` = `contact`.`uid`
950                                                 AND `user`.`verified` =1
951                                         AND `contact`.`self` =1
952                                 ORDER BY `contact`.`name` LIMIT %d, %d
953                                 ",
954                                 intval($a->pager['start']),
955                                 intval($a->pager['itemspage'])
956                                 );
957
958         function _setup_users($e){
959                 $a = get_app();
960
961                 $adminlist = explode(",", str_replace(" ", "", $a->config['admin_email']));
962
963                 $accounts = Array(
964                         t('Normal Account'),
965                         t('Soapbox Account'),
966                         t('Community/Celebrity Account'),
967                                                 t('Automatic Friend Account')
968                 );
969                 $e['page-flags'] = $accounts[$e['page-flags']];
970                 $e['register_date'] = relative_date($e['register_date']);
971                 $e['login_date'] = relative_date($e['login_date']);
972                 $e['lastitem_date'] = relative_date($e['lastitem_date']);
973                 //$e['is_admin'] = ($e['email'] === $a->config['admin_email']);
974                 $e['is_admin'] = in_array($e['email'], $adminlist);
975                 $e['deleted'] = ($e['account_removed']?relative_date($e['account_expires_on']):False);
976                 return $e;
977         }
978         $users = array_map("_setup_users", $users);
979
980
981         // Get rid of dashes in key names, Smarty3 can't handle them
982         // and extracting deleted users
983
984         $tmp_users = Array();
985         $deleted = Array();
986
987         while(count($users)) {
988                 $new_user = Array();
989                 foreach( array_pop($users) as $k => $v) {
990                         $k = str_replace('-','_',$k);
991                         $new_user[$k] = $v;
992                 }
993                 if($new_user['deleted']) {
994                         array_push($deleted, $new_user);
995                 }
996                 else {
997                         array_push($tmp_users, $new_user);
998                 }
999         }
1000         //Reversing the two array, and moving $tmp_users to $users
1001         array_reverse($deleted);
1002         while(count($tmp_users)) {
1003                 array_push($users, array_pop($tmp_users));
1004         }
1005
1006         $t = get_markup_template("admin_users.tpl");
1007         $o = replace_macros($t, array(
1008                 // strings //
1009                 '$title' => t('Administration'),
1010                 '$page' => t('Users'),
1011                 '$submit' => t('Add User'),
1012                 '$select_all' => t('select all'),
1013                 '$h_pending' => t('User registrations waiting for confirm'),
1014                 '$h_deleted' => t('User waiting for permanent deletion'),
1015                 '$th_pending' => array( t('Request date'), t('Name'), t('Email') ),
1016                 '$no_pending' =>  t('No registrations.'),
1017                 '$approve' => t('Approve'),
1018                 '$deny' => t('Deny'),
1019                 '$delete' => t('Delete'),
1020                 '$block' => t('Block'),
1021                 '$unblock' => t('Unblock'),
1022                 '$siteadmin' => t('Site admin'),
1023                 '$accountexpired' => t('Account expired'),
1024
1025                 '$h_users' => t('Users'),
1026                 '$h_newuser' => t('New User'),
1027                 '$th_deleted' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'), t('Deleted since') ),
1028                 '$th_users' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'),  t('Account') ),
1029
1030                 '$confirm_delete_multi' => t('Selected users will be deleted!\n\nEverything these users had posted on this site will be permanently deleted!\n\nAre you sure?'),
1031                 '$confirm_delete' => t('The user {0} will be deleted!\n\nEverything this user has posted on this site will be permanently deleted!\n\nAre you sure?'),
1032
1033                 '$form_security_token' => get_form_security_token("admin_users"),
1034
1035                 // values //
1036                 '$baseurl' => $a->get_baseurl(true),
1037
1038                 '$pending' => $pending,
1039                 'deleted' => $deleted,
1040                 '$users' => $users,
1041                 '$newusername'  => array('new_user_name', t("Name"), '', t("Name of the new user.")),
1042                 '$newusernickname'  => array('new_user_nickname', t("Nickname"), '', t("Nickname of the new user.")),
1043                 '$newuseremail'  => array('new_user_email', t("Email"), '', t("Email address of the new user."), '', '', 'email'),
1044         ));
1045         $o .= paginate($a);
1046         return $o;
1047 }
1048
1049
1050 /**
1051  * Plugins admin page
1052  *
1053  * @param App $a
1054  * @return string
1055  */
1056 function admin_page_plugins(&$a){
1057
1058         /**
1059          * Single plugin
1060          */
1061         if ($a->argc == 3){
1062                 $plugin = $a->argv[2];
1063                 if (!is_file("addon/$plugin/$plugin.php")){
1064                         notice( t("Item not found.") );
1065                         return '';
1066                 }
1067
1068                 if (x($_GET,"a") && $_GET['a']=="t"){
1069                         check_form_security_token_redirectOnErr('/admin/plugins', 'admin_themes', 't');
1070
1071                         // Toggle plugin status
1072                         $idx = array_search($plugin, $a->plugins);
1073                         if ($idx !== false){
1074                                 unset($a->plugins[$idx]);
1075                                 uninstall_plugin($plugin);
1076                                 info( sprintf( t("Plugin %s disabled."), $plugin ) );
1077                         } else {
1078                                 $a->plugins[] = $plugin;
1079                                 install_plugin($plugin);
1080                                 info( sprintf( t("Plugin %s enabled."), $plugin ) );
1081                         }
1082                         set_config("system","addon", implode(", ",$a->plugins));
1083                         goaway($a->get_baseurl(true) . '/admin/plugins' );
1084                         return ''; // NOTREACHED
1085                 }
1086                 // display plugin details
1087                 require_once('library/markdown.php');
1088
1089                 if (in_array($plugin, $a->plugins)){
1090                         $status="on"; $action= t("Disable");
1091                 } else {
1092                         $status="off"; $action= t("Enable");
1093                 }
1094
1095                 $readme=Null;
1096                 if (is_file("addon/$plugin/README.md")){
1097                         $readme = file_get_contents("addon/$plugin/README.md");
1098                         $readme = Markdown($readme);
1099                 } else if (is_file("addon/$plugin/README")){
1100                         $readme = "<pre>". file_get_contents("addon/$plugin/README") ."</pre>";
1101                 }
1102
1103                 $admin_form="";
1104                 if (is_array($a->plugins_admin) && in_array($plugin, $a->plugins_admin)){
1105                         @require_once("addon/$plugin/$plugin.php");
1106                         $func = $plugin.'_plugin_admin';
1107                         $func($a, $admin_form);
1108                 }
1109
1110                 $t = get_markup_template("admin_plugins_details.tpl");
1111
1112                 return replace_macros($t, array(
1113                         '$title' => t('Administration'),
1114                         '$page' => t('Plugins'),
1115                         '$toggle' => t('Toggle'),
1116                         '$settings' => t('Settings'),
1117                         '$baseurl' => $a->get_baseurl(true),
1118
1119                         '$plugin' => $plugin,
1120                         '$status' => $status,
1121                         '$action' => $action,
1122                         '$info' => get_plugin_info($plugin),
1123                         '$str_author' => t('Author: '),
1124                         '$str_maintainer' => t('Maintainer: '),
1125
1126                         '$admin_form' => $admin_form,
1127                         '$function' => 'plugins',
1128                         '$screenshot' => '',
1129                         '$readme' => $readme,
1130
1131                         '$form_security_token' => get_form_security_token("admin_themes"),
1132                 ));
1133         }
1134
1135
1136
1137         /**
1138          * List plugins
1139          */
1140
1141         $plugins = array();
1142         $files = glob("addon/*/"); /* */
1143         if($files) {
1144                 foreach($files as $file) {
1145                         if (is_dir($file)){
1146                                 list($tmp, $id)=array_map("trim", explode("/",$file));
1147                                 $info = get_plugin_info($id);
1148                                 $show_plugin = true;
1149
1150                                 // If the addon is unsupported, then only show it, when it is enabled
1151                                 if ((strtolower($info["status"]) == "unsupported") AND !in_array($id,  $a->plugins))
1152                                         $show_plugin = false;
1153
1154                                 // Override the above szenario, when the admin really wants to see outdated stuff
1155                                 if (get_config("system", "show_unsupported_addons"))
1156                                         $show_plugin = true;
1157
1158                                 if ($show_plugin)
1159                                         $plugins[] = array($id, (in_array($id,  $a->plugins)?"on":"off") , $info);
1160                         }
1161                 }
1162         }
1163
1164         $t = get_markup_template("admin_plugins.tpl");
1165         return replace_macros($t, array(
1166                 '$title' => t('Administration'),
1167                 '$page' => t('Plugins'),
1168                 '$submit' => t('Save Settings'),
1169                 '$baseurl' => $a->get_baseurl(true),
1170                 '$function' => 'plugins',
1171                 '$plugins' => $plugins,
1172                 '$form_security_token' => get_form_security_token("admin_themes"),
1173         ));
1174 }
1175
1176 /**
1177  * @param array $themes
1178  * @param string $th
1179  * @param int $result
1180  */
1181 function toggle_theme(&$themes,$th,&$result) {
1182         for($x = 0; $x < count($themes); $x ++) {
1183                 if($themes[$x]['name'] === $th) {
1184                         if($themes[$x]['allowed']) {
1185                                 $themes[$x]['allowed'] = 0;
1186                                 $result = 0;
1187                         }
1188                         else {
1189                                 $themes[$x]['allowed'] = 1;
1190                                 $result = 1;
1191                         }
1192                 }
1193         }
1194 }
1195
1196 /**
1197  * @param array $themes
1198  * @param string $th
1199  * @return int
1200  */
1201 function theme_status($themes,$th) {
1202         for($x = 0; $x < count($themes); $x ++) {
1203                 if($themes[$x]['name'] === $th) {
1204                         if($themes[$x]['allowed']) {
1205                                 return 1;
1206                         }
1207                         else {
1208                                 return 0;
1209                         }
1210                 }
1211         }
1212         return 0;
1213 }
1214
1215
1216 /**
1217  * @param array $themes
1218  * @return string
1219  */
1220 function rebuild_theme_table($themes) {
1221         $o = '';
1222         if(count($themes)) {
1223                 foreach($themes as $th) {
1224                         if($th['allowed']) {
1225                                 if(strlen($o))
1226                                         $o .= ',';
1227                                 $o .= $th['name'];
1228                         }
1229                 }
1230         }
1231         return $o;
1232 }
1233
1234
1235 /**
1236  * Themes admin page
1237  *
1238  * @param App $a
1239  * @return string
1240  */
1241 function admin_page_themes(&$a){
1242
1243         $allowed_themes_str = get_config('system','allowed_themes');
1244         $allowed_themes_raw = explode(',',$allowed_themes_str);
1245         $allowed_themes = array();
1246         if(count($allowed_themes_raw))
1247                 foreach($allowed_themes_raw as $x)
1248                         if(strlen(trim($x)))
1249                                 $allowed_themes[] = trim($x);
1250
1251         $themes = array();
1252         $files = glob('view/theme/*'); /* */
1253         if($files) {
1254                 foreach($files as $file) {
1255                         $f = basename($file);
1256                         $is_experimental = intval(file_exists($file . '/experimental'));
1257                         $is_supported = 1-(intval(file_exists($file . '/unsupported')));
1258                         $is_allowed = intval(in_array($f,$allowed_themes));
1259
1260                         if ($is_allowed OR $is_supported OR get_config("system", "show_unsupported_themes"))
1261                                 $themes[] = array('name' => $f, 'experimental' => $is_experimental, 'supported' => $is_supported, 'allowed' => $is_allowed);
1262                 }
1263         }
1264
1265         if(! count($themes)) {
1266                 notice( t('No themes found.'));
1267                 return '';
1268         }
1269
1270         /**
1271          * Single theme
1272          */
1273
1274         if ($a->argc == 3){
1275                 $theme = $a->argv[2];
1276                 if(! is_dir("view/theme/$theme")){
1277                         notice( t("Item not found.") );
1278                         return '';
1279                 }
1280
1281                 if (x($_GET,"a") && $_GET['a']=="t"){
1282                         check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't');
1283
1284                         // Toggle theme status
1285
1286                         toggle_theme($themes,$theme,$result);
1287                         $s = rebuild_theme_table($themes);
1288                         if($result) {
1289                                 install_theme($theme);
1290                                 info( sprintf('Theme %s enabled.',$theme));
1291                         }
1292                         else {
1293                                 uninstall_theme($theme);
1294                                 info( sprintf('Theme %s disabled.',$theme));
1295                         }
1296
1297                         set_config('system','allowed_themes',$s);
1298                         goaway($a->get_baseurl(true) . '/admin/themes' );
1299                         return ''; // NOTREACHED
1300                 }
1301
1302                 // display theme details
1303                 require_once('library/markdown.php');
1304
1305                 if (theme_status($themes,$theme)) {
1306                         $status="on"; $action= t("Disable");
1307                 } else {
1308                         $status="off"; $action= t("Enable");
1309                 }
1310
1311                 $readme=Null;
1312                 if (is_file("view/theme/$theme/README.md")){
1313                         $readme = file_get_contents("view/theme/$theme/README.md");
1314                         $readme = Markdown($readme);
1315                 } else if (is_file("view/theme/$theme/README")){
1316                         $readme = "<pre>". file_get_contents("view/theme/$theme/README") ."</pre>";
1317                 }
1318
1319                 $admin_form="";
1320                 if (is_file("view/theme/$theme/config.php")){
1321                         require_once("view/theme/$theme/config.php");
1322                         if(function_exists("theme_admin")){
1323                                 $admin_form = theme_admin($a);
1324                         }
1325
1326                 }
1327
1328                 $screenshot = array( get_theme_screenshot($theme), t('Screenshot'));
1329                 if(! stristr($screenshot[0],$theme))
1330                         $screenshot = null;
1331
1332                 $t = get_markup_template("admin_plugins_details.tpl");
1333                 return replace_macros($t, array(
1334                         '$title' => t('Administration'),
1335                         '$page' => t('Themes'),
1336                         '$toggle' => t('Toggle'),
1337                         '$settings' => t('Settings'),
1338                         '$baseurl' => $a->get_baseurl(true),
1339
1340                         '$plugin' => $theme,
1341                         '$status' => $status,
1342                         '$action' => $action,
1343                         '$info' => get_theme_info($theme),
1344                         '$function' => 'themes',
1345                         '$admin_form' => $admin_form,
1346                         '$str_author' => t('Author: '),
1347                         '$str_maintainer' => t('Maintainer: '),
1348                         '$screenshot' => $screenshot,
1349                         '$readme' => $readme,
1350
1351                         '$form_security_token' => get_form_security_token("admin_themes"),
1352                 ));
1353         }
1354
1355         /**
1356          * List themes
1357          */
1358
1359         $xthemes = array();
1360         if($themes) {
1361                 foreach($themes as $th) {
1362                         $xthemes[] = array($th['name'],(($th['allowed']) ? "on" : "off"), get_theme_info($th['name']));
1363                 }
1364         }
1365
1366         $t = get_markup_template("admin_plugins.tpl");
1367         return replace_macros($t, array(
1368                 '$title' => t('Administration'),
1369                 '$page' => t('Themes'),
1370                 '$submit' => t('Save Settings'),
1371                 '$baseurl' => $a->get_baseurl(true),
1372                 '$function' => 'themes',
1373                 '$plugins' => $xthemes,
1374                 '$experimental' => t('[Experimental]'),
1375                 '$unsupported' => t('[Unsupported]'),
1376                 '$form_security_token' => get_form_security_token("admin_themes"),
1377         ));
1378 }
1379
1380
1381 /**
1382  * Logs admin page
1383  *
1384  * @param App $a
1385  */
1386
1387 function admin_page_logs_post(&$a) {
1388         if (x($_POST,"page_logs")) {
1389                 check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
1390
1391                 $logfile                =       ((x($_POST,'logfile'))          ? notags(trim($_POST['logfile']))       : '');
1392                 $debugging              =       ((x($_POST,'debugging'))        ? true                                                          : false);
1393                 $loglevel               =       ((x($_POST,'loglevel'))         ? intval(trim($_POST['loglevel']))      : 0);
1394
1395                 set_config('system','logfile', $logfile);
1396                 set_config('system','debugging',  $debugging);
1397                 set_config('system','loglevel', $loglevel);
1398
1399
1400         }
1401
1402         info( t("Log settings updated.") );
1403         goaway($a->get_baseurl(true) . '/admin/logs' );
1404         return; // NOTREACHED
1405 }
1406
1407 /**
1408  * @param App $a
1409  * @return string
1410  */
1411 function admin_page_logs(&$a){
1412
1413         $log_choices = Array(
1414                 LOGGER_NORMAL => 'Normal',
1415                 LOGGER_TRACE => 'Trace',
1416                 LOGGER_DEBUG => 'Debug',
1417                 LOGGER_DATA => 'Data',
1418                 LOGGER_ALL => 'All'
1419         );
1420
1421         $t = get_markup_template("admin_logs.tpl");
1422
1423         $f = get_config('system','logfile');
1424
1425         $data = '';
1426
1427         if(!file_exists($f)) {
1428                 $data = t("Error trying to open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f exist and is
1429 readable.");
1430         }
1431         else {
1432                 $fp = fopen($f, 'r');
1433                 if(!$fp) {
1434                         $data = t("Couldn't open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f is readable.");
1435                 }
1436                 else {
1437                         $fstat = fstat($fp);
1438                         $size = $fstat['size'];
1439                         if($size != 0)
1440                         {
1441                                 if($size > 5000000 || $size < 0)
1442                                         $size = 5000000;
1443                                 $seek = fseek($fp,0-$size,SEEK_END);
1444                                 if($seek === 0) {
1445                                         $data = escape_tags(fread($fp,$size));
1446                                         while(! feof($fp))
1447                                                 $data .= escape_tags(fread($fp,4096));
1448                                 }
1449                         }
1450                         fclose($fp);
1451                 }
1452         }
1453
1454         return replace_macros($t, array(
1455                 '$title' => t('Administration'),
1456                 '$page' => t('Logs'),
1457                 '$submit' => t('Save Settings'),
1458                 '$clear' => t('Clear'),
1459                 '$data' => $data,
1460                 '$baseurl' => $a->get_baseurl(true),
1461                 '$logname' =>  get_config('system','logfile'),
1462
1463                                                                         // name, label, value, help string, extra data...
1464                 '$debugging'            => array('debugging', t("Enable Debugging"),get_config('system','debugging'), ""),
1465                 '$logfile'                      => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Friendica top-level directory.")),
1466                 '$loglevel'             => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices),
1467
1468                 '$form_security_token' => get_form_security_token("admin_logs"),
1469         ));
1470 }
1471
1472 /**
1473  * @param App $a
1474  */
1475 function admin_page_remoteupdate_post(&$a) {
1476         // this function should be called via ajax post
1477         if(!is_site_admin()) {
1478                 return;
1479         }
1480
1481
1482         if (x($_POST,'remotefile') && $_POST['remotefile']!=""){
1483                 $remotefile = $_POST['remotefile'];
1484                 $ftpdata = (x($_POST['ftphost'])?$_POST:false);
1485                 doUpdate($remotefile, $ftpdata);
1486         } else {
1487                 echo "No remote file to download. Abort!";
1488         }
1489
1490         killme();
1491 }
1492
1493 /**
1494  * @param App $a
1495  * @return string
1496  */
1497 function admin_page_remoteupdate(&$a) {
1498         if(!is_site_admin()) {
1499                 return login(false);
1500         }
1501
1502         $canwrite = canWeWrite();
1503         $canftp = function_exists('ftp_connect');
1504
1505         $needupdate = true;
1506         $u = checkUpdate();
1507         if (!is_array($u)){
1508                 $needupdate = false;
1509                 $u = array('','','');
1510         }
1511
1512         $tpl = get_markup_template("admin_remoteupdate.tpl");
1513         return replace_macros($tpl, array(
1514                 '$baseurl' => $a->get_baseurl(true),
1515                 '$submit' => t("Update now"),
1516                 '$close' => t("Close"),
1517                 '$localversion' => FRIENDICA_VERSION,
1518                 '$remoteversion' => $u[1],
1519                 '$needupdate' => $needupdate,
1520                 '$canwrite' => $canwrite,
1521                 '$canftp'       => $canftp,
1522                 '$ftphost'      => array('ftphost', t("FTP Host"), '',''),
1523                 '$ftppath'      => array('ftppath', t("FTP Path"), '/',''),
1524                 '$ftpuser'      => array('ftpuser', t("FTP User"), '',''),
1525                 '$ftppwd'       => array('ftppwd', t("FTP Password"), '',''),
1526                 '$remotefile'=>array('remotefile','', $u['2'],''),
1527         ));
1528
1529 }