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