]> git.mxchange.org Git - friendica.git/blob - mod/admin.php
Merge pull request #970 from annando/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         $lockpath               =       ((x($_POST,'lockpath'))                 ? notags(trim($_POST['lockpath']))              : '');
359         $temppath               =       ((x($_POST,'temppath'))                 ? notags(trim($_POST['temppath']))              : '');
360         $basepath               =       ((x($_POST,'basepath'))                 ? notags(trim($_POST['basepath']))              : '');
361         $singleuser             =       ((x($_POST,'singleuser'))               ? notags(trim($_POST['singleuser']))            : '');
362         if($ssl_policy != intval(get_config('system','ssl_policy'))) {
363                 if($ssl_policy == SSL_POLICY_FULL) {
364                         q("update `contact` set 
365                                 `url`     = replace(`url`    , 'http:' , 'https:'),
366                                 `photo`   = replace(`photo`  , 'http:' , 'https:'),
367                                 `thumb`   = replace(`thumb`  , 'http:' , 'https:'),
368                                 `micro`   = replace(`micro`  , 'http:' , 'https:'),
369                                 `request` = replace(`request`, 'http:' , 'https:'),
370                                 `notify`  = replace(`notify` , 'http:' , 'https:'),
371                                 `poll`    = replace(`poll`   , 'http:' , 'https:'),
372                                 `confirm` = replace(`confirm`, 'http:' , 'https:'),
373                                 `poco`    = replace(`poco`   , 'http:' , 'https:')
374                                 where `self` = 1"
375                         );
376                         q("update `profile` set 
377                                 `photo`   = replace(`photo`  , 'http:' , 'https:'),
378                                 `thumb`   = replace(`thumb`  , 'http:' , 'https:')
379                                 where 1 "
380                         );
381                 }
382                 elseif($ssl_policy == SSL_POLICY_SELFSIGN) {
383                         q("update `contact` set 
384                                 `url`     = replace(`url`    , 'https:' , 'http:'),
385                                 `photo`   = replace(`photo`  , 'https:' , 'http:'),
386                                 `thumb`   = replace(`thumb`  , 'https:' , 'http:'),
387                                 `micro`   = replace(`micro`  , 'https:' , 'http:'),
388                                 `request` = replace(`request`, 'https:' , 'http:'),
389                                 `notify`  = replace(`notify` , 'https:' , 'http:'),
390                                 `poll`    = replace(`poll`   , 'https:' , 'http:'),
391                                 `confirm` = replace(`confirm`, 'https:' , 'http:'),
392                                 `poco`    = replace(`poco`   , 'https:' , 'http:')
393                                 where `self` = 1"
394                         );
395                         q("update `profile` set 
396                                 `photo`   = replace(`photo`  , 'https:' , 'http:'),
397                                 `thumb`   = replace(`thumb`  , 'https:' , 'http:')
398                                 where 1 "
399                         );
400                 }
401         }
402         set_config('system','ssl_policy',$ssl_policy);
403         set_config('system','delivery_interval',$delivery_interval);
404         set_config('system','poll_interval',$poll_interval);
405         set_config('system','maxloadavg',$maxloadavg);
406         set_config('config','sitename',$sitename);
407         set_config('system','suppress_language',$suppress_language);
408         if ($banner==""){
409                 // don't know why, but del_config doesn't work...
410                 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
411                         dbesc("system"),
412                         dbesc("banner")
413                 );
414         } else {
415                 set_config('system','banner', $banner);
416         }
417         if ($info=="") {
418             del_config('config','info');
419         } else {
420             set_config('config','info',$info);
421         }
422         set_config('system','language', $language);
423         set_config('system','theme', $theme);
424         if ( $theme_mobile === '---' ) {
425                 del_config('system','mobile-theme');
426         } else {
427                 set_config('system','mobile-theme', $theme_mobile);
428         }
429         if ( $singleuser === '---' ) {
430             del_config('system','singleuser');
431         } else {
432             set_config('system','singleuser', $singleuser);
433         }
434         set_config('system','maximagesize', $maximagesize);
435         set_config('system','max_image_length', $maximagelength);
436         set_config('system','jpeg_quality', $jpegimagequality);
437
438         set_config('config','register_policy', $register_policy);
439         set_config('system','max_daily_registrations', $daily_registrations);
440         set_config('system','account_abandon_days', $abandon_days);
441         set_config('config','register_text', $register_text);
442         set_config('system','allowed_sites', $allowed_sites);
443         set_config('system','allowed_email', $allowed_email);
444         set_config('system','block_public', $block_public);
445         set_config('system','publish_all', $force_publish);
446         if ($global_directory==""){
447                 // don't know why, but del_config doesn't work...
448                 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
449                         dbesc("system"),
450                         dbesc("directory_submit_url")
451                 );
452         } else {
453                 set_config('system','directory_submit_url', $global_directory);
454         }
455         set_config('system','thread_allow', $thread_allow);
456         set_config('system','newuser_private', $newuser_private);
457         set_config('system','enotify_no_content', $enotify_no_content);
458         set_config('system','disable_embedded', $disable_embedded);
459         set_config('system','allow_users_remote_self', $allow_users_remote_self);
460
461         set_config('system','block_extended_register', $no_multi_reg);
462         set_config('system','no_openid', $no_openid);
463         set_config('system','no_regfullname', $no_regfullname);
464         set_config('system','no_community_page', $no_community_page);
465         set_config('system','no_utf', $no_utf);
466         set_config('system','verifyssl', $verifyssl);
467         set_config('system','proxyuser', $proxyuser);
468         set_config('system','proxy', $proxy);
469         set_config('system','curl_timeout', $timeout);
470         set_config('system','dfrn_only', $dfrn_only);
471         set_config('system','ostatus_disabled', $ostatus_disabled);
472         set_config('system','ostatus_poll_interval', $ostatus_poll_interval);
473         set_config('system','diaspora_enabled', $diaspora_enabled);
474         set_config('config','private_addons', $private_addons);
475
476         set_config('system','old_share', $old_share);
477         set_config('system','hide_help', $hide_help);
478         set_config('system','use_fulltext_engine', $use_fulltext_engine);
479         set_config('system','itemcache', $itemcache);
480         set_config('system','itemcache_duration', $itemcache_duration);
481         set_config('system','lockpath', $lockpath);
482         set_config('system','temppath', $temppath);
483         set_config('system','basepath', $basepath);
484
485         info( t('Site settings updated.') . EOL);
486         goaway($a->get_baseurl(true) . '/admin/site' );
487         return; // NOTREACHED
488
489 }
490
491 /**
492  * @param  App $a
493  * @return string
494  */
495 function admin_page_site(&$a) {
496
497         /* Installed langs */
498         $lang_choices = array();
499         $langs = glob('view/*/strings.php');
500
501         if(is_array($langs) && count($langs)) {
502                 if(! in_array('view/en/strings.php',$langs))
503                         $langs[] = 'view/en/';
504                 asort($langs);
505                 foreach($langs as $l) {
506                         $t = explode("/",$l);
507                         $lang_choices[$t[1]] = $t[1];
508                 }
509         }
510
511         /* Installed themes */
512         $theme_choices = array();
513         $theme_choices_mobile = array();
514         $theme_choices_mobile["---"] = t("No special theme for mobile devices");
515         $files = glob('view/theme/*');
516         if($files) {
517                 foreach($files as $file) {
518                         $f = basename($file);
519                         $theme_name = ((file_exists($file . '/experimental')) ?  sprintf("%s - \x28Experimental\x29", $f) : $f);
520             if (file_exists($file . '/mobile')) {
521                 $theme_choices_mobile[$f] = $theme_name;
522             }
523                 else {
524                 $theme_choices[$f] = $theme_name;
525                         }
526                 }
527         }
528
529         /* OStatus conversation poll choices */
530         $ostatus_poll_choices = array(
531                 "-2" => t("Never"),
532                 "-1" => t("At post arrival"),
533                 "0" => t("Frequently"),
534                 "60" => t("Hourly"),
535                 "720" => t("Twice daily"),
536                 "1440" => t("Daily")
537             );
538
539         /* get user names to make the install a personal install of X */
540         $user_names = array();
541         $user_names['---'] = t('Multi user instance');
542         $users = q("SELECT username, nickname FROM `user`");
543         foreach ($users as $user) {
544             $user_names[$user['nickname']] = $user['username'];
545         }
546
547         /* Banner */
548         $banner = get_config('system','banner');
549         if($banner == false) 
550                 $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>';
551         $banner = htmlspecialchars($banner);
552         $info = get_config('config','info');
553         $info = htmlspecialchars($info);
554
555         //echo "<pre>"; var_dump($lang_choices); die("</pre>");
556
557         /* Register policy */
558         $register_choices = Array(
559                 REGISTER_CLOSED => t("Closed"),
560                 REGISTER_APPROVE => t("Requires approval"),
561                 REGISTER_OPEN => t("Open")
562         ); 
563
564         $ssl_choices = array(
565                 SSL_POLICY_NONE => t("No SSL policy, links will track page SSL state"),
566                 SSL_POLICY_FULL => t("Force all links to use SSL"),
567                 SSL_POLICY_SELFSIGN => t("Self-signed certificate, use SSL for local links only (discouraged)")
568         );
569
570         $t = get_markup_template("admin_site.tpl");
571         return replace_macros($t, array(
572                 '$title' => t('Administration'),
573                 '$page' => t('Site'),
574                 '$submit' => t('Save Settings'),
575                 '$registration' => t('Registration'),
576                 '$upload' => t('File upload'),
577                 '$corporate' => t('Policies'),
578                 '$advanced' => t('Advanced'),
579                 '$performance' => t('Performance'),
580                 '$relocate'=> t('Relocate - WARNING: advanced function. Could make this server unreachable.'),
581                 '$baseurl' => $a->get_baseurl(true),
582                 // name, label, value, help string, extra data...
583                 '$sitename'             => array('sitename', t("Site name"), htmlentities($a->config['sitename'], ENT_QUOTES), 'UTF-8'),
584                 '$banner'               => array('banner', t("Banner/Logo"), $banner, ""),
585                 '$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.')),
586                 '$language'             => array('language', t("System language"), get_config('system','language'), "", $lang_choices),
587                 '$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),
588                 '$theme_mobile'         => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile-theme'), t("Theme for mobile devices"), $theme_choices_mobile),
589                 '$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),
590                 '$old_share'            => array('old_share', t("Old style 'Share'"), get_config('system','old_share'), t("Deactivates the bbcode element 'share' for repeating items.")),
591                 '$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.")),
592                 '$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),
593                 '$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.")),
594                 '$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.")),
595                 '$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.")),
596
597                 '$register_policy'      => array('register_policy', t("Register policy"), $a->config['register_policy'], "", $register_choices),
598                 '$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.")),
599                 '$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.")),
600                 '$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.')),
601                 '$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")),
602                 '$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")),
603                 '$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.")),
604                 '$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.")),
605                 '$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.")),
606                 '$thread_allow'         => array('thread_allow', t("Allow threaded items"), get_config('system','thread_allow'), t("Allow infinite level threading for items on this site.")),
607                 '$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.")),
608                 '$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.")),
609                 '$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.")),
610                 '$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.")),
611                 '$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.')),
612                 '$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.")),
613                 '$no_openid'            => array('no_openid', t("OpenID support"), !get_config('system','no_openid'), t("OpenID support for registration and logins.")),
614                 '$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")),
615                 '$no_utf'               => array('no_utf', t("UTF-8 Regular expressions"), !get_config('system','no_utf'), t("Use PHP UTF8 regular expressions")),
616                 '$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.")),
617                 '$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.")),     
618                 '$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),
619                 '$diaspora_enabled'     => array('diaspora_enabled', t("Enable Diaspora support"), get_config('system','diaspora_enabled'), t("Provide built-in Diaspora network compatibility.")),     
620                 '$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.")),
621                 '$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.")),
622                 '$proxyuser'            => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""),
623                 '$proxy'                => array('proxy', t("Proxy URL"), get_config('system','proxy'), ""),
624                 '$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).")),
625                 '$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.")),
626                 '$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.")),
627                 '$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.")),
628
629                 '$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.")),
630                 '$suppress_language'    => array('suppress_language', t("Suppress Language"), get_config('system','suppress_language'), t("Suppress language information in meta information about a posting.")),
631                 '$itemcache'            => array('itemcache', t("Path to item cache"), get_config('system','itemcache'), "The item caches buffers generated bbcode and external images."),
632                 '$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).")),
633                 '$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."),
634                 '$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."),
635                 '$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."),
636                 
637                 '$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."),
638                 
639         '$form_security_token' => get_form_security_token("admin_site"),
640
641         ));
642
643 }
644
645
646 function admin_page_dbsync(&$a) {
647
648         $o = '';
649
650         if($a->argc > 3 && intval($a->argv[3]) && $a->argv[2] === 'mark') {
651                 set_config('database', 'update_' . intval($a->argv[3]), 'success');
652                 $curr = get_config('system','build');
653                 if(intval($curr) == intval($a->argv[3]))
654                         set_config('system','build',intval($curr) + 1);
655                 info( t('Update has been marked successful') . EOL);
656                 goaway($a->get_baseurl(true) . '/admin/dbsync');
657         }
658
659         if($a->argc > 2 && intval($a->argv[2])) {
660                 require_once('update.php');
661                 $func = 'update_' . intval($a->argv[2]);
662                 if(function_exists($func)) {
663                         $retval = $func();
664                         if($retval === UPDATE_FAILED) {
665                                 $o .= sprintf( t('Executing %s failed. Check system logs.'), $func); 
666                         }
667                         elseif($retval === UPDATE_SUCCESS) {
668                                 $o .= sprintf( t('Update %s was successfully applied.', $func));
669                                 set_config('database',$func, 'success');
670                         }
671                         else
672                                 $o .= sprintf( t('Update %s did not return a status. Unknown if it succeeded.'), $func);
673                 }
674                 else
675                         $o .= sprintf( t('Update function %s could not be found.'), $func);
676                 return $o;
677         }
678
679         $failed = array();
680         $r = q("select k, v from config where `cat` = 'database' ");
681         if(count($r)) {
682                 foreach($r as $rr) {
683                         $upd = intval(substr($rr['k'],7));
684                         if($upd < 1139 || $rr['v'] === 'success')
685                                 continue;
686                         $failed[] = $upd;
687                 }
688         }
689         if(! count($failed))
690                 return '<h3>' . t('No failed updates.') . '</h3>';
691
692         $o = replace_macros(get_markup_template('failed_updates.tpl'),array(
693                 '$base' => $a->get_baseurl(true),
694                 '$banner' => t('Failed Updates'),
695                 '$desc' => t('This does not include updates prior to 1139, which did not return a status.'),
696                 '$mark' => t('Mark success (if update was manually applied)'),
697                 '$apply' => t('Attempt to execute this update step automatically'),
698                 '$failed' => $failed
699         ));
700
701         return $o;
702
703 }
704
705 /**
706  * Users admin page
707  *
708  * @param App $a
709  */
710 function admin_page_users_post(&$a){
711         $pending = ( x($_POST, 'pending') ? $_POST['pending'] : Array() );
712         $users = ( x($_POST, 'user') ? $_POST['user'] : Array() );
713         $nu_name = ( x($_POST, 'new_user_name') ? $_POST['new_user_name'] : ''); 
714   $nu_nickname = ( x($_POST, 'new_user_nickname') ? $_POST['new_user_nickname'] : ''); 
715   $nu_email = ( x($_POST, 'new_user_email') ? $_POST['new_user_email'] : '');
716
717   check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
718
719   if (!($nu_name==="") && !($nu_email==="") && !($nu_nickname==="")) { 
720       require_once('include/user.php'); 
721       require_once('include/email.php'); 
722       $result = create_user( array('username'=>$nu_name, 'email'=>$nu_email, 'nickname'=>$nu_nickname, 'verified'=>1)  ); 
723       if(! $result['success']) { 
724                     notice($result['message']); 
725                     return; 
726       } 
727       $nu = $result['user']; 
728       $email_tpl = get_intltext_template("register_adminadd_eml.tpl"); 
729       $email_tpl = replace_macros($email_tpl, array( 
730                     '$sitename' => $a->config['sitename'], 
731                     '$siteurl' =>  $a->get_baseurl(), 
732                     '$username' => $nu['username'], 
733                     '$email' => $nu['email'], 
734                     '$password' => $result['password'], 
735                     '$uid' => $nu['uid'] )); 
736  
737       $res = mail($nu['email'], email_header_encode( sprintf( t('Registration details for %s'), $a->config['sitename']),'UTF-8'), 
738                     $email_tpl,  
739                     'From: ' . 'Administrator' . '@' . $_SERVER['SERVER_NAME'] . "\n" 
740                     . 'Content-type: text/plain; charset=UTF-8' . "\n" 
741                     . 'Content-transfer-encoding: 8bit' ); 
742       if ($res) { 
743                     info( t('Registration successful. Email send to user').EOL ); 
744       } 
745   }
746
747         if (x($_POST,'page_users_block')){
748                 foreach($users as $uid){
749                         q("UPDATE `user` SET `blocked`=1-`blocked` WHERE `uid`=%s",
750                                 intval( $uid )
751                         );
752                 }
753                 notice( sprintf( tt("%s user blocked/unblocked", "%s users blocked/unblocked", count($users)), count($users)) );
754         }
755         if (x($_POST,'page_users_delete')){
756                 require_once("include/Contact.php");
757                 foreach($users as $uid){
758                         user_remove($uid);
759                 }
760                 notice( sprintf( tt("%s user deleted", "%s users deleted", count($users)), count($users)) );
761         }
762
763         if (x($_POST,'page_users_approve')){
764                 require_once("mod/regmod.php");
765                 foreach($pending as $hash){
766                         user_allow($hash);
767                 }
768         }
769         if (x($_POST,'page_users_deny')){
770                 require_once("mod/regmod.php");
771                 foreach($pending as $hash){
772                         user_deny($hash);
773                 }
774         }
775         goaway($a->get_baseurl(true) . '/admin/users' );
776         return; // NOTREACHED
777 }
778
779 /**
780  * @param App $a
781  * @return string
782  */
783 function admin_page_users(&$a){
784         if ($a->argc>2) {
785                 $uid = $a->argv[3];
786                 $user = q("SELECT username, blocked FROM `user` WHERE `uid`=%d", intval($uid));
787                 if (count($user)==0){
788                         notice( 'User not found' . EOL);
789                         goaway($a->get_baseurl(true) . '/admin/users' );
790                         return ''; // NOTREACHED
791                 }
792                 switch($a->argv[2]){
793                         case "delete":{
794                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
795                                 // delete user
796                                 require_once("include/Contact.php");
797                                 user_remove($uid);
798
799                                 notice( sprintf(t("User '%s' deleted"), $user[0]['username']) . EOL);
800                         }; break;
801                         case "block":{
802                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
803                                 q("UPDATE `user` SET `blocked`=%d WHERE `uid`=%s",
804                                         intval( 1-$user[0]['blocked'] ),
805                                         intval( $uid )
806                                 );
807                                 notice( sprintf( ($user[0]['blocked']?t("User '%s' unblocked"):t("User '%s' blocked")) , $user[0]['username']) . EOL);
808                         }; break;
809                 }
810                 goaway($a->get_baseurl(true) . '/admin/users' );
811                 return ''; // NOTREACHED
812
813         }
814
815         /* get pending */
816         $pending = q("SELECT `register`.*, `contact`.`name`, `user`.`email`
817                                  FROM `register`
818                                  LEFT JOIN `contact` ON `register`.`uid` = `contact`.`uid`
819                                  LEFT JOIN `user` ON `register`.`uid` = `user`.`uid`;");
820
821
822         /* get users */
823
824         $total = q("SELECT count(*) as total FROM `user` where 1");
825         if(count($total)) {
826                 $a->set_pager_total($total[0]['total']);
827                 $a->set_pager_itemspage(100);
828         }
829
830
831         $users = q("SELECT `user` . * , `contact`.`name` , `contact`.`url` , `contact`.`micro`, `lastitem`.`lastitem_date`, `user`.`account_expired`
832                                 FROM
833                                         (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid`
834                                         FROM `item`
835                                         WHERE `item`.`type` = 'wall'
836                                         GROUP BY `item`.`uid`) AS `lastitem`
837                                                  RIGHT OUTER JOIN `user` ON `user`.`uid` = `lastitem`.`uid`,
838                                            `contact`
839                                 WHERE
840                                            `user`.`uid` = `contact`.`uid`
841                                                 AND `user`.`verified` =1
842                                         AND `contact`.`self` =1
843                                 ORDER BY `contact`.`name` LIMIT %d, %d
844                                 ",
845                                 intval($a->pager['start']),
846                                 intval($a->pager['itemspage'])
847                                 );
848
849         function _setup_users($e){
850                 $a = get_app();
851
852                 $adminlist = explode(",", str_replace(" ", "", $a->config['admin_email']));
853
854                 $accounts = Array(
855                         t('Normal Account'),
856                         t('Soapbox Account'),
857                         t('Community/Celebrity Account'),
858                         t('Automatic Friend Account')
859                 );
860                 $e['page-flags'] = $accounts[$e['page-flags']];
861                 $e['register_date'] = relative_date($e['register_date']);
862                 $e['login_date'] = relative_date($e['login_date']);
863                 $e['lastitem_date'] = relative_date($e['lastitem_date']);
864                 //$e['is_admin'] = ($e['email'] === $a->config['admin_email']);
865                 $e['is_admin'] = in_array($e['email'], $adminlist);
866                 $e['deleted'] = ($e['account_removed']?relative_date($e['account_expires_on']):False);
867                 return $e;
868         }
869         $users = array_map("_setup_users", $users);
870
871
872         // Get rid of dashes in key names, Smarty3 can't handle them
873         // and extracting deleted users
874
875         $tmp_users = Array();
876         $deleted = Array();
877
878         while(count($users)) {
879                 $new_user = Array();
880                 foreach( array_pop($users) as $k => $v) {
881                         $k = str_replace('-','_',$k);
882                         $new_user[$k] = $v;
883                 }
884                 if($new_user['deleted']) {
885                         array_push($deleted, $new_user);
886                 }
887                 else {
888                         array_push($tmp_users, $new_user);
889                 }
890         }
891         //Reversing the two array, and moving $tmp_users to $users
892         array_reverse($deleted);
893         while(count($tmp_users)) {
894                 array_push($users, array_pop($tmp_users));
895         }
896
897         $t = get_markup_template("admin_users.tpl");
898         $o = replace_macros($t, array(
899                 // strings //
900                 '$title' => t('Administration'),
901                 '$page' => t('Users'),
902                 '$submit' => t('Add User'),
903                 '$select_all' => t('select all'),
904                 '$h_pending' => t('User registrations waiting for confirm'),
905                 '$h_deleted' => t('User waiting for permanent deletion'),
906                 '$th_pending' => array( t('Request date'), t('Name'), t('Email') ),
907                 '$no_pending' =>  t('No registrations.'),
908                 '$approve' => t('Approve'),
909                 '$deny' => t('Deny'),
910                 '$delete' => t('Delete'),
911                 '$block' => t('Block'),
912                 '$unblock' => t('Unblock'),
913         '$siteadmin' => t('Site admin'),
914         '$accountexpired' => t('Account expired'),
915                 
916                 '$h_users' => t('Users'),
917                 '$h_newuser' => t('New User'),
918                 '$th_deleted' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'), t('Deleted since') ),
919                 '$th_users' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'),  t('Account') ),
920
921                 '$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?'),
922                 '$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?'),
923
924         '$form_security_token' => get_form_security_token("admin_users"),
925
926                 // values //
927                 '$baseurl' => $a->get_baseurl(true),
928
929                 '$pending' => $pending,
930                 'deleted' => $deleted,
931                 '$users' => $users,
932                 '$newusername'  => array('new_user_name', t("Name"), '', t("Name of the new user.")), 
933     '$newusernickname'  => array('new_user_nickname', t("Nickname"), '', t("Nickname of the new user.")), 
934     '$newuseremail'  => array('new_user_email', t("Email"), '', t("Email address of the new user.")),
935         ));
936         $o .= paginate($a);
937         return $o;
938 }
939
940
941 /**
942  * Plugins admin page
943  *
944  * @param App $a
945  * @return string
946  */
947 function admin_page_plugins(&$a){
948
949         /**
950          * Single plugin
951          */
952         if ($a->argc == 3){
953                 $plugin = $a->argv[2];
954                 if (!is_file("addon/$plugin/$plugin.php")){
955                         notice( t("Item not found.") );
956                         return '';
957                 }
958
959                 if (x($_GET,"a") && $_GET['a']=="t"){
960                         check_form_security_token_redirectOnErr('/admin/plugins', 'admin_themes', 't');
961
962                         // Toggle plugin status
963                         $idx = array_search($plugin, $a->plugins);
964                         if ($idx !== false){
965                                 unset($a->plugins[$idx]);
966                                 uninstall_plugin($plugin);
967                                 info( sprintf( t("Plugin %s disabled."), $plugin ) );
968                         } else {
969                                 $a->plugins[] = $plugin;
970                                 install_plugin($plugin);
971                                 info( sprintf( t("Plugin %s enabled."), $plugin ) );
972                         }
973                         set_config("system","addon", implode(", ",$a->plugins));
974                         goaway($a->get_baseurl(true) . '/admin/plugins' );
975                         return ''; // NOTREACHED
976                 }
977                 // display plugin details
978                 require_once('library/markdown.php');
979
980                 if (in_array($plugin, $a->plugins)){
981                         $status="on"; $action= t("Disable");
982                 } else {
983                         $status="off"; $action= t("Enable");
984                 }
985
986                 $readme=Null;
987                 if (is_file("addon/$plugin/README.md")){
988                         $readme = file_get_contents("addon/$plugin/README.md");
989                         $readme = Markdown($readme);
990                 } else if (is_file("addon/$plugin/README")){
991                         $readme = "<pre>". file_get_contents("addon/$plugin/README") ."</pre>";
992                 }
993
994                 $admin_form="";
995                 if (is_array($a->plugins_admin) && in_array($plugin, $a->plugins_admin)){
996                         @require_once("addon/$plugin/$plugin.php");
997                         $func = $plugin.'_plugin_admin';
998                         $func($a, $admin_form);
999                 }
1000
1001                 $t = get_markup_template("admin_plugins_details.tpl");
1002
1003                 return replace_macros($t, array(
1004                         '$title' => t('Administration'),
1005                         '$page' => t('Plugins'),
1006                         '$toggle' => t('Toggle'),
1007                         '$settings' => t('Settings'),
1008                         '$baseurl' => $a->get_baseurl(true),
1009
1010                         '$plugin' => $plugin,
1011                         '$status' => $status,
1012                         '$action' => $action,
1013                         '$info' => get_plugin_info($plugin),
1014                         '$str_author' => t('Author: '),
1015                         '$str_maintainer' => t('Maintainer: '),
1016
1017                         '$admin_form' => $admin_form,
1018                         '$function' => 'plugins',
1019                         '$screenshot' => '',
1020                         '$readme' => $readme,
1021
1022                         '$form_security_token' => get_form_security_token("admin_themes"),
1023                 ));
1024         }
1025
1026
1027
1028         /**
1029          * List plugins
1030          */
1031
1032         $plugins = array();
1033         $files = glob("addon/*/"); /* */
1034         if($files) {
1035                 foreach($files as $file) {
1036                         if (is_dir($file)){
1037                                 list($tmp, $id)=array_map("trim", explode("/",$file));
1038                                 $info = get_plugin_info($id);
1039                                 $show_plugin = true;
1040
1041                                 // If the addon is unsupported, then only show it, when it is enabled
1042                                 if ((strtolower($info["status"]) == "unsupported") AND !in_array($id,  $a->plugins))
1043                                         $show_plugin = false;
1044
1045                                 // Override the above szenario, when the admin really wants to see outdated stuff
1046                                 if (get_config("system", "show_unsupported_addons"))
1047                                         $show_plugin = true;
1048
1049                                 if ($show_plugin)
1050                                         $plugins[] = array($id, (in_array($id,  $a->plugins)?"on":"off") , $info);
1051                         }
1052                 }
1053         }
1054
1055         $t = get_markup_template("admin_plugins.tpl");
1056         return replace_macros($t, array(
1057                 '$title' => t('Administration'),
1058                 '$page' => t('Plugins'),
1059                 '$submit' => t('Save Settings'),
1060                 '$baseurl' => $a->get_baseurl(true),
1061                 '$function' => 'plugins',
1062                 '$plugins' => $plugins,
1063         '$form_security_token' => get_form_security_token("admin_themes"),
1064         ));
1065 }
1066
1067 /**
1068  * @param array $themes
1069  * @param string $th
1070  * @param int $result
1071  */
1072 function toggle_theme(&$themes,$th,&$result) {
1073         for($x = 0; $x < count($themes); $x ++) {
1074                 if($themes[$x]['name'] === $th) {
1075                         if($themes[$x]['allowed']) {
1076                                 $themes[$x]['allowed'] = 0;
1077                                 $result = 0;
1078                         }
1079                         else {
1080                                 $themes[$x]['allowed'] = 1;
1081                                 $result = 1;
1082                         }
1083                 }
1084         }
1085 }
1086
1087 /**
1088  * @param array $themes
1089  * @param string $th
1090  * @return int
1091  */
1092 function theme_status($themes,$th) {
1093         for($x = 0; $x < count($themes); $x ++) {
1094                 if($themes[$x]['name'] === $th) {
1095                         if($themes[$x]['allowed']) {
1096                                 return 1;
1097                         }
1098                         else {
1099                                 return 0;
1100                         }
1101                 }
1102         }
1103         return 0;
1104 }
1105
1106
1107 /**
1108  * @param array $themes
1109  * @return string
1110  */
1111 function rebuild_theme_table($themes) {
1112         $o = '';
1113         if(count($themes)) {
1114                 foreach($themes as $th) {
1115                         if($th['allowed']) {
1116                                 if(strlen($o))
1117                                         $o .= ',';
1118                                 $o .= $th['name'];
1119                         }
1120                 }
1121         }
1122         return $o;
1123 }
1124
1125
1126 /**
1127  * Themes admin page
1128  *
1129  * @param App $a
1130  * @return string
1131  */
1132 function admin_page_themes(&$a){
1133
1134         $allowed_themes_str = get_config('system','allowed_themes');
1135         $allowed_themes_raw = explode(',',$allowed_themes_str);
1136         $allowed_themes = array();
1137         if(count($allowed_themes_raw))
1138                 foreach($allowed_themes_raw as $x)
1139                         if(strlen(trim($x)))
1140                                 $allowed_themes[] = trim($x);
1141
1142         $themes = array();
1143         $files = glob('view/theme/*'); /* */
1144         if($files) {
1145                 foreach($files as $file) {
1146                         $f = basename($file);
1147                         $is_experimental = intval(file_exists($file . '/experimental'));
1148                         $is_supported = 1-(intval(file_exists($file . '/unsupported'))); // Is not used yet
1149                         $is_allowed = intval(in_array($f,$allowed_themes));
1150                         $themes[] = array('name' => $f, 'experimental' => $is_experimental, 'supported' => $is_supported, 'allowed' => $is_allowed);
1151                 }
1152         }
1153
1154         if(! count($themes)) {
1155                 notice( t('No themes found.'));
1156                 return '';
1157         }
1158
1159         /**
1160          * Single theme
1161          */
1162
1163         if ($a->argc == 3){
1164                 $theme = $a->argv[2];
1165                 if(! is_dir("view/theme/$theme")){
1166                         notice( t("Item not found.") );
1167                         return '';
1168                 }
1169
1170                 if (x($_GET,"a") && $_GET['a']=="t"){
1171                         check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't');
1172
1173                         // Toggle theme status
1174
1175                         toggle_theme($themes,$theme,$result);
1176                         $s = rebuild_theme_table($themes);
1177                         if($result) {
1178                                 install_theme($theme);
1179                                 info( sprintf('Theme %s enabled.',$theme));
1180                         }
1181                         else {
1182                                 uninstall_theme($theme);
1183                                 info( sprintf('Theme %s disabled.',$theme));
1184                         }
1185
1186                         set_config('system','allowed_themes',$s);
1187                         goaway($a->get_baseurl(true) . '/admin/themes' );
1188                         return ''; // NOTREACHED
1189                 }
1190
1191                 // display theme details
1192                 require_once('library/markdown.php');
1193
1194                 if (theme_status($themes,$theme)) {
1195                         $status="on"; $action= t("Disable");
1196                 } else {
1197                         $status="off"; $action= t("Enable");
1198                 }
1199
1200                 $readme=Null;
1201                 if (is_file("view/theme/$theme/README.md")){
1202                         $readme = file_get_contents("view/theme/$theme/README.md");
1203                         $readme = Markdown($readme);
1204                 } else if (is_file("view/theme/$theme/README")){
1205                         $readme = "<pre>". file_get_contents("view/theme/$theme/README") ."</pre>";
1206                 }
1207
1208                 $admin_form="";
1209                 if (is_file("view/theme/$theme/config.php")){
1210                         require_once("view/theme/$theme/config.php");
1211                         if(function_exists("theme_admin")){
1212                                 $admin_form = theme_admin($a);
1213                         }
1214
1215                 }
1216
1217                 $screenshot = array( get_theme_screenshot($theme), t('Screenshot'));
1218                 if(! stristr($screenshot[0],$theme))
1219                         $screenshot = null;
1220
1221                 $t = get_markup_template("admin_plugins_details.tpl");
1222                 return replace_macros($t, array(
1223                         '$title' => t('Administration'),
1224                         '$page' => t('Themes'),
1225                         '$toggle' => t('Toggle'),
1226                         '$settings' => t('Settings'),
1227                         '$baseurl' => $a->get_baseurl(true),
1228
1229                         '$plugin' => $theme,
1230                         '$status' => $status,
1231                         '$action' => $action,
1232                         '$info' => get_theme_info($theme),
1233                         '$function' => 'themes',
1234                         '$admin_form' => $admin_form,
1235                         '$str_author' => t('Author: '),
1236                         '$str_maintainer' => t('Maintainer: '),
1237                         '$screenshot' => $screenshot,
1238                         '$readme' => $readme,
1239
1240                         '$form_security_token' => get_form_security_token("admin_themes"),
1241                 ));
1242         }
1243
1244         /**
1245          * List themes
1246          */
1247
1248         $xthemes = array();
1249         if($themes) {
1250                 foreach($themes as $th) {
1251                         $xthemes[] = array($th['name'],(($th['allowed']) ? "on" : "off"), get_theme_info($th['name']));
1252                 }
1253         }
1254
1255         $t = get_markup_template("admin_plugins.tpl");
1256         return replace_macros($t, array(
1257                 '$title' => t('Administration'),
1258                 '$page' => t('Themes'),
1259                 '$submit' => t('Save Settings'),
1260                 '$baseurl' => $a->get_baseurl(true),
1261                 '$function' => 'themes',
1262                 '$plugins' => $xthemes,
1263                 '$experimental' => t('[Experimental]'),
1264                 '$unsupported' => t('[Unsupported]'),
1265         '$form_security_token' => get_form_security_token("admin_themes"),
1266         ));
1267 }
1268
1269
1270 /**
1271  * Logs admin page
1272  *
1273  * @param App $a
1274  */
1275  
1276 function admin_page_logs_post(&$a) {
1277         if (x($_POST,"page_logs")) {
1278         check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
1279
1280                 $logfile                =       ((x($_POST,'logfile'))          ? notags(trim($_POST['logfile']))       : '');
1281                 $debugging              =       ((x($_POST,'debugging'))        ? true                                                          : false);
1282                 $loglevel               =       ((x($_POST,'loglevel'))         ? intval(trim($_POST['loglevel']))      : 0);
1283
1284                 set_config('system','logfile', $logfile);
1285                 set_config('system','debugging',  $debugging);
1286                 set_config('system','loglevel', $loglevel);
1287
1288
1289         }
1290
1291         info( t("Log settings updated.") );
1292         goaway($a->get_baseurl(true) . '/admin/logs' );
1293         return; // NOTREACHED
1294 }
1295
1296 /**
1297  * @param App $a
1298  * @return string
1299  */
1300 function admin_page_logs(&$a){
1301
1302         $log_choices = Array(
1303                 LOGGER_NORMAL => 'Normal',
1304                 LOGGER_TRACE => 'Trace',
1305                 LOGGER_DEBUG => 'Debug',
1306                 LOGGER_DATA => 'Data',
1307                 LOGGER_ALL => 'All'
1308         );
1309
1310         $t = get_markup_template("admin_logs.tpl");
1311
1312         $f = get_config('system','logfile');
1313
1314         $data = '';
1315
1316         if(!file_exists($f)) {
1317                 $data = t("Error trying to open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f exist and is 
1318 readable.");
1319         }
1320         else {
1321                 $fp = fopen($f, 'r');
1322                 if(!$fp) {
1323                         $data = t("Couldn't open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f is readable.");
1324                 }
1325                 else {
1326                         $fstat = fstat($fp);
1327                         $size = $fstat['size'];
1328                         if($size != 0)
1329                         {
1330                                 if($size > 5000000 || $size < 0)
1331                                         $size = 5000000;
1332                                 $seek = fseek($fp,0-$size,SEEK_END);
1333                                 if($seek === 0) {
1334                                         $data = escape_tags(fread($fp,$size));
1335                                         while(! feof($fp))
1336                                                 $data .= escape_tags(fread($fp,4096));
1337                                 }
1338                         }
1339                         fclose($fp);
1340                 }
1341         }
1342
1343         return replace_macros($t, array(
1344                 '$title' => t('Administration'),
1345                 '$page' => t('Logs'),
1346                 '$submit' => t('Save Settings'),
1347                 '$clear' => t('Clear'),
1348                 '$data' => $data,
1349                 '$baseurl' => $a->get_baseurl(true),
1350                 '$logname' =>  get_config('system','logfile'),
1351
1352                                                                         // name, label, value, help string, extra data...
1353                 '$debugging'            => array('debugging', t("Enable Debugging"),get_config('system','debugging'), ""),
1354                 '$logfile'                      => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Friendica top-level directory.")),
1355                 '$loglevel'             => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices),
1356
1357         '$form_security_token' => get_form_security_token("admin_logs"),
1358         ));
1359 }
1360
1361 /**
1362  * @param App $a
1363  */
1364 function admin_page_remoteupdate_post(&$a) {
1365         // this function should be called via ajax post
1366         if(!is_site_admin()) {
1367                 return;
1368         }
1369
1370
1371         if (x($_POST,'remotefile') && $_POST['remotefile']!=""){
1372                 $remotefile = $_POST['remotefile'];
1373                 $ftpdata = (x($_POST['ftphost'])?$_POST:false);
1374                 doUpdate($remotefile, $ftpdata);
1375         } else {
1376                 echo "No remote file to download. Abort!";
1377         }
1378
1379         killme();
1380 }
1381
1382 /**
1383  * @param App $a
1384  * @return string
1385  */
1386 function admin_page_remoteupdate(&$a) {
1387         if(!is_site_admin()) {
1388                 return login(false);
1389         }
1390
1391         $canwrite = canWeWrite();
1392         $canftp = function_exists('ftp_connect');
1393
1394         $needupdate = true;
1395         $u = checkUpdate();
1396         if (!is_array($u)){
1397                 $needupdate = false;
1398                 $u = array('','','');
1399         }
1400
1401         $tpl = get_markup_template("admin_remoteupdate.tpl");
1402         return replace_macros($tpl, array(
1403                 '$baseurl' => $a->get_baseurl(true),
1404                 '$submit' => t("Update now"),
1405                 '$close' => t("Close"),
1406                 '$localversion' => FRIENDICA_VERSION,
1407                 '$remoteversion' => $u[1],
1408                 '$needupdate' => $needupdate,
1409                 '$canwrite' => $canwrite,
1410                 '$canftp'       => $canftp,
1411                 '$ftphost'      => array('ftphost', t("FTP Host"), '',''),
1412                 '$ftppath'      => array('ftppath', t("FTP Path"), '/',''),
1413                 '$ftpuser'      => array('ftpuser', t("FTP User"), '',''),
1414                 '$ftppwd'       => array('ftppwd', t("FTP Password"), '',''),
1415                 '$remotefile'=>array('remotefile','', $u['2'],''),
1416         ));
1417
1418 }