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