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