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